Jump to content
VoZk

Saber se os caracteres de string são números com isdigit()

Recommended Posts

VoZk

Boas,

Eu tenho uma string ( array de char's ) e quero confirmar se todos os valores dessa string são dígitos (menos o primeiro que como da para perceber pela função a 1ª posição pode ser o sinal ' - ' )e criei a seguinte função:

int validar_saldo(char* str){
if(str[0] == '-' || isdigit(str[0]) == 1){
int i=1;
for(i = 1; str[i]!='\0' ; i++){
if(isdigit(str[i])==0){
return 0;
}
}
}
return 1;
}

Mas por algum motivo que nao sei porque o valor retornado é sempre o valor que tenho no ultimo return mesmo que algum dos valores intermédios não seja digito. Alguém me sabe dizer porque?

Cumps

Edited by thoga31
GeSHi

Share this post


Link to post
Share on other sites
VoZk

Eu tenho um ficheiro com este formato:

123-55555-1 10000 0

123-55533-3 12300 500

123-99971-3 50000 0

123-38951-2 350 10

120-39888-0 4910 100

121-12345-3 50000 150

121-xptoz-3 1000 100

150-23857-1 350000 20000

521-71750-4 500000 25000

191-11999-7 -1200

estou a dividir isto com o strtok e o valor que interessa para este caso é o 2º.

Tenho :

char* componentes;

componentes = strtok (contas, " ");

Guado o segundo valor na variável 'componentes' e depois faço:

int valido = validar_saldo(componentes);

Mas o valor de valido é sempre o que ponho no ultimo return...

Share this post


Link to post
Share on other sites
pmg

Duas coisas:

1) Da maneira que construiste a funcao, a string composta unicamente pelo sinal "-" é aceite.

2) o valor devolvido pelo isdigit() quando passado um digito pode ser diferente de 1. O que o Standard obriga é que seja diferente de zero

Para averiguar a causa do teu problema (assumindo que os pontos acima nao tem relevancia) eu imprimia o valor passado dentro da funcao

int validar_saldo(char *str) {
   /* DEBUG */
   fprintf(stderr, "DEBUG: valor passado: [%s]\n", str);

   if (*str == '-') str++;
   if (!isdigit((unsigned char)*str)) return 0; /* empty strings return false */
   while (*str) {
       if (!isdigit((unsigned char)*str)) return 0;
       str++;
   }
   return 1;
}

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Duas coisas:

1) Da maneira que construiste a funcao, a string composta unicamente pelo sinal "-" é aceite.

2) o valor devolvido pelo isdigit() quando passado um digito pode ser diferente de 1. O que o Standard obriga é que seja diferente de zero

Para averiguar a causa do teu problema (assumindo que os pontos acima nao tem relevancia) eu imprimia o valor passado dentro da funcao

int validar_saldo(char *str) {
/* DEBUG */
fprintf(stderr, "DEBUG: valor passado: [%s]\n", str);

if (*str == '-') str++;
if (!isdigit((unsigned char)*str)) return 0; /* empty strings return false */
while (*str) {
	if (!isdigit((unsigned char)*str)) return 0;
	str++;
}
return 1;
}

Já fiz como me disseste para fazer debug, e o valor que ele me está a imprimir é o valor correto mas continuo a ter o mesmo problema. Se eu por exemplo puser uma letra ou uma palavra em vez de números ele diz na mesma que e um digito.

Share this post


Link to post
Share on other sites
pmg
Ta aqui

Estas a chamar a funcao validar_limite() com o terceiro componente!

O primeiro componente é tratado no if (contador == 0), o segundo componente no if (contador == 1) e o terceiro no if seguinte

                                       else if (contador == 2){
                                               strcpy(tmplimitecredito , componentes);
                                               int valido = validar_limite(componentes);


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Estas a chamar a funcao validar_limite() com o terceiro componente!

O primeiro componente é tratado no if (contador == 0), o segundo componente no if (contador == 1) e o terceiro no if seguinte

									else if (contador == 2){
											strcpy(tmplimitecredito , componentes);
											int valido = validar_limite(componentes);

Sim mas é esse o objectivo. Na primeira valido o suposto ID , na segunda e para validar o saldo ( que pode ser negativo ) , na terceira é o limite de credito daí chamar a função validar credito

Share this post


Link to post
Share on other sites
pmg

A implementacao usada no ideone devolveu 2048 para isdigit('4') na minha experiencia.

http://ideone.com/GjSavF

2) o valor devolvido pelo isdigit() quando passado um digito pode ser diferente de 1. O que o Standard obriga é que seja diferente de zero

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Sim é isso mas da maneira que esta implementado no código ele ignora se for uma letra em vez de retornar logo 0 não sei porquê... E assim percorre sempre ate ao ultimo return...

Edited by VoZk

Share this post


Link to post
Share on other sites
pmg

Sim é isso mas da maneira que esta implementado no código ele ignora se for uma letra em vez de retornar logo 0 não sei porquê... E assim percorre sempre ate ao ultimo return...

Compara

if (isdigit('4') == 1); // if (2048 == 1)
if (isdigit('4') != 0); // if (2048 != 0)
if (isdigit('4')      ; // if (2048)

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Sim mas eu tenho que se o valor == 0 faz uma coisa, else ( ou seja valor != 0 ) faz outra... certo?

Share this post


Link to post
Share on other sites
pmg

Linhas 72 e 73 do teu ideone

int validar_limite(char* str){
       if(str[0] == '-' || isdigit(str[0]) == 1){
//                          ^^^^^^^^^^^^^^^^^^^^ ERRADO!

Edited by pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Neste momento tenho esta função assim:

int validar_limite(char* str){
if(str[0] == '-' || isdigit(str[0]) != 0){
int i=1;
for(i = 1; str[i]!='\0' ; i++){
if(isdigit(str[i])==0){
return 0;
}
}
}
return 1;
}

E continua a imprimir que a função é valida se escrever no array só caracteres

Share this post


Link to post
Share on other sites
pmg

Hmmm ... o teu primeiro if nao faz o que tu queres

if(str[0] == '-' || isdigit(str[0]) != 0)

Vamos la fazer uma tabela de "debug"

| str[0] | str[0] == '-' (A) | isdigit(str[0]) != 0 (B) | A || B |
+--------+-------------------+--------------------------+--------+
|   -    |      TRUE         |     nao interessa        |  TRUE  | entra no if
|   4    |      FALSE        |          TRUE            |  TRUE  | entra no if
|   H    |      FALSE        |         FALSE            | FALSE  | vai directo para return 1


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Então se puser assim está certo?

int validar_limite(char* str){
if(str[0] == '-' || isdigit(str[0]) != 0){
int i=1;
for(i = 1; str[i]!='\0' ; i++){
if(isdigit(str[i])==0){
return 0;
}
}
return 1;
}
return 0;
}

Edited by VoZk

Share this post


Link to post
Share on other sites
pmg

Então se puser assim está certo?

Melhora a indentacao do teu codigo!!

No teu computador tambem tens tudo chegado a esquerda ou foi problema do editor do P@P?

Para evitar problemas no editor, eu meto-o em modo basico (primeiro botao da barra de ferramentas do editor) e escrevo as tags à mao.

O teu codigo indentado aparece assim:

int validar_limite(char* str){
   if(str[0] == '-' || isdigit(str[0]) != 0){
       int i=1;
       for(i = 1; str[i]!='\0' ; i++){
           if(isdigit(str[i])==0){
               return 0;
           }
       }
       return 1;
   }
   return 0;
}

Agora ja parece certo


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Share this post


Link to post
Share on other sites
VoZk

Agora ja parece certo

Foi problema do editor do P@P, no computador tenho tudo identado.

Pois.... Continua a dar mal. Neste momento tenho o codigo assim: http://ideone.com/JGNvO7

Ignora aquelas partes do levantamento e deposito, etc, que isso é outra parte que ainda estou a fazer... Segundo o que tenho ai na função 'contas' o que deveria acontecer era quando o validar_limite fosse 0 imprimia "Limite de credito invalido"e quando o validar_limite fosse 1 imprimia "- Limite de credito: %s\n" , mas quando executo o programa ele diz-me que todos os limites estão invalidos...

Edited by VoZk

Share this post


Link to post
Share on other sites
HappyHippyHippo

"dividir para conquistar"

int is_valid_n_chars(char * string, size_t size, char * chars) {
 int sindex = 0, cindex = 0;

 // ciclo de validação da string dada
 while(sindex < size && string[sindex] != '\0') {
   // pesquisa do caracter iterado na lista de caracteres válidos
   for (cindex = 0;
        chars[cindex] != '\0' && string[sindex] != chars[cindex];
        cindex++) /* void */;

   // verificação se o caracter foi encontrado
   if (chars[cindex] == '\0')
     return 0;

   // incremento da iteração
   sindex++;
 }

 // é válido se chegou ao fim da string com todos os caracteres validados
 // (verificação de string[sindex] == '\0' mas sindex < size)
 return sindex == size;
}

int is_valid_chars(char * string, char * chars) {
 return is_valid_n_chars(string, strlen(string), chars);
}

int is_valid_n_number(char * string, size_t size) {
 if (string[0] == '-')
   return is_valid_chars(&string[1], size - 1, "0123456789");
 return is_valid_chars(string, size, "0123456789");
}

int is_valid_number(char * string) {
 return is_valid_n_number(string, strlen(string));
}

int is_valid_id(char * string) {
 return string[3] == '-' &&
        string[9] == '-' &&
        string[11] == '\0' &&
        is_valid_n_number(string, 3) &&
        is_valid_n_number(&string[4], 5) &&
        is_valid_n_number(&string[10], 1);
}

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.