2009-09-15 24 views
20

我正在使用以下C代碼從用戶處獲取輸入,直到發生EOF,但是問題是此代碼無法工作,它會在首次輸入後終止。任何人都可以告訴我這個代碼有什麼問題。提前致謝。在C中檢測EOF

float input; 

printf("Input No: "); 
scanf("%f", &input); 

while(!EOF) 
{ 
    printf("Output: %f", input); 
    printf("Input No: "); 
    scanf("%f", &input); 
} 
+3

注意:假設用戶輸入不被管道輸送,檢查EOF可能是不理想的,因爲這個都通常,這意味着用戶必須按ctrl + d退出,這是不明顯的 – Brian 2009-09-15 18:41:33

回答

40

EOF只是一個具有值(通常爲-1)的宏。您必須針對EOF進行測試,例如getchar()調用的結果。

測試流結束的一種方法是使用feof函數。

if (feof(stdin)) 

注意的是,國家「流的末尾」只會後設置失敗的讀取。

在你的例子中,你應該檢查scanf的返回值,如果這表明沒有字段被讀取,那麼檢查文件結束。

+2

謝謝Charles Bailey。 – itsaboutcode 2009-09-15 18:46:44

+3

並注意Brian的評論:stdin通常不會註冊EOF,因爲用戶可以輸入的內容總是更多。在Unixy系統上,這通常意味着control-D。 – 2009-09-15 19:08:21

+0

這取決於你的意思是我的'通常'。如果您已重定向標準輸入(文件或管道,unix或窗口),EOF通常會正確發送信號。在一個交互式的unix終端中^ D通常工作,在windows文本模式下,一行開頭的^ Z起作用。 – 2009-09-15 19:12:19

8

EOF是C中的常量。您沒有檢查EOF的實際文件。您需要這樣做

while(!feof(stdin)) 

這是feof的文檔。您也可以檢查返回值scanf。它返回已成功轉換項目的數量,如果達到文件末尾,則返回EOF

+0

FILE函數是否包含比使用EOF更好的測試變量?看起來好像在實際的文件指針上檢查一個狀態會比使用一些只有一半時間的奇怪函數更好。 – MarcusJ 2015-07-13 07:42:09

0

爲出發點,你可以嘗試用

while(!feof(stdin)) 
4

的另一個問題是,你只scanf("%f", &input);閱讀更換

while(!EOF) 

。如果用戶輸入的內容不能被解釋爲C浮點數,如「pi」,則scanf()調用不會將任何內容分配給input,並且不會從那裏進行。這意味着它會試圖繼續閱讀「pi」,並失敗。

鑑於while(!feof(stdin))哪些其他海報正確推薦,如果您鍵入「pi」,將出現無限循環打印出前值input並打印提示,但該程序不會處理任何新的輸入。

scanf()返回分配給它所輸入變量的數量。如果它沒有賦值,那意味着它沒有找到一個浮點數,並且您應該閱讀更多的輸入,例如char string[100];scanf("%99s", string);。這將從輸入流中移除下一個字符串(最多99個字符,無論如何 - 多餘的char用於字符串上的空終止符)。

你知道,這讓我想起我討厭scanf()的所有原因,以及爲什麼我用fgets()代替,然後用sscanf()解析它。

-1

你想檢查scanf()的結果,以確保有一個成功的轉換;如果沒有,則三件事情之一是真實的:

  1. scanf()窒礙對%f轉換說明符無效的字符(即,某些不是數字的東西,點,'e'或'E');
  2. scanf()檢測到EOF;
  3. scanf()在讀取stdin時檢測到錯誤。

實施例:

int moreData = 1; 
... 
printf("Input no: "); 
fflush(stdout); 
/** 
* Loop while moreData is true 
*/ 
while (moreData) 
{ 
    errno = 0; 
    int itemsRead = scanf("%f", &input); 
    if (itemsRead == 1) 
    { 
    printf("Output: %f\n", input); 
    printf("Input no: "); 
    fflush(stdout); 
    } 
    else 
    { 
    if (feof(stdin)) 
    { 
     printf("Hit EOF on stdin; exiting\n"); 
     moreData = 0; 
    } 
    else if (ferror(stdin)) 
    { 
     /** 
     * I *think* scanf() sets errno; if not, replace 
     * the line below with a regular printf() and 
     * a generic "read error" message. 
     */ 
     perror("error during read"); 
     moreData = 0; 
    } 
    else 
    { 
     printf("Bad character stuck in input stream; clearing to end of line\n"); 
     while (getchar() != '\n') 
     ; /* empty loop */ 
     printf("Input no: "); 
     fflush(stdout); 
    } 
} 
+1

清除行結束時可能出現無限循環。我建議'while(((ch = getchar())!= EOF)&&(ch!='\ n'))/ * void * /;''然後檢查(再次)EOF並設置''moredata = 0;'' – pmg 2009-09-15 19:58:45

+0

請打開一個新問題。 – andig 2018-01-22 07:46:29

-2
while(scanf("%d %d",a,b)!=EOF) 
{ 

//do ..... 
} 
+0

我已經使用這個.... – 2015-08-02 11:37:20

+0

最新錯誤:/我不明白 – 2015-08-02 11:37:53