How to test if a string is a number in the C language?

0

I'm a beginner in programming.

I am performing an exercise in which I must determine whether a string is a number, whereas the user can write anything as input. Then I created the function below. I can only use the standard library. I'm trying to use as few variables as possible.

Could anyone evaluate?

int isNumber(char input[], int input_size){

int i;

//Elimina cadeia com caracteres não numéricos
for(i = 1; i < input_size; i++)
{
    if(input[i-1] != '0' && input[i-1] != '1' &&
       input[i-1] != '2' && input[i-1] != '3' &&
       input[i-1] != '4' && input[i-1] != '5' &&
       input[i-1] != '6' && input[i-1] != '7' &&
       input[i-1] != '8' && input[i-1] != '9' &&
       input[i-1] != '.' && input[i-1] != ',' &&
       input[i-1] != ' ' && input[i-1] != '-' &&
       input[i-1] != '
int isNumber(char input[], int input_size){

int i;

//Elimina cadeia com caracteres não numéricos
for(i = 1; i < input_size; i++)
{
    if(input[i-1] != '0' && input[i-1] != '1' &&
       input[i-1] != '2' && input[i-1] != '3' &&
       input[i-1] != '4' && input[i-1] != '5' &&
       input[i-1] != '6' && input[i-1] != '7' &&
       input[i-1] != '8' && input[i-1] != '9' &&
       input[i-1] != '.' && input[i-1] != ',' &&
       input[i-1] != ' ' && input[i-1] != '-' &&
       input[i-1] != '%pre%'){
        return 0;
    }
}

//Elimina cadeia que só possui espaços e caracteres nulos
for(i = 1; i < input_size; i++){
    if(input[i-1] != ' ' && input[i-1] != '%pre%'){
        break;
    }
}
if(i >= input_size){
    return 0;
}

//Elimina cadeia com mais de um ponto ou vírgula
for(i = 1; i < input_size; i++){
    if(input[i-1] == '.' || input[i-1] == ','){
        for(i++; i < input_size; i++){
            if(input[i-1] == '.' || input[i-1] == ','){
                return 0;
            }
        }
        break;
    }
}

//Elimina cadeia com mais de um sinal de menos
for(i = 1; i < input_size; i++){
    if(input[i-1] == '-'){
        for(i++; i < input_size; i++){
            if(input[i-1] == '-'){
                return 0;
            }
        }
        break;
    }
}

//Elimina cadeia com dois números separados por espaço
for(i = 2; i < input_size; i++){
    if(input[i-2] != ' ' &&
       input[i-2] != '%pre%' &&
       input[i-1] == ' ' &&
       input[i] != ' ' &&
       input[i] != '%pre%'){
        return 0;
    }
}

//Elimina cadeia com dois números separados por sinal de menos
for(i = 2; i < input_size; i++){
    if(input[i-2] != ' ' &&
       input[i-2] != '%pre%' &&
       input[i-1] == '-' &&
       input[i] != ' ' &&
       input[i] != '%pre%'){
        return 0;
    }
}

//Elimina cadeia terminada em sinal de menos
for(i = input_size; i > 0; i--){
    if(input[i-0] != '%pre%' && input[i-0] != ' ' && input[i-0] == '-'){
        return 0;
    }
}

//Elimina cadeia que somente tem ponto, vírgula ou sinal de menos
if((input[0] == '.' || input[0] == ',' || input[0] == '-') && (input[1] == ' ' || input[1] == '%pre%')){
    return 0;
}
for(i = 2; i < input_size; i++){
    if((input[i-2] == ' ' || input[i-2] == '%pre%') &&
       (input[i-1] == '.' || input[i-1] == ',' || input[i-1] == '-') &&
       (input[i] == ' ' || input[i] == '%pre%')){
        return 0;
    }
}

return 1;
}
'){ return 0; } } //Elimina cadeia que só possui espaços e caracteres nulos for(i = 1; i < input_size; i++){ if(input[i-1] != ' ' && input[i-1] != '%pre%'){ break; } } if(i >= input_size){ return 0; } //Elimina cadeia com mais de um ponto ou vírgula for(i = 1; i < input_size; i++){ if(input[i-1] == '.' || input[i-1] == ','){ for(i++; i < input_size; i++){ if(input[i-1] == '.' || input[i-1] == ','){ return 0; } } break; } } //Elimina cadeia com mais de um sinal de menos for(i = 1; i < input_size; i++){ if(input[i-1] == '-'){ for(i++; i < input_size; i++){ if(input[i-1] == '-'){ return 0; } } break; } } //Elimina cadeia com dois números separados por espaço for(i = 2; i < input_size; i++){ if(input[i-2] != ' ' && input[i-2] != '%pre%' && input[i-1] == ' ' && input[i] != ' ' && input[i] != '%pre%'){ return 0; } } //Elimina cadeia com dois números separados por sinal de menos for(i = 2; i < input_size; i++){ if(input[i-2] != ' ' && input[i-2] != '%pre%' && input[i-1] == '-' && input[i] != ' ' && input[i] != '%pre%'){ return 0; } } //Elimina cadeia terminada em sinal de menos for(i = input_size; i > 0; i--){ if(input[i-0] != '%pre%' && input[i-0] != ' ' && input[i-0] == '-'){ return 0; } } //Elimina cadeia que somente tem ponto, vírgula ou sinal de menos if((input[0] == '.' || input[0] == ',' || input[0] == '-') && (input[1] == ' ' || input[1] == '%pre%')){ return 0; } for(i = 2; i < input_size; i++){ if((input[i-2] == ' ' || input[i-2] == '%pre%') && (input[i-1] == '.' || input[i-1] == ',' || input[i-1] == '-') && (input[i] == ' ' || input[i] == '%pre%')){ return 0; } } return 1; }
    
asked by anonymous 02.05.2017 / 11:52

2 answers

0

Instead of going through the string several times looking for specific properties, it is best to look at it once, considering the properties of a well-formed number:

#include <stdio.h>
#define FLAG_DIGITO_ENCONTRADO 1

int
eh_numero(const char * entrada) {
    unsigned int flags = 0;
    // um número pode ter uma quantidade arbitrária de espaços antes dele
    while (*entrada == ' ') entrada ++;
    // seguido, opcionalmente, de um único sinal de menos
    if (*entrada == '-') entrada ++;
    // seguido de zero ou mais dígitos
    while (*entrada >= '0' && *entrada <= '9') {
        flags |= FLAG_DIGITO_ENCONTRADO;
        entrada ++;
    }
    // se encontrou pelo menos um dígito, o número pode terminar aqui
    if ((flags & FLAG_DIGITO_ENCONTRADO) && *entrada == '
$ cc -o so201793 so201793.c -Wall

$ ./so201793
A sequência 0 é um numero válido
A sequência          -2.5 é um numero válido
A sequência 1. é um numero válido
A sequência ,25 é um numero válido
A sequência 3.. não é um numero válido
A sequência +1 não é um numero válido
A sequência --8 não é um numero válido
A sequência , não é um numero válido
A sequência 3A não é um numero válido

$
') return 1; // senão, vai ter que encontrar um separador decimal if (*entrada == '.' || *entrada == ',') entrada ++; // Se não houver dígitos antes da vírgula/ponto, precisa de // pelo menos um depois do ponto if (!(flags & FLAG_DIGITO_ENCONTRADO) && (*entrada < '0' || *entrada > '9')) return 0; // se houver, pode haver mais zero ou mais dígitos depois do ponto while (*entrada >= '0' && *entrada <= '9') entrada ++; // finalmente, temos que ter chegado ao fim da sequência, ou // ela não é um número return (*entrada == '
#include <stdio.h>
#define FLAG_DIGITO_ENCONTRADO 1

int
eh_numero(const char * entrada) {
    unsigned int flags = 0;
    // um número pode ter uma quantidade arbitrária de espaços antes dele
    while (*entrada == ' ') entrada ++;
    // seguido, opcionalmente, de um único sinal de menos
    if (*entrada == '-') entrada ++;
    // seguido de zero ou mais dígitos
    while (*entrada >= '0' && *entrada <= '9') {
        flags |= FLAG_DIGITO_ENCONTRADO;
        entrada ++;
    }
    // se encontrou pelo menos um dígito, o número pode terminar aqui
    if ((flags & FLAG_DIGITO_ENCONTRADO) && *entrada == '
$ cc -o so201793 so201793.c -Wall

$ ./so201793
A sequência 0 é um numero válido
A sequência          -2.5 é um numero válido
A sequência 1. é um numero válido
A sequência ,25 é um numero válido
A sequência 3.. não é um numero válido
A sequência +1 não é um numero válido
A sequência --8 não é um numero válido
A sequência , não é um numero válido
A sequência 3A não é um numero válido

$
') return 1; // senão, vai ter que encontrar um separador decimal if (*entrada == '.' || *entrada == ',') entrada ++; // Se não houver dígitos antes da vírgula/ponto, precisa de // pelo menos um depois do ponto if (!(flags & FLAG_DIGITO_ENCONTRADO) && (*entrada < '0' || *entrada > '9')) return 0; // se houver, pode haver mais zero ou mais dígitos depois do ponto while (*entrada >= '0' && *entrada <= '9') entrada ++; // finalmente, temos que ter chegado ao fim da sequência, ou // ela não é um número return (*entrada == '%pre%'); } // main para efetuar alguns testes #define VERIFIQUE(N) printf("A sequência " N " %sé um numero válido\n",\ eh_numero(N) ? "" : "não ") int main(int argc, char ** argv) { VERIFIQUE("0"); VERIFIQUE(" -2.5"); VERIFIQUE("1."); VERIFIQUE(",25"); VERIFIQUE("3.."); VERIFIQUE("+1"); VERIFIQUE("--8"); VERIFIQUE(","); VERIFIQUE("3A"); return 0; }
'); } // main para efetuar alguns testes #define VERIFIQUE(N) printf("A sequência " N " %sé um numero válido\n",\ eh_numero(N) ? "" : "não ") int main(int argc, char ** argv) { VERIFIQUE("0"); VERIFIQUE(" -2.5"); VERIFIQUE("1."); VERIFIQUE(",25"); VERIFIQUE("3.."); VERIFIQUE("+1"); VERIFIQUE("--8"); VERIFIQUE(","); VERIFIQUE("3A"); return 0; }

Note that I used unsigned int to save binary flags. In this case, I only needed one (to save against the case of no digits before or after the comma), but there could be more if we wanted to convert the number to float , for example. In this case, the second flag would be 2, the third flag 4, the fourth flag 8, and so on. It uses bit-to-bit ( | ) disjunction to connect the flag, and bit-to-bit conjunction ( & ) to test if it is turned on. I could substitute for a simple variable in this case, but I think it's worth just to remind people of this possibility.

The test result:

%pre%     
03.05.2017 / 19:12
1

See if this is what you wanted.

#include <stdio.h>

int IsNumber( char input[] )
{
    register int i;
    int flagVirgula = 0;

    for(i = 0; input[i]; i++)
    {
        if( !i && !(input[i] - '-') )//Numero negativo
            continue;

        if( (!(input[i] - ',') || !(input[i] - '.')) && !flagVirgula )//só pode posuir uma virgula ou ponto
        {
            flagVirgula = 1;
            continue;
        }

        if( (!(input[i] - ',') || !(input[i] - '.')) )//segunda virgula
            return 0;

        if( (input[i] - '0') < 0 || (input[i] - '0') > 9 )
            return 0;
    }

    return 1;
}

int main()
{   
    char nome[50];

    while(1)
    {
        gets(nome);

        printf("%s\n", IsNumber(nome) ? "E um numero." : "Nao e um numero.");
    }

    return (0);
}
    
02.05.2017 / 13:54