前言
之前在做課程設計時, 無意間想起了以前做ACM題常用的一行語句:
- while(scanf("%d", &a) != EOF)
忽然間對這句話作用產生了好奇,想了半天終於有了一點結果。
1. EOF是什麼東東?
EOF是一個宏,許多函數(包括scanf)在讀文件讀到末尾時,會返回EOF。[1]
2. while(scanf()!=EOF)流程圖
先看看以前學過的3種循環語句的流程圖:
===================================================================================
① for循環
- for (表達式1; 表達式2; 表達式3)
- {
- 循環語句;
- }
② while循環
- while (判斷語句)
- {
- 循環語句;
- }
③ do-while循環
- do
- {
- 循環語句;
- }while(循環條件);
===================================================================
顯然,while (scanf("%d", &a) != EOF)不像以上任何一種的流程圖,
那麼while(scanf("%d", &a) != EOF)的流程圖是怎樣的?
應該是像下面這樣:
- while (scanf() != EOF)
- {
- 循環語句;
- }
3. OnlineJuge的評判時,該語句的作用
OJ評判的原理應該是這樣的:
輸入:通過管道命令,將一個包含若干測試用例的文件作爲【標準輸入流】,所以需要while(scanf() != EOF)來判斷測試文件是否讀完。
輸出:通過管道命令,將【標準輸出流】,輸出到一個文件中。
- //輸入輸出
- ./prog < test_input > output_file
4. 本機運行程序時,該語句的作用。
當在本機運行程序,運行while(scanf() != EOF)時,程序會進入阻塞狀態,即,
運行到上面流程圖中【temp = scanf("%d", &a)】這一句 時,程序會進入到阻塞狀態——在這一語句處暫停。
那麼如何在本機輸入的時候達到EOF的效果呢?
Linux中,在新的一行的開頭,按下Ctrl-D,就代表EOF;
Windows中,Ctrl-Z表示EOF。[2]
5. 等效的語句
雖然該語句用起來很方便,卻不太好理解,因此建議用以下等效的語句來代替該語句。
- while (true)
- {
- if (scanf("%d", &a) != EOF)
- break;
- }