NOTE THAT I AM A NEWBIE
I\'ve used isdigit()
function before, but now I have an issue:
I need to check if (for an example) a
The isdigit() function does not check if a number is a number, numbers are always numbers, it checks if the number is the ascii code of a character that corresponds to a numeric value or more precisely to a digit, i.e. a charachter of the following set
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
You can try to use strtol() for that purpose, like this
char *endptr;
char *number = "-46";
strtol(number, &endptr, 10);
if (*endptr == '\0') /* read the manual in the link to understand this please */
printf("yes, it's a number!\n");
else
printf("NO, `%s' is not a number!\n", number);
Note: if you read the manual or the standard specification of each function you use, you will improve your language skills, I very often see misuses of every single function from the standard library mostly because the user didn't read the manual.
The trick is that the isdigit
function does not take an argument of type char
. Quoting the standard (N1570 7.4p1:
The header
<ctype.h>
declares several functions useful for classifying and mapping characters. In all cases the argument is anint
, the value of which shall be representable as anunsigned char
or shall equal the value of the macroEOF
. If the argument has any other value, the behavior is undefined.
The type char
may be either signed or unsigned. If it's signed (as it very commonly is), then it can hold negative values -- and passing a negative value other than EOF
(typically -1
) to isdigit
, or to any of the other functions declared in <ctype.h>
, causes undefined behavior.
The solution is to convert the argument to unsigned char
before passing it to isdigit
:
char c = -46;
if (isdigit((unsigned char)c) {
puts("It's a digit (?)");
}
else {
puts("It's not a digit");
}
And yes, this is exactly as annoying and counterintuitive as you think it is.