cin 可以用來從鍵盤輸入數據;將標准輸入重定向為文件后,cin 也可以用來從文件中讀入數據。在輸入數據的多少不確定,且沒有結束標志的情況下,該如何判斷輸入數據已經讀完了呢?
從文件中讀取數據很好辦,到達文件末尾就讀取結束了。從控制台讀取數據怎么辦呢?總不能把控制台關閉吧?這樣程序也運行結束了!
其實,在控制台中輸入特殊的控制字符就表示輸入結束了:
- 在 Windows 系統中,通過鍵盤輸入時,按 Ctrl+Z 組合鍵后再按回車鍵,就代表輸入結束。
- 在 UNIX/Linux/Mac OS 系統中,Ctrl+D 代表輸入結束。
不管是文件末尾,還是 Ctrl+Z 或者 Ctrl+D,它們都是結束標志;cin 在正常讀取時返回 true,遇到結束標志時返回 false,我們可以根據 cin 的返回值來判斷是否讀取結束。
cin 判斷控制台(鍵盤)讀取結束
輸入若干個正整數,輸出其中的最大值,程序該如何編寫?
- #include <iostream>
- using namespace std;
- int main()
- {
- int n;
- int maxN = 0;
- while (cin >> n){ //輸入沒有結束,cin 就返回 true,條件就為真
- if (maxN < n)
- maxN = n;
- }
- cout << maxN <<endl;
- return 0;
- }
在 Windows 下運行該程序,先輸入以下整數:
10
30
93
206
8
然后在按下 Ctrl+Z 組合鍵(可以在當前行,也可以在新的一行),接着按下回車鍵,輸入就結束了,此時 cin 返回 false,循環結束,得到了最大值。
完整的輸入輸出結果如下所示:
10↙
30↙
93↙
206↙
8↙
^Z↙
206
↙
表示回車鍵,^Z
表示 Ctrl+Z 組合鍵。
cin 判斷文件讀取結束
如果將標准輸入重定向為某個文件,如在程序開始添加freopen("test.txt", "r", stdin);
語句,或者不添加上述語句,但是在 Windows 的“命令提示符”窗口中輸入:
mycin < test.txt //假設編譯生成的可執行文件的名字為 mycin.exe
則都能使得本程序不再從鍵盤輸入數據,而是從 test.txt 文件輸入數據(前提是 test.txt 文件和 mycin.exe 在同一個文件夾中)。在這種情況下,test.txt 文件中並不需要包含 Ctrl+Z,只要有用空格或回車隔開的若干個正整數即可。
cin 讀到文件末尾時,cin>>n
就會返回 false,從而導致程序結束。例如,假定 test.txt 文件中的內容如下所示:
112
23123
34 444 55
44
對於前面的代碼,在“命令提示符”窗口中先 cd 到 mycin.exe 所在目錄,然后輸入mycin < test.txt
,則程序的輸出是:
23123
下面是筆者實操演示圖:

答疑解惑
在《C++重載<<和>>》一節中我們提到過 istream 類將>>
重載為成員函數,而且這些成員函數的返回值是 cin 的引用。准確地說,cin>>n
的返回值的確是 istream & 類型的,而 while 語句中的條件表達式的返回值應該是 bool 類型、整數類型或其他和整數類型兼容的類型,istream & 顯然和整數類型不兼容,為什么while(cin>>n)
還能成立呢?
這是因為,istream 類對強制類型轉換運算符 bool 進行了重載,這使得 cin 對象可以被自動轉換成 bool 類型。所謂自動轉換的過程,就是調用 cin 的 operator bool() 這個成員函數,而該成員函數可以返回某個標志值,該標志值在 cin 沒有讀到輸入結尾時為 true,讀到輸入結尾后變為 false。對該標志值的設置,在 operator <<() 成員函數中進行。
如果 cin 在讀取過程中發生了錯誤,cin>>n
這樣的表達式也會返回 false。例如下面的程序:
- #include <iostream>
- using namespace std;
- int main()
- {
- int n;
- while (cin >> n)
- cout << n << endl;
- return 0;
- }
程序本該輸入整數,如果輸入了一個字母,則程序就會結束。因為,應該讀入整數時卻讀入了字母也算讀入出錯。