2015-03-19 66 views
3

最近我正在閱讀Deitel編寫的C How to Program,第7版的文件處理部分。對於寫入文件,它使用這個例子:C程序打印最後一行兩次(文件I/O)

// Fig. 11.2: fig11_02.c 
// Creating a sequential file 
#include <stdio.h> 

int main(void) 
{ 
    unsigned int account; // account number 
    char name[ 30 ]; // account name 
    double balance; // account balance 

    FILE *cfPtr; // cfPtr = clients.dat file pointer 

    // fopen opens file. Exit program if unable to create file 
    if ((cfPtr = fopen("clients.dat", "w")) == NULL) { 
     puts("File could not be opened"); 
    } // end if 
    else { 
     puts("Enter the account, name, and balance."); 
     puts("Enter EOF to end input."); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 

     // write account, name and balance into file with fprintf 
     while (!feof(stdin)) { 
     fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 
     } // end while 

     fclose(cfPtr); // fclose closes file 
    } // end else 
} // end main 

,你可以看到,它會掃描並打印數據先在別的塊,然後在while循環。因爲我認爲做兩遍沒有意義,它只是刪除了if-else部分並編譯它。以及它工作正常,但後來我意識到它重複輸出文件中的最後一行輸入。在Deitel版本中沒有。

我的版本有什麼問題?爲什麼它複製最後一行?我認爲這可能是一個循環條件的問題,但我不知道..

編輯:此代碼是由Dietel使用,我不相信這是錯誤的,因爲他正在使用if-else來修復引起的問題通過!feof。但我想知道如何解決它,而沒有,如果 - 其他。

在編輯的版本

沒有的if-else,只帶環的輸入和輸出是:

輸入:

1 test 25.6 
2 some 95 

輸出:

1 test 25.6 
2 some 95 
2 some 95 
+0

可能重複(http://stackoverflow.com/questions/5431941/while-feof-文件是總是錯誤的) – 2015-03-19 11:26:53

+1

我讀過,但我認爲我的情況是不同的。 – vvvsg 2015-03-19 11:29:12

+0

在完成'main'函數之前,您應該輸入'return 0;'或某個數字。 – Gophyr 2015-03-19 11:38:58

回答

4

重點是E OF測試必須始終遵循scanf(),並在打印讀取信息之前進行。

if-else條件僅用於處理最終打開的錯誤條件,所以如何修改代碼並不完全清楚。然而人們常常試圖做的事:

while (!feof(stdin)) { 
    scanf("%d%29s%lf", &account, name, &balance); 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 

,這是錯誤的,因爲讀的是最後的數據時,它不會「讀EOF」(EOF是你讀完數據你後遇到條件):只隨後的scanf()將會執行,並且輸出函數將會輸出錯誤的數據(以前的數據,由於輸入錯誤而未被覆蓋,這就是最後一行重複的原因)。

例如,這是正確的:

for (;;) { 
    scanf("%d%29s%lf", &account, name, &balance); 
    if (feof(stdin)) break; 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 

而實際上我更喜歡重複相同scanf()線兩次被Deitel公司的建議。

1

更改爲:

else { 
    puts("Enter the account, name, and balance."); 
    puts("Enter to end input."); 

    // write account, name and balance into file with fprintf 
    while (scanf("%d%29s%lf", &account, name, &balance)==3) 
    { 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 
    fclose(cfPtr); // fclose closes file 
} // end else 
+0

3是參數的數量正確嗎? – vvvsg 2015-03-19 11:40:32

+0

閱讀文檔(習慣於查找 - 它有幫助)。 – 2015-03-19 11:55:46

0

改正的代碼是:

while (!feof(stdin)) { 
    if(!feof(stdin)) 
    { 
     fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 
    } 
} 
的[ 「而(!FEOF(文件))」 永遠是錯]