從while(scanf() != EOF)說到ACM OnlineJuge的評判原理

前言

之前在做課程設計時, 無意間想起了以前做ACM題常用的一行語句:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. while(scanf("%d", &a) != EOF)  

忽然間對這句話作用產生了好奇,想了半天終於有了一點結果。


1. EOF是什麼東東?

EOF是一個宏,許多函數(包括scanf)在讀文件讀到末尾時,會返回EOF。[1]


2. while(scanf()!=EOF)流程圖

先看看以前學過的3種循環語句的流程圖:

===================================================================================

① for循環

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. for (表達式1; 表達式2; 表達式3)  
  2. {  
  3.     循環語句;  
  4. }  

 

 ② while循環

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. while (判斷語句)  
  2. {  
  3.     循環語句;  
  4. }  
 

③ do-while循環

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. do  
  2. {  
  3.     循環語句;  
  4. }while(循環條件);  

===================================================================

顯然,while (scanf("%d", &a) != EOF)不像以上任何一種的流程圖,

那麼while(scanf("%d", &a) != EOF)的流程圖是怎樣的?

應該是像下面這樣:

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. while (scanf() != EOF)  
  2. {  
  3.     循環語句;  
  4. }  

          

3. OnlineJuge的評判時,該語句的作用

OJ評判的原理應該是這樣的:

輸入:通過管道命令,將一個包含若干測試用例的文件作爲【標準輸入流】,所以需要while(scanf() != EOF)來判斷測試文件是否讀完。

輸出:通過管道命令,將【標準輸出流】,輸出到一個文件中。

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. //輸入輸出  
  2. ./prog < test_input > output_file   
評判:將程序的【輸出文件】與【正確答案文件】進行比對:如果一樣,則返回程序正確提示;否則返回程序錯誤的提示。


4. 本機運行程序時,該語句的作用。

當在本機運行程序,運行while(scanf() != EOF)時,程序會進入阻塞狀態,即,

運行到上面流程圖中【temp = scanf("%d", &a)】這一句 時,程序會進入到阻塞狀態——在這一語句處暫停。


那麼如何在本機輸入的時候達到EOF的效果呢?

Linux中,在新的一行的開頭,按下Ctrl-D,就代表EOF;

Windows中,Ctrl-Z表示EOF。[2]


5. 等效的語句

雖然該語句用起來很方便,卻不太好理解,因此建議用以下等效的語句來代替該語句。

[cpp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. while (true)  
  2. {  
  3.     if (scanf("%d", &a) != EOF)  
  4.         break;  
  5. }  

原文地址:http://blog.csdn.net/timberwolf_2012/article/details/18096493
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章