2017-04-18 52 views
1

在我的代碼中,我從控制檯輸入並將其寫入文件「test」,我從控制檯輸入輸入信息,直到遇到EOF((fscanf (stdin,「%c%s%d%f」,& a,b,& c,& d))!= EOF),因爲如果我們在掃描時輸入EOF(ctrl + Z),fscanf會返回EOF。但是我的代碼在一次EOF後並沒有停止,它需要兩到三個EOF來掃描終止。我手動檢查第一個EOF什麼也沒有返回,第二個EOF返回一個和第三個EOF返回-1。掃描終止後它也打印出荒謬的東西。 我的代碼如下EOF在C中不能正常工作以及打印也是荒謬的

#include<stdio.h> 
int main() 
{ 
    FILE *f; 
    char a,b[100]; 
    int c; 
    float d; 
    f=fopen("test","w"); 
    if(f==NULL) 
     printf("error"); 
    while((fscanf(stdin,"%c %s %d %f",&a,b,&c,&d))!=EOF) 
     fprintf(f,"%c%s%d%f",a,b,c,d); 
    fclose(f); 
    f=fopen("test","r"); 
    while((fscanf(f,"%c%s%d%f",&a,b,&c,&d))!=EOF) 
     printf("%c %s %d %f\n",a,b,c,d); 
    return 0; 
} 
+0

請給你確切的測試輸入 – kaylum

+0

也許它與按^ Z兩次模擬EOF如果你不是在一個空行的事。按^ Z作爲第一個輸入時,程序的行爲與預期相同。 –

+1

至於爲什麼你必須按兩次以上,是因爲fscanf只有在第一次匹配轉換或失敗之前到達文件結尾時才返回EOF。所以你給了一些輸入,然後按^ Z(2次),然後fscanf不會返回EOF。 –

回答

0

發佈的代碼不能正確處理換行符。第二行輸入將從前一行輸入的\n開始,此字符與%c轉換說明符相匹配。當從鍵盤發送EOF時,此匹配已完成,因此fscanf()函數返回1而不是EOF。第二次發送EOF時,輸入流中不再有字符,也沒有匹配,並返回EOF

這也部分解釋了亂碼輸出,因爲寫入文件的第二行從\n字符開始,而不是預期的字符。此外,寫入該文件的fprintf()調用在字段之間不留空間,因此以後嘗試讀取數據失敗。

此外,雖然代碼檢查文件是否第一次成功打開,但如果沒有,則不執行任何操作。以下是帶有更正的發佈代碼的一個版本,如果文件無法打開,則會退出並顯示錯誤消息,如果文件未能關閉,還會打印錯誤消息,如果在重新打開文件之前文件未能關閉,則退出。

已將一個空格添加到fscanf()格式字符串的開頭,以便跳過包括換行符在內的初始空白字符。在fprintf()格式字符串的指令之間放置了空格,最後在\n之間放置了空格,以便可以通過後續調用fscanf()來識別這些字段。請注意,如果fscanf()格式字符串中沒有%s的寬度說明符,則存在緩衝區溢出的風險。但即使有了這種改進,如果輸入的字符串太大,輸入將會被加上額外的字符。最好使用fgets()sscanf(),更仔細地驗證輸入。

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    FILE *f; 
    char a, b[100]; 
    int c; 
    float d; 

    f = fopen("test", "w"); 
    if(f == NULL) { 
     fprintf(stderr, "Unable to open file for writing\n"); 
     exit(EXIT_FAILURE); 
    } 

    while((fscanf(stdin," %c%99s%d%f", &a, b, &c, &d)) != EOF) 
     fprintf(f,"%c %s %d %f\n", a, b, c, d); 

    if (fclose(f) != 0) { 
     fprintf(stderr, "Unable to close file\n"); 
     exit(EXIT_FAILURE); 
    } 

    f = fopen("test", "r"); 
    if(f == NULL) { 
     fprintf(stderr, "Unable to open file for reading\n"); 
     exit(EXIT_FAILURE); 
    } 

    while((fscanf(f," %c%99s%d%f", &a, b, &c, &d)) != EOF) 
     printf("%c %s %d %f\n", a, b, c, d); 

    if (fclose(f) != 0) { 
     fprintf(stderr, "Unable to close file\n"); 
    } 

    return 0; 
} 

這是一個示例交互。以換行符終止輸入的每一行:

λ> ./a.out 
a first 3 3.14 
b second 42 2.71828 
a first 3 3.140000 
b second 42 2.718280 
+0

非常感謝您的參與你的答案。我不期待這樣的答案。但是,在這個代碼中,閱讀不是終止在第一次EOF的遭遇。是否有可能在EOF的第一次遭遇時終止閱讀。 –

+0

它終止於我的第一個'EOF'。你能否給你的問題添加一個輸入例子? –

+0

對於您的解決方案中給出的相同示例輸入,我必須給出兩個EOF來終止掃描。但是,我正在使用代碼塊來編譯代碼。 –