Assuming that earlier code has already split up the line into individual numbers, then the check you want is
errno = 0;
long row = strtol(token, &endtoken, 10);
if (*endtoken != '\0')
fprintf(stderr, "invalid number '%s' (syntax error)\n", token);
else if (endtoken == token)
fprintf(stderr, "invalid number '' (empty string)\n");
else if (errno)
fprintf(stderr, "invalid number '%s' (%s)\n", token, strerror(errno));
else
/* number is valid, proceed */;
strtol
will never set endtoken
to a null pointer; it will set it to point to the first character that is not a digit. If that character is the NUL string terminator (note the slightly different spelling), then the entire string was a valid number, unless endtoken == token
, which means that you gave strtol
the empty string, which probably doesn't count as a valid number. The errno
manipulation is necessary to catch numbers which were syntactically correct but outside the range of long
.
You might be able to simplify your code by pulling numbers directly out of the line buffer rather than splitting it up first: assuming there are supposed to be exactly two numbers on any given line,
char *p = linebuf;
char *endp;
errno = 0;
long row = strtol(p, &endp, 10);
if (endp == p || !isspace(p) || errno)
/* error, abandon parsing */;
p = endp;
long col = strtol(p, &endp, 10);
if (endp == p || p != '\0' || errno)
/* error, abandon parsing */;