2010-02-09 33 views
10

爲什麼下面的代碼不起作用?我的意思是,它在控制檯輸出上顯示各種奇怪的字符。爲什麼我需要刷新我的I/O流才能獲得正確的結果?

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 

     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

但是,下面的代碼運行良好。

#include <stdio.h> 
char mybuffer[80]; 
int main() 
{ 
    FILE * pFile; 
    pFile = fopen ("example.txt","r+"); 
    if (pFile == NULL) perror ("Error opening file"); 

    else { 
     fputs ("test",pFile); 
     fflush (pFile);  
     fgets (mybuffer,80,pFile); 
     puts (mybuffer); 
     fclose (pFile); 
     return 0; 
    } 
} 

爲什麼我需要刷新流以獲得正確的結果?

回答

12

此答案由於標準是這樣說的(§7.19.5.3/ 5):

當一個文件被打開與更新模式 ( '+' 作爲第二或在上述模式參數 值列表中的第三個字符 ),輸入和輸出可能是在關聯流上執行的 。 然而,輸出應不直接 接着輸入沒有 居間調用fflush 功能或文件定位 功能(FSEEK,fsetpos,或倒帶), 和輸入不得直接 隨後輸出無需除非輸入操作 遇到文件結束,否則干預調用文件定位 函數。

有一個原因:輸出和輸入通常分開緩衝。當存在刷新或尋道時,它會將緩衝區與文件同步,但否則會讓它們不同步。這大大提高了性能(例如,當您進行讀取時,無需檢查自從讀取數據到緩衝區後您讀取的位置是否已寫入)。

+0

Thx很多!!!!!! – Jaebum 2010-02-09 16:47:05

+0

但爲什麼第二個來源的輸出不是「測試」? 它只是沒有顯示任何內容。 – Jaebum 2010-02-09 17:04:15

+1

@Lee:簡單的說,你從你寫作的地方開始閱讀,你需要回到開始工作。 – falstro 2010-02-09 17:22:23

2

它因爲C文件io使用緩衝區。只有在刷新它時,纔會寫入磁盤,寫入/ n字符或填充緩衝區。

因此,在第一種情況下,當您來讀取文件時,您的文件不包含任何內容。

+0

但即使使用「test \ n」而不是「test」,它仍然不起作用。 – Jaebum 2010-02-09 16:32:42

+0

在這方面的答案是錯誤的:將\ n寫入文件根本沒有任何效果;您必須刷新文件或寫入大量數據以便C庫自行刷新(通常爲4KiB)。 – 2010-02-09 16:38:08

+0

我認爲\ n位取決於實現 - MS確實至少對於C++代碼。 – gbjbaanb 2010-02-09 18:51:27

相關問題