最近,有幾個同學讓我看了乙個程式,後來發現問題都是出在使用printf()函式進行輸出時的緩衝模式造成的。比如這樣的程式:
#include
int main()
程式並不是很長,但是就這樣的程式出現了乙個問題:為什麼進入死迴圈之後,並沒有輸出「1234」,這個與我們預想的完全不一樣,還以為是自己的程式寫錯了,可是看了又看,就三行**,怎麼會出錯呢?原來這個就是標準i/o的緩衝模式造成的。
基於流的標準i/o的緩衝模式有三種:全緩衝,半緩衝,無緩衝。
全緩衝:直到緩衝區被填滿,才呼叫系統i/o函式。對於讀操作來說,直到讀入的內容的位元組數等於緩衝區大小或者檔案已經到達結尾,才進行實際的i/o操作,將外存檔案內容讀入緩衝區;對於寫操作來說,直到緩衝區被填滿,才進行實際的i/o操作,緩衝區內容寫到外存檔案中。磁碟檔案通常是全緩衝的。
行緩衝:直到遇到換行符'\n',才呼叫系統i/o庫函式。對於讀操作來說,遇到換行符'\n'才進行i/o操作,將所讀內容讀入緩衝區;對於寫操作來說,遇到換行符'\n'才進行i/o操作,將緩衝區內容寫到外存中。由於緩衝區的大小是有限的,所以當緩衝區被填滿時,即使沒有遇到換行符'\n',也同樣會進行實際的i/o操作。標準輸入stdin和標準輸出stdout預設都是行緩衝的。
無緩衝:沒有緩衝區,資料會立即讀入或者輸出到外存檔案和裝置上。標準出錯stderr是無緩衝的,這樣保證錯誤提示和輸出能夠及時反饋給使用者,供使用者排除錯誤。
看了這個應該明白了,原來這個是行緩衝造成的。我們是試著把
fprintf(stout,
"1234");
改為 fprintf(stout,
"1234\n");
這樣的話,當我們陷入死迴圈之前,"1234"已經顯示在標準輸出上了。或者我們把
fprintf(stout,
"1234");
改為 fprintf(stderr,
"1234");
這個結果和上面的結果是一樣的,只不過顯示在了標準錯誤輸出上了。
如果你不想按照上面的兩種修改方式進行,也可以按照下面的方式,將i/o的緩衝設定為無緩衝方式。
#include
int main()
這樣修改之後的結果與前面兩種方式修改之後的結果是一樣的。
標準I O緩衝
ansi c裡定義的標準i o是一種帶緩衝的高階磁碟i o,目的是盡可能減少使用read和write系統呼叫的次數,從而提高i o效率.標準i o提供了3種型別的緩衝型別.全緩衝.在這種情況下,當填滿標準i o快取後才進行實際i o操作.對駐留在磁碟上的檔案的訪問通常是由標準i o庫實施全緩衝的.行...
標準IO緩衝
一 問題描述 終端無輸出結果。二 分析問題 1.標準輸出 stdout 是行緩衝模式。其何時會輸出在於 printf裡有 n fflush stdout 或setbuf stdout,null 緩衝區已滿三種。在應用程式退出時 exit 會ffush緩衝區。2.上述程式,如果將sleep 1 usl...
標準I O緩衝機制
標準i o庫提供緩衝的目的是盡可能減少使用read和write呼叫的次數。它對每個io流自動的進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準io庫最令人迷惑的也是他的緩衝。標準io提供了3種緩衝機制 1 全緩衝。這種情況下,在填滿標準io緩衝區後才進行實際io操作。對於駐...