C / CHAPTER 05
Text parsing and complete-consumption checks
AdvancedDetect 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.
#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);
}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