看板 C_and_CPP 關於我們 聯絡資訊
標題不知該打什麼,最近正好在跟人討論這個, 發現16192那篇有些東西講錯,所以把重點重新整理了一下, 以下物件都是指cout、clog、cerr 1.該物件所用的stream是否按照規定分配buffer 全緩衝:buffer滿了才執行fflush() 行緩衝:buffer滿了or碰到換行字元才執行fflush() 無緩衝:不管buffer有沒有滿都執行fflush() cout使用stdout stream cerr跟clog使用stderr stream console下 標準 windows linux stdout|行/無緩衝|全緩衝 |行緩衝 | stderr|行/無緩衝|全緩衝 |無緩衝 | 非console(即重定向) 標準 windows linux stdout|全緩衝 |全緩衝 |全緩衝 | stderr|行/無緩衝|全緩衝 |無緩衝 | 以上是預設值,有一點要釐清,全/行/無緩衝只是該stream的特性, 與它有沒有buffer並沒有關係,網路上的解釋幾乎都把這兩個混在一起講, 拿windows來說,乍看之下會等到buffer滿才輸出,但實際上是直接輸出, 因為沒有分配buffer,如果把屬性是全/行緩衝且分配buffer的stream的flag, 改成_IONBF,也會直接執行fflush() 如果要分配buffer給stream,可以用setbuf()和setvbuf(), 用前者時要注意,一但用它分配buffer後,原本的緩衝特性會消失, 舉例來說,setbuf(stdout,buf)會變為全緩衝, setbuf(stdout,0)會變為無緩衝,且buffer不能是local變數, 因為最後一次fflush()是在exit()裡執行,那時local變數已經被釋放 註:windows下的_IOLBF,作用等同於_IOFBF,也就是windows實際上沒有行緩衝 2.該物件是否按照規定設置ios::unitbuf 如果有設ios::unitbuf,就直接執行fflush(), 即使底下stream設成全緩衝跟分配buffer也一樣, 除非手動設定,否則只有cerr才有設ios::unitbuf 如果要修改物件的ios::unitbuf,可用setf()或unsetf()設定 3.該物件的是否按照規定綁定別的物件 標準 windows linux clog.tie()|null |&cout|null | cerr.tie()|&cout|&cout|&cout| cout.tie()|null |null |null | 如果有綁別的物件,當自己被寫入時, 不管自己能不能馬上跑fflush(), 都會先讓被綁定的物件執行fflush() 如果要修改綁定的物件,就用tie()來設,傳0代表不綁定 下列網站也寫cin、cerr綁定cout(C++11) http://www.cplusplus.com/reference/iostream/ios/tie/ 4.換行字元跟endl 前者只能讓行緩衝的stream跑fflush(), 後者則強迫cout、cerr、clog跑fflush() 5.如果一直到main()結束都沒有跑fflush() 那麼stdout會先輸出,接著才是stderr 6.main()結束後,不可再用cout、cerr、clog來輸出 首先來看exit()的標準流程 A.銷毀thread變數 B.銷毀global變數/銷毀函式裡的static變數/執行atexit註冊函式 C.讓所有的C stream執行fflush(),接著關閉它們 D.砍掉暫存檔 E.歸還控制權給OS 在執行dtor/atexit註冊函式時,無法保證cout、cerr、clog這些物件還在, 雖然標準是有規定這些物件最慢銷毀 總結: 沒分配buffer、屬性為無緩衝、ios::unitbuf不為0、buffer已滿 、行緩衝碰到'\n'、讓物件使用endl/flush/flush(),綁定自己的物件被寫入 以上只要有一個成立就會跑fflush() -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.252.64.44
tinlans:...局...局...局部...局部變量? 11/20 07:41
loveflames:local variable啦,腦袋還沒從大陸的用語轉過來 11/20 07:42
loveflames:沒人回,看來似乎是太基本了(汗) 11/22 10:14
nowar100:心得不錯啊 不過通常我都懶得管有沒有緩衝 XD 11/22 11:20
loveflames:用fork()時,前面如果先設成unbuffered就省事多了 11/22 14:45
loveme00835:我也沒在管緩衝這部份的問題 XD 11/22 17:50
※ 編輯: loveflames 來自: 220.130.247.105 (03/21 10:55)