語法書 / AA 競程語法書 下冊 / 第八單元 / 字元的分類與 cctype 函式

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.4while (cin >> c) 把輸入逐字讀完,統計其中數字字元字母字元各有幾個(isdigitisalpha 一人一句)。學完 8.7 之後,可以再想想改用字串讀入要怎麼寫。