Question:
In C,how to ensure the statement "num1=atoi(string)" outputs an error if non-numeric string is entered?
Sheer
2012-07-25 09:45:36 UTC
I mean, the string in "atoi(string)" is expected to be numeric so that it would be converted to an integer.But suppose one inadvertently enters something like "23f8@36", then how do we ensure that it prints a message "Please enter a numeric value only"?

Is there any return value of atoi() for a valid numeric string and another for a non-valid string that would produce an error?Like 0 & -1 respectively? Please give your suggestions.(In this case I am getting the string through the command-line.So kindly also tell me how to ensure that only a numeric string is entered if it is accepted through the scanf() function from keyboard).Thanks.
Six answers:
2012-07-25 20:59:10 UTC
As Roger has already pointed out, it's better to use strtol. Here's an example:



#include

#include

#include

#include



enum { NOTNUMERIC = 1, RANGE, EXTRA };



static int parseint(int *dst, const char *str)

{

        char *endp;

        long n;



        errno = 0;

        n = strtol(str, &endp, 10);

        if (*endp == *str)

                return NOTNUMERIC;

        if (errno || n < INT_MIN || n > INT_MAX)

                return RANGE;

        *dst = n;

        return *endp != '\0' ? EXTRA : 0;

}



int main(void)

{

        int n;



        switch (parseint(&n, "123a")) {

        case NOTNUMERIC:

                fputs("error: input must be numeric\n", stderr);

                return EXIT_FAILURE;

        case RANGE:

                fputs("error: value out of range\n", stderr);

                return EXIT_FAILURE;

        case EXTRA:

                fputs("warning: extra characters in input\n", stderr);

        default:

                ;

        }

        printf("%d\n", n);

        return 0;

}
husoski
2012-07-25 10:21:26 UTC
I like to use sscanf for rock-solid parsing of numeric input. For a single number:



/* Given: */

int n;

char extra;

long result;

char *string = ???;

...

n = sscanf(" %ld %c", &result, &extra);

if (n == 1)

{

...success!

}

else

{

... error--either no number was seen, or there was nonblank garbage afterward

}



The spaces before and after %ld allow for leading and trailing whitespace. (%ld will also skip leading whitespace, so the first space is just "documentation".) The %c at the and will match anything that's left in the string after skipping any trailing whitespace. If that succeeds, then there was something in the string besides the number parsed by the %ld format. sscanf returns the number of values stored, so n==1 means that the %ld succeeded and the %c did not, while n!=1 means something else happened.



You can combine that with other formats: " %d , %d %c" with n==2 for success will accept a comma-separated pair of ints, and nothing else will be allowed.



Edit: strtol() has the same problems as atol() for error detection...there isn't any. There can't be, with a simple function syntax. A long result can't both encode every valid long number, AND an error indicator that's distinct from every valid value. There's no such number. (For float and double, there are NAN values, but they have their own problems.)



When I need conversions in multiple places, I tend to make a function like:



/* Convert string to long. Return nozero on success. */



int parseLong( const char *input; long *pvalue)

{

char extra;

long value;

int n = sscanf(" %ld %c", value, extra);

if (n != 1) return 0;

*pvalue = value; /* store value only on 100% success */

return 1;

}



Now you can use:



if ( !parseLong(input, myLongVar) )

{

printf("I don't understand %s\n", input);

continue:

}



...or whatever's appropriate to your validation logic.
2012-07-25 09:52:14 UTC
atoi does have a return value. returns converted number on success, or a zero value if the conversion was invalid. Not without writing a long an obnoxious checker code is there any streamlined way to do that. That I'm aware of, at least with normal C-standard libraries.
roger
2012-07-25 10:02:14 UTC
you can use strtol().

http://www.thinkage.ca/english/gcos/expl/c/lib/strtol.html



that will give you a pointer to the character one past the last character used in calculating the number. If it does not point to a NUL then there was an invalid character in the string.



Or you can check the string yourself.

Scan through the string and look for values >='0' and <='9'.

And allow for a leading '-' and spaces.
Jared
2012-07-25 10:25:51 UTC
develop a stringCheck() function that returns 0 if good, and -1 if non numeric characters are found in the string. Well in C, it's a character array, not really a string. maybe something like:



Consider this example. Quick and dirty, but you should get the idea:



#include

#include



int CheckString(char *chkString, int chkStringLen){

int i;

for (i=0;i
printf("Character %d is %c\n",i,chkString[i]);

if (chkString[i] <= '0' || chkString[i] >= '9'){

printf("String '%s' is not numeric!\n",chkString);

return -1;

}

}

printf("String '%s' is numeric.\n",chkString);

return 0;

}





int main(int argc, char *argv[]){



char a[] = "3456";

char b[] = "rat";



printf("String A:\t%s\n",a);

CheckString(a,strlen(a));



printf("String B:\t%s\n",b);

CheckString(b,strlen(b));



return 0;

}



Basically comparing the ASCII numerical value of the character. Works like a charm for me.
sepe
2016-12-13 12:56:57 UTC
report me in case you like for being a *****, I formally do no longer care yet Nateena is a bloody liar. 4% of her solutions are superb solutions. never been given a superb answer? Take an prolonged walk off a short cliff you mendacity rat. yet that grow to be a somewhat stable shaggy dog tale. did no longer make me giggle even though it grow to be unique.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...