#include <ctype.h>
#include <stddef.h>
typedef struct {
size_t space;
size_t alnum;
size_t punct;
} chartypes;
chartypes classify(const char *s) {
chartypes types = { 0, 0, 0 };
const char *p;
for (p= s; p != '\0'; p++) {
types.space += !!isspace((unsigned char)*p);
types.alnum += !!isalnum((unsigned char)*p);
types.punct += !!ispunct((unsigned char)*p);
}
return types;
}
The classify
function examines all characters from a string and counts the number of spaces, alphanumeric and punctuation characters. It avoids several pitfalls.
isspace
) expect their argument to be either representable as an unsigned char
, or the value of the EOF
macro.*p
is of type char
and must therefore be converted to match the above wording.char
type is defined to be equivalent to either signed char
or unsigned char
.char
is equivalent to unsigned char
, there is no problem, since every possible value of the char
type is representable as unsigned char
.char
is equivalent to signed char
, it must be converted to unsigned char
before being passed to the character classification functions. And although the value of the character may change because of this conversion, this is exactly what these functions expect.false
) and nonzero (meaning true
). For counting the number of occurrences, this value needs to be converted to a 1 or 0, which is done by the double negation, !!
.