c - What is the correct behavior of strtol? -
i'm creating wrapper function around strtol() int16_t, , ran across problem: how handle input such 0x? is, valid digit 0, followed non-digit x, or invalid because nothing follows 0x?
tl;dr results: windows rejects 0x described in latter case, debian sees digit 0, followed non-digit character x, explained in former case.
implementations tested1
- windows
- visual c++ 2015 (henceforth msvc)
- mingw-w64 gcc (5.2.0)
- debian
for further comparison purposes, included sscanf() format specification of " %li", supposed act strtol() base==0. surprisingly, ended 2 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 no error in case, yet results differed. initializing base 16 instead of 0 made no difference @ all, nor did removal of leading blanks in test string.
i expected result got on debian: 0 parsed valid value (whether base 0 or 16), , remainder set point x after seeing there no valid hexadecimal values following x (had there been any, 0x skipped whether base 0 or 16).
so i'm confused correct behavior in situation. either of these behaviors in violation of c standard? interpretation of relevant sections of standard debian correct, i'm not certain.
1 cygwin exhibited windows behavior in case of strtol() , debian behavior in case of sscanf() interested. since behavior of %li supposed match strtol() base==0, considered bug , ignored results.
the specification 7.22.1.4 of c11:
if value of base zero, expected form of subject sequence of integer constant described in 6.4.4.1,
the subject sequence defined longest initial subsequence of input string, starting first non-white-space character, of expected form
as described in 6.4.4.1, 0 integer constant, 0x not. therefore, subject sequence 0 input case.
so correct behaviour return 0, , endptr should left pointing x.
Comments
Post a Comment