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
空白和換行全部被跳過了——輸入排得再亂,程式拿到的就是乾乾淨淨的 a、b、c 三個字元。多數題目(例如讀一個網格、讀一串答案)要的正是這種行為。
¶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')。跑一段有空白、換行的輸入驗證格式沒有跑掉。