According to the documentation for strtoul
, regarding its return value...
This function returns the converted integral number as a long int value. If no valid conversion could be performed, a zero value is returned.
What if I'm parsing a user-supplied string of "0" where, for my application, "0" may be a valid entry? In that case it seems that I have no way to determine from using strtoul
if a valid conversion was performed. Is there another way to handle this?
Read further the man page:
Since
strtoul()
can legitimately return0
orULONG_MAX
(ULLONG_MAX
forstrtoull()
) on both success and failure, the calling program should seterrno
to0
before the call, and then determine if an error occurred by checking whethererrno
has a nonzero value after the call.
Also, to handle another scenario, where no digits were read in the input. If this happens, strtol()
sets the value of *endptr
to that of the nptr
. So, you should also check that the pointer values compare equal or not.
How to use
strtoul
to parse string where zero may be valid?
Any value returned from strtoul()
may be from an expected string input or from other not so expected strings. Further tests are useful.
The following strings all return 0 from strtoul()
"0"
, "-0"
, "+0"
""
, "abc"
" 0"
"0xyz"
, "0 "
, "0.0"
strtoul()
has the various detection modes.
int base = 10;
char *endptr; // Store the location where conversion stopped
errno = 0;
unsigned long y = strtoul(s, &endptr, base);
if (s == endptr) puts("No conversion"); // "", "abc"
else if (errno == ERANGE) puts("Overflow");
else if (*endptr) puts("Extra text after the number"); // "0xyz", "0 ", "0.0"
else puts("Mostly successful");
What is not yet detected.
Negative input. strtoul()
effectively wraps around such that strtoul("-1", 0, 10) == ULONG_MAX)
. This issue is often missed in cursory documentation review.
Leading white space allowed. This may or may not be desired.
To also detect negative values:
// find sign
while (isspace((unsigned char) *s)) {
s++;
}
char sign = *s;
int base = 10;
char *endptr; // Store the location where conversion stopped
errno = 0;
unsigned long y = strtoul(s, &endptr, base);
if (s == endptr) puts("No conversiosn");
else if (errno == ERANGE) puts("Overflow");
else if (*endptr) puts("Extra text after the number");
else if (sign == '-' && y != 0) puts("Negative value");
else puts("Successful");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With