某日一朋友寫了乙個hello world**,出不來結果,**如下:
#include
intmain(int argc, char **argv)
注意到,在**中printf語句列印的字串最後沒有帶換行符,而且最後呼叫了_exit函式,這導致了在終端螢幕上顯示不出來字串"hello world!"。
首先介紹一下unix裡面關於標準io的幾種緩衝機制:
1、全緩衝 。全緩衝指的是系統在填滿標準io緩衝區之後才進行實際的io操作;注意,對於駐留在磁碟上的檔案來說通常是由標準io庫實施全緩衝。
2、行緩衝 。在這種情況下,標準io在輸入和輸出中遇到換行符時執行io操作;注意,當流涉及終端的時候,通常使用的是行緩衝。
3、無緩衝 。無緩衝指的是標準io庫不對字元進行緩衝儲存;注意,標準出錯流stderr通常是無緩衝的。
其次介紹一下幾個退出函式:
1、exit ()。呼叫exit函式之後,它首先會執行一系列的清理處理,包括呼叫執行各終止處理程式,關閉所有標準io流等,然後進入核心。
2、_exit ()。與exit不同的是,它不進行清理工作而直接進入核心。此函式由posix.1說明,放在unistd.h裡面。
3、_exit ()。同樣,它也不進行清理工作而直接進入核心。此函式跟exit一樣由iso c說明,放在stdlib.h裡面。
現在回過頭來看上面的那段**,很容易發現,由於printf函式是行緩衝的(因為它要往終端輸出資料),而且要列印的字串不帶換行符,因此在它沒有遇到換行符或者沒有填滿緩衝區之前不會進行實際的io操作,而緊接下來的_exit函式又立即進入核心沒有處理io緩衝區,所以我們在終端上看不到hello world語句。
我們可以有很多方法修正這段**。最簡單的莫過於增加乙個換行符:
#include
intmain(int argc, char **argv)
此時行緩衝遇到換行符/n,執行實際io操作。
其次,我們可以呼叫exit函式,讓它幫我們進行相應的io處理:
#include
intmain(int argc, char **argv)
exit函式在進入核心之前,對儲存在緩衝區內的資料進行沖洗,然後關閉io流。
或者,我們可以改變標準輸出流的預設緩衝模式:
#include
intmain(int argc, char **argv)
此時,由於呼叫了setvbuf函式,把標準輸出流預設的行緩衝變成了無緩衝(具體請查閱setvbuf函式實現機制),因此呼叫printf時立即輸出。
當然,我們還可以呼叫fclose函式來達到此目的:
#include
intmain(int argc, char **argv)
實際上,
fclose函式隱含包含了一次fflush操作,把緩衝區內的資料沖洗到終端。
標準I O緩衝 全緩衝 行緩衝 無緩衝
說明 我只對網路資源進行了整合,方便學習 基於流的操作最終會呼叫read或者write函式進行i o操作。為了使程式的執行效率最高,流物件通常會提供緩衝區,以減少呼叫系統i o庫函式的次數。基於流的i o提供以下3種緩衝 全緩衝 直到緩衝區被填滿,才呼叫系統i o函式。對於讀操作來說,直到讀入的內容...
標準I O緩衝 全緩衝 行緩衝 無緩衝
說明 我只對網路資源進行了整合,方便學習 基於流的操作最終會呼叫read或者write函式進行i o操作。為了使程式的執行效率最高,流物件通常會提供緩衝區,以減少呼叫系統i o庫函式的次數。基於流的i o提供以下 3種緩衝 全緩衝 直到緩衝區被填滿,才呼叫系統i o函式。對於讀操作來說,直到讀入的內...
標準IO緩衝詳解全緩衝 行緩衝 不緩衝
標準i o庫提供緩衝的目的是盡可能地減少使用read和write呼叫的次數。他也對每個i o流自動地進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準i o庫最令人迷惑的也是他的緩衝。標準i o提供了三種型別的緩衝 1 全緩衝。這種情況下,在填滿標準i o緩衝區後才進行實際i...