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 */;