Classifying characters read from a stream
suggest change#include <ctype.h> #include <stdio.h> typedef struct { size_t space; size_t alnum; size_t punct; } chartypes; chartypes classify(FILE *f) { chartypes types = { 0, 0, 0 }; int ch; while ((ch = fgetc(f)) != EOF) { types.space += !!isspace(ch); types.alnum += !!isalnum(ch); types.punct += !!ispunct(ch); } return types; }
The classify
function reads characters from a stream and counts the number of spaces, alphanumeric and punctuation characters. It avoids several pitfalls.
- When reading a character from a stream, the result is saved as an
int
, since otherwise there would be an ambiguity between readingEOF
(the end-of-file marker) and a character that has the same bit pattern. - The character classification functions (e.g.
isspace
) expect their argument to be either representable as anunsigned char
, or the value of theEOF
macro. Since this is exactly what thefgetc
returns, there is no need for conversion here. - The return value of the character classification functions only distinguishes between zero (meaning
false
) and nonzero (meaningtrue
). For counting the number of occurrences, this value needs to be converted to a 1 or 0, which is done by the double negation,!!
.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents