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 theEOFmacro. Since this is exactly what thefgetcreturns, 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