8.5 字元的分類與 cctype 函式
競程題目整天在問:「這個字元是不是數字?」「是不是大寫字母?」你已經會手寫判斷:
if (c >= '0' && c <= '9') { ... } // c 是數字字元
這寫法完全正確,也永遠值得會。不過 <cctype> 函式庫早就幫你把常用判斷都包好了——名字還取得一目瞭然:
| 函式 | 判斷「c 是不是…」 | 等價的手寫範圍 |
|---|---|---|
isdigit(c) |
數字字元 | '0' <= c && c <= '9' |
isupper(c) |
大寫字母 | 'A' <= c && c <= 'Z' |
islower(c) |
小寫字母 | 'a' <= c && c <= 'z' |
isalpha(c) |
字母(大寫或小寫) | isupper(c) || islower(c) |
isalnum(c) |
字母或數字 | isalpha(c) || isdigit(c) |
isspace(c) |
空白字元(空格、換行、Tab 等) | 見下方說明 |
isprint(c) |
可顯示字元 | 編號 32 \sim 126 |
搭配兩個轉換函式:
| 函式 | 功能 |
|---|---|
toupper(c) |
若 c 是小寫字母,回傳對應大寫;否則原樣回傳 |
tolower(c) |
若 c 是大寫字母,回傳對應小寫;否則原樣回傳 |
「原樣回傳」很貼心:toupper('7') 就是 '7',不用先判斷是不是字母再轉。
¶兩個正式的分類名詞
8.1 提過可顯示字元(編號 32 \sim 126)與控制字元(其餘)。這裡再補一類競程會遇到的:空白字元(whitespace characters)——就是 cin >> 會跳過的那群,包括空格(32)和編號 9 \sim 13 的控制字元(Tab、換行等)。isspace(c) 判斷的正是這一群。
¶範例程式碼
一個小任務:給一個字元(保證是數字、大寫、小寫三者之一),判斷它是哪類:
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char c;
cin >> c;
if (isdigit(c)) {
cout << "digit" << '\n';
} else if (isupper(c)) {
cout << "upper" << '\n';
} else {
cout << "lower" << '\n';
}
return 0;
}
執行結果(輸入 Q):
upper
順帶一提,8.4 救援程式的判斷式 c >= 'A' && c <= 'Z' 也可以改寫成 isupper(c),行數更短、意圖更明顯——兩種寫法都對,選你順手的。
動手試試看:用 8.4 的 while (cin >> c) 把輸入逐字讀完,統計其中數字字元和字母字元各有幾個(isdigit/isalpha 一人一句)。學完 8.7 之後,可以再想想改用字串讀入要怎麼寫。