1. 程式人生 > >C語言 fflush和stdin stdout stderr之間的聯絡

C語言 fflush和stdin stdout stderr之間的聯絡

寫在前面:

閱讀這篇文章前,讀者應該大致瞭解C語言“緩衝區”的概念,在前面的文章中有詳細介紹。

**Stdin:** 是標準輸入,一般指鍵盤輸入到緩衝區裡的東西。
**Stdout:** C語言中的 stdout 是一個定義在<stdio.h>的巨集(macro),它展開到一個 FILE* (“指向 FILE 的指標”)型別的表示式(不一定是常量),這個表示式指向一個與標準輸出流(standard output stream)相關連的 FILE 物件。
**stderr:** 【unix】標準輸出(裝置)檔案,對應終端的螢幕。程序將從標準輸入檔案中得到輸入資料,將正常輸出資料輸出到標準輸出檔案,而將錯誤資訊送到標準錯誤檔案中。在C中,程式執行時,一直處於開啟狀態。

        敲黑板了,同志們,以上是百度百科給出的解釋,相信會有人和我一樣還是似懂非懂的樣子。OK,下面我來具體介紹:

         我們在寫C程式時經常遇到printf(),fprintf(),perror(),這些東西到底有什麼作用。說到這不得不提及stdin,stdout,stderr。想想,我們在用C去寫檔案時的操作:

 File *fp=fopen();

定義一個指向檔案流的指標,通過操作這個指標你就能進行檔案讀寫,開啟關閉。
其實,stdin,stdout,stderr就是這個fp,不過他是隨著計算機系統的開啟預設開啟的,其中0就是stdin,表示輸入流,指從鍵盤輸入,1代表stdout,2代表stderr,1,2預設是顯示器。printf()其實就是向stdout中輸出,等同於fprintf(stdout,“xxx”),perror()其實就是向stderr中輸出,相當於fprintf(stderr,“xxx”),那到底stdout,和stderr有什麼區別和作用呢?
        stderr,和stdout重要的一點區別,stderr是沒有緩衝的,它立即輸出,而stdout預設是行緩衝,也就是它遇到‘\n’,才向外輸出內容,如果你想stdout也實時輸出內容,那就在輸出語句後加上fflush(stdout),這樣就能達到實時輸出的效果。
談到這裡,我們趁熱打鐵認識一下fflush()函式。

 

FFLUSH函式:

fflush是一個計算機函式,功能是沖洗流中的資訊,該函式通常用於處理磁碟檔案。fflush()會強迫將緩衝區內的資料寫回引數stream 指定的檔案中。

函式原型:int fflush(FILE *stream) ;

函式功能:清除一個流,即清除檔案緩衝區.

常用場合:

一、fflush(stdin)重新整理標準輸入緩衝區,把輸入緩衝區裡的東西丟棄
fflush(stdout)重新整理標準輸出緩衝區,把輸出緩衝區裡的東西列印到標準輸出裝置上。
二、scanf()函式接收輸入資料時,遇以下情況結束一個數據的輸入:(不是結束該scanf函式,scanf函式僅在每一個數據域均有資料,並按回車後結 束)。
① 遇空格、“回車”、“跳格”鍵。
② 遇寬度結束。
③ 遇非法輸入。
鍵盤緩衝區就可能有殘餘資訊問題。
scanf()函式應該只是掃描stdin流,這個殘存資訊是在stdin中
解決就要在scanf()函式之後加個fflush(stdin)
三、寫檔案的時候 不會馬上進行物理磁碟的檔案讀寫,而是先寫入快取,當快取中內容達到一定程度後再寫

FILE *fp=fopen("a.txt","w");
fprintf(fp,"abcdef");
fflush(fp);

大家可以回想一下之前介紹過的“進度條”小程式,就會發現裡邊在每一次在迴圈體的最後,都要進行fflush(stdout)一下。這時候,大家應該就會明白這個操作的含義了:沒錯,就是因為stdout預設是行緩衝,所以沒有遇到‘\n’之前,我們必須要手動的將緩衝區的內容刷到螢幕上來*()*