語法書 / AA 競程語法書 下冊 / 第八單元 / 字元的讀入與輸出

8.4 字元的讀入與輸出

開頭救援程式的兩塊拼圖,「運算」上一節已經到手;這一節補上另一塊——把空白和換行也當成一般字元讀進來,然後把慘案收拾掉。

cin >> c:跳過空白與換行

上冊 6.6 用過 cin >> c 逐字讀入。它的規則跟讀整數一樣:先跳過所有空白和換行,讀下一個「看得見」的字元。搭配 4.8 的 EOF 模式,可以把輸入裡的字元一個一個撈出來:

#include <iostream>
using namespace std;

int main() {
    char c;
    while (cin >> c) {         // 讀不到下一個非空白字元時(EOF)迴圈結束
        cout << c << '\n';     // 每讀一個字元,就印出它並換行
    }
    return 0;
}

拿這份程式跑跑看下面的測試資料(字元之間有空白、有空行):

a  b

c

執行結果:

a
b
c

空白和換行全部被跳過了——輸入排得再亂,程式拿到的就是乾乾淨淨的 abc 三個字元。多數題目(例如讀一個網格、讀一串答案)要的正是這種行為。

cin.get(c):一個都不放過

但開頭的 Caps Lock 慘案要求空白和換行原樣保留cin >> c 根本讀不到它們。這時改用 cin.get(c):讀入「下一個字元」,不管它是什麼——空白、換行、Tab,通通照單全收:

#include <iostream>
using namespace std;

int main() {
    char c;
    while (cin.get(c)) {       // 連空白和換行都會讀進來;EOF 時結束
        cout << c;             // 讀到什麼印什麼——原樣複印整份輸入
    }
    return 0;
}

這支程式會把整份輸入一模一樣地印出來(空白幾個、換行在哪,全部保留)。它就是開頭救援程式的骨架:先能原樣複印,再把「字母」那些字元動點手腳——本節結尾就來完成它。

動手試試看:把「原樣複印」的程式改成:複印時順便把所有小寫字母改印成 *,其他字元照舊(提示:c >= 'a' && c <= 'z')。跑一段有空白、換行的輸入驗證格式沒有跑掉。