C: using strtol endptr is never NULL, cannot check if value is integer only?

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

Leave a Comment