The strtol
family of functions provide this capability. They allow you to convert a string to a numeric type (depending on which member of the family you choose) and, unlike the atoi
family, also allow you to detect if scanning failed before reaching the end.
It does this by populating the pointer you pass with the address of the first character not included in the conversion. If this is anything other than the string terminator, it had to stop early.
There's also the special case where it may point at a terminator even when the string is invalid (specifically, the case of an empty string ""
).
As an example, the following program shows one way to use it:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main (int argc, char *argv[]) {
int i;
long val;
char *next;
// Process each argument.
for (i = 1; i < argc; i++) {
// Get value with failure detection.
errno = 0;
val = strtol (argv[i], &next, 10);
// Check for empty string and characters left after conversion.
if (errno == EINVAL) {
printf ("'%s' invalid\n", argv[i]);
} else if (errno == ERANGE) {
printf ("'%s' out of range\n", argv[i]);
} else if (next == argv[i]) {
printf ("'%s' is not valid at first character\n", argv[i]);
} else if (*next != '\0') {
printf ("'%s' is not valid at subsequent character\n", argv[i]);
} else {
printf ("'%s' gives %ld\n", argv[i], val);
}
}
return 0;
}
Running that code with the arguments hi "" 42 3.14159 9999999999999999999999999 7 9q
gives:
'hi' is not valid at first character
'' is not valid at first character
'42' gives 42
'3.14159' is not valid at subsequent character
'9999999999999999999999999' out of range
'7' gives 7
'9q' is not valid at subsequent character