[c] how to check if the input is a number or not in C?

In the main function of C:

void main(int argc, char **argv)
{
   // do something here
}

In the command line, we will type any number for example 1 or 2 as input, but it will be treated as char array for the parameter of argv, but how to make sure the input is a number, in case people typed hello or c?

This question is related to c types

The answer is


if (sscanf(command_level[2], "%f%c", &check_f, &check_c)!=1)
{
        is_num=false;
}
else
{
        is_num=true;
}   

if(sscanf(command_level[2],"%f",&check_f) != 1) 
{
    is_num=false;
}

how about this?


The sscanf() solution is better in terms of code lines. My answer here is a user-build function that does almost the same as sscanf(). Stores the converted number in a pointer and returns a value called "val". If val comes out as zero, then the input is in unsupported format, hence conversion failed. Hence, use the pointer value only when val is non-zero.

It works only if the input is in base-10 form.

#include <stdio.h>
#include <string.h>
int CONVERT_3(double* Amt){

    char number[100];

    // Input the Data
    printf("\nPlease enter the amount (integer only)...");
    fgets(number,sizeof(number),stdin);

    // Detection-Conversion begins
    int iters = strlen(number)-2;
    int val = 1;
    int pos;
    double Amount = 0;
    *Amt = 0;
    for(int i = 0 ; i <= iters ; i++ ){
        switch(i){
            case 0:
                if(number[i]=='+'){break;}
                if(number[i]=='-'){val = 2; break;}
                if(number[i]=='.'){val = val + 10; pos = 0; break;}
                if(number[i]=='0'){Amount = 0; break;}
                if(number[i]=='1'){Amount = 1; break;}
                if(number[i]=='2'){Amount = 2; break;}
                if(number[i]=='3'){Amount = 3; break;}
                if(number[i]=='4'){Amount = 4; break;}
                if(number[i]=='5'){Amount = 5; break;}
                if(number[i]=='6'){Amount = 6; break;}
                if(number[i]=='7'){Amount = 7; break;}
                if(number[i]=='8'){Amount = 8; break;}
                if(number[i]=='9'){Amount = 9; break;}
            default:
                switch(number[i]){
                    case '.':
                        val = val + 10;
                        pos = i;
                        break;
                    case '0':
                        Amount = (Amount)*10;
                        break;
                    case '1':
                        Amount = (Amount)*10 + 1;
                        break;
                    case '2':
                        Amount = (Amount)*10 + 2;
                        break;
                    case '3':
                        Amount = (Amount)*10 + 3;
                        break;
                    case '4':
                        Amount = (Amount)*10 + 4;
                        break;
                    case '5':
                        Amount = (Amount)*10 + 5;
                        break;
                    case '6':
                        Amount = (Amount)*10 + 6;
                        break;
                    case '7':
                        Amount = (Amount)*10 + 7;
                        break;
                    case '8':
                        Amount = (Amount)*10 + 8;
                        break;
                    case '9':
                        Amount = (Amount)*10 + 9;
                        break;
                    default:
                        val = 0;
                }
        }
        if( (!val) | (val>20) ){val = 0; break;}// val == 0
    }

    if(val==1){*Amt = Amount;}
    if(val==2){*Amt = 0 - Amount;}
    if(val==11){
        int exp = iters - pos;
        long den = 1;
        for( ; exp-- ; ){
            den = den*10;
        }
        *Amt = Amount/den;
    }
    if(val==12){
        int exp = iters - pos;
        long den = 1;
        for( ; exp-- ; ){
            den = den*10;
        }
        *Amt = 0 - (Amount/den);
    }

    return val;
}


int main(void) {
    double AM = 0;
    int c = CONVERT_3(&AM);
    printf("\n\n%d    %lf\n",c,AM);

    return(0);
}

You can use a function like strtol() which will convert a character array to a long.

It has a parameter which is a way to detect the first character that didn't convert properly. If this is anything other than the end of the string, then you have a problem.

See the following program for an example:

#include <stdio.h>
#include <stdlib.h>

int main( int argc, char *argv[]) {
    int i;
    long val;
    char *next;

    // Process each argument given.

    for (i = 1; i < argc; i++) {
        // Get value with failure detection.

        val = strtol (argv[i], &next, 10);

        // Check for empty string and characters left after conversion.

        if ((next == argv[i]) || (*next != '\0')) {
            printf ("'%s' is not valid\n", argv[i]);
        } else {
            printf ("'%s' gives %ld\n", argv[i], val);
        }
    }

    return 0;
}

Running this, you can see it in operation:

pax> testprog hello "" 42 12.2 77x

'hello' is not valid
'' is not valid
'42' gives 42
'12.2' is not valid
'77x' is not valid

I was struggling with this for awhile, so I thought I'd just add my two cents:

1) Create a separate function to check if an fgets input consists entirely of numbers:

int integerCheck(){
char myInput[4];
fgets(myInput, sizeof(myInput), stdin);
    int counter = 0;
    int i;
    for (i=0; myInput[i]!= '\0'; i++){
        if (isalpha(myInput[i]) != 0){
            counter++;
            if(counter > 0){
                printf("Input error: Please try again. \n ");
                return main();
            }
        }

    }
    return atoi(myInput); 
}

The above starts a loop through every unit of an fgets input until the ending NULL value. If it comes across a letter or an operator, it adds "1" to the int "counter" which is initially set to 0. Once the counter becomes greater than 0, the nested if statement instructs the loop to print an error message & then restart the program. When the loops completes, if int 'counter' is still the value of 0, it returns the initially inputted integer to be used in the main function ...

2) the main function would be:

int main(void){
unsigned int numberOne;
unsigned int numberTwo;
numberOne = integerCheck();
numberTwo = integerCheck();
return numberOne*numberTwo;

}

Assuming both integers are inputted correctly, the example provided will yield the result of int "numberOne" multiplied by int "numberTwo". The program will repeat for however long it takes to get two properly inputted integers.


A self-made solution:

bool isNumeric(const char *str) 
{
    while(*str != '\0')
    {
        if(*str < '0' || *str > '9')
            return false;
        str++;
    }
    return true;
}

Note that this solution should not be used in production-code, because it has severe limitations. But I like it for understanding C-Strings and ASCII.


Using scanf is very easy, this is an example :

if (scanf("%d", &val_a_tester) == 1) {
    ... // it's an integer
}

Using fairly simple code:

int i;
int value;
int n;
char ch;

/* Skip i==0 because that will be the program name */
for (i=1; i<argc; i++) {
    n = sscanf(argv[i], "%d%c", &value, &ch);

    if (n != 1) {
        /* sscanf didn't find a number to convert, so it wasn't a number */
    }
    else {
        /* It was */
    }
}