對字串中的字元進行分類

#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 charunsigned char
  • char 相當於 unsigned char 時,沒有問題,因為 char 型別的每個可能值都可以表示為 unsigned char
  • char 相當於 signed char 時,必須將其轉換為 unsigned char 才能傳遞給字元分類函式。儘管由於這種轉換,角色的值可能會發生變化,但這正是這些函式所期望的。
  • 字元分類函式的返回值僅區分零(表示 false)和非零(表示 true)。為計算出現次數,需要將此值轉換為 1 或 0,這由雙重否定 !! 完成。