对字符串中的字符进行分类
#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;
}
classify
函数检查字符串中的所有字符,并计算空格数,字母数字和标点符号。它避免了几个陷阱。
- 字符分类函数(例如
isspace
)期望它们的参数可以表示为unsigned char
,或者EOF
宏的值。 *p
的表达式为char
,因此必须进行转换以匹配上述措辞。char
类型定义为signed char
或unsigned char
。- 当
char
相当于unsigned char
时,没有问题,因为char
类型的每个可能值都可以表示为unsigned char
。 - 当
char
相当于signed char
时,必须将其转换为unsigned char
才能传递给字符分类函数。尽管由于这种转换,角色的值可能会发生变化,但这正是这些函数所期望的。 - 字符分类函数的返回值仅区分零(表示
false
)和非零(表示true
)。为计算出现次数,需要将此值转换为 1 或 0,这由双重否定!!
完成。