C / CHAPTER 05

Text parsing and complete-consumption checks

Advanced

Detect malformed input instead of silently accepting a numeric prefix.

By the end of this chapter

  • Use strtol with an end pointer
  • Distinguish no digits from zero
  • Check range and trailing data separately

The idea

strtol converts an initial numeric portion of text and reports where conversion stopped through an end pointer. A return value of zero can be a valid conversion or a failure to consume digits. Compare the end pointer with the start to detect the latter. Set errno to zero before conversion and inspect ERANGE to detect a result outside long’s range.

A parser’s whitespace and sign rules are application decisions. strtol permits leading whitespace and a sign; a complete-token policy should inspect the unconsumed suffix and reject it unless explicitly allowed. Converting to a narrower type needs another range check before the cast. Avoid atoi when you need dependable error reporting, because its simple result does not distinguish all invalid inputs from valid zero.

C example
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void) {
  const char *text = "42x";
  char *end;
  errno = 0;
  long value = strtol(text, &end, 10);
  int valid = end != text && *end == '\0' && errno != ERANGE;
  printf("%ld %c %d\n", value, *end, valid);
}
Result
42 x 0

The prefix converts to 42, but x remains, so the whole token is rejected.

Try it yourself

Parse an int with complete consumption and reject values outside INT_MIN through INT_MAX before casting.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

How does an end pointer reveal that strtol consumed no digits?