'What is the correct behavior of strtol?
I'm creating a wrapper function around strtol() for int16_t, and I ran across a problem: how to handle input such as 0x? That is, is it valid as digit 0, followed by non-digit x, or is it invalid because nothing follows 0x?
tl;dr results: Windows rejects 0x completely as described in the latter case, but Debian sees it as the digit 0, followed by the non-digit character x, as explained in the former case.
Implementations tested1
- Windows
- Visual C++ 2015 (henceforth MSVC)
- MinGW-w64 GCC (5.2.0)
- Debian
For further comparison purposes, I included sscanf() with a format specification of " %li", which is supposed to act like strtol() with base==0. Surprisingly, I ended up with two different results.
Code:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char *foo = " 0x";
char *remainder;
long n;
int base = 0;
n = strtol(foo, &remainder, base);
printf("strtol(): ");
if (*remainder == 'x')
printf("OK\n");
else {
printf("NOMATCH\n");
printf(" Remaining -- %s\n", remainder);
printf(" errno: %s (%d)\n", strerror(errno), errno);
}
errno = 0;
base = sscanf(foo, " %li", &n);
printf("sscanf(): ");
if (base == 1)
printf("OK\n");
else {
printf("NOMATCH\n");
printf(" Returned: %s\n", base==0 ? "0" : "EOF");
printf(" errno: %s (%d)\n", strerror(errno), errno);
}
}
Debian results:
strtol(): OK
sscanf(): OK
Windows results:
strtol(): NOMATCH
Remaining -- 0x
errno: No error (0)
sscanf(): NOMATCH
Returned: 0
errno: No error (0)
There was no error in any case, yet the results differed. Initializing base to 16 instead of 0 made no difference at all, nor did removal of the leading blanks in the test string.
I honestly expected the result that I got on Debian: 0 is parsed as a valid value (whether base is 0 or 16), and remainder is set to point to x after seeing there were no valid hexadecimal values immediately following x (had there been any, the 0x would be skipped whether base is 0 or 16).
So now I'm confused about the correct behavior in this situation. Is either of these behaviors in violation of the C standard? My interpretation of the relevant sections of the standard is that Debian is correct, but I'm really not certain.
1 Cygwin exhibited the Windows behavior in the case of strtol() and the Debian behavior in the case of sscanf() for those who are interested. Since the behavior is of %li is supposed to match strtol() with base==0, I considered this a bug and ignored its results.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
