字元分類函式(返回非 0 為真,0 為假)
| 函式 | 判斷條件 | 範例字元 |
isalpha(c) | 字母 A-Z a-z | 'A' 'z' |
isdigit(c) | 數字 0-9 | '5' |
isalnum(c) | 字母或數字 | 'A' '9' |
isxdigit(c) | 十六進位數字 0-9 A-F a-f | 'F' 'a' |
islower(c) | 小寫字母 | 'a' |
isupper(c) | 大寫字母 | 'Z' |
isspace(c) | 空白字元:空格、\t、\n、\v、\f、\r | ' ' '\n' |
iscntrl(c) | 控制字元(非列印) | '\0' '\b' |
ispunct(c) | 標點符號(非字母數字空白) | '.' ',' |
isprint(c) | 可列印字元(含空格) | 'A' ' ' |
isgraph(c) | 可列印非空格字元 | 'A' '.' |
字元大小寫轉換
| 函式 | 行為 | 備註 |
toupper(c) | 小寫→大寫,非小寫原樣返回 | 需包含 <ctype.h> |
tolower(c) | 大寫→小寫,非大寫原樣返回 | |
引數型別:int(實際傳 unsigned char 或 EOF),直接傳 char 可能因符號擴展導致未定義行為,建議轉型:toupper((unsigned char)ch)。
實戰範例 1:統計字串中字母與數字個數
#include <ctype.h> #include <stdio.h>
int main(void) {
char str[] = "C99 Standard";
int alpha = 0, digit = 0;
for (char *p = str; *p; ++p) {
if (isalpha(*p)) ++alpha;
else if (isdigit(*p)) ++digit;
}
printf("字母:%d 數字:%d\n", alpha, digit); // 字母:10 數字:2
return 0;
}
實戰範例 2:大小寫轉換
char s[] = "Hello World";
for (char *p = s; *p; ++p) *p = toupper((unsigned char)*p);
puts(s); // HELLO WORLD
實戰範例 3:isspace 替換空白為換行
char line[] = "Split this line";
for (char *p = line; *p; ++p) {
if (isspace((unsigned char)*p)) putchar('\n');
else putchar(*p);
}
進階應用:十六進位字串轉整數
long hex_to_long(const char *s) {
while (isspace((unsigned char)*s)) ++s; // 跳過前導空白
long val = 0;
while (isxdigit((unsigned char)*s)) {
int digit = isdigit(*s) ? *s - '0' : toupper(*s) - 'A' + 10;
val = val * 16 + digit;
++s;
}
return val;
}
// hex_to_long("1A") → 26
常見陷阱
- 直接傳
char 給 isxxx:若 char 有號且值 > 127,會變負數導致 UB。永遠轉型為 unsigned char。
- 區域設定影響:
setlocale 可能改變字元分類行為,嚴格 ASCII 環境可忽略。
tolower/toupper 返回 int,賦值給 char 時需轉型。