每個 IO 對象管理一個緩沖區,用于存儲程式讀寫的資料。如有下面語句:
系統将字元串字面值存儲在與流 os 關聯的緩沖區中。下面幾種情況将導緻緩沖區的内容被重新整理,即寫入到真實的輸出裝置或者檔案:
1. 程式正常結束。作為 main 傳回工作的一部分,将清空所有輸出緩沖區。
2. 在一些不确定的時候,緩沖區可能已經滿了,在這種情況下,緩沖區将會在寫下一個值之前重新整理。
3. 用操縱符(第 1.2.2 節)顯式地重新整理緩沖區,例如行結束符 endl。
4. 在每次輸出操作執行完後,用 unitbuf 操作符設定流的内部狀态,進而清空緩沖區。
5. 可将輸出流與輸入流關聯(tie)起來。在這種情況下,在讀輸入流時将重新整理其關聯的輸出緩沖區。
輸出緩沖區的重新整理
endl 操縱符,用于輸出一個換行符并重新整理緩沖區。
flush操縱符,用于重新整理流,但不在輸出中添加任何字元。
ends操縱符,這個操縱符在緩沖區中插入空字元 null,然後後重新整理它:
如果需要重新整理所有輸出,最好使用 unitbuf 操縱符。這個操縱符在每次執
行完寫操作後都重新整理流:
等價于:
nounitbuf 操縱符将流恢複為使用正常的、由系統管理的緩沖區重新整理方式。
如果程式不正常結束,輸出緩沖區将不會重新整理。在嘗試調試已崩潰的程式時,通常會根據最後的輸出找出程式發生錯誤的區域。如果崩潰出現在某個特定的輸出語句後面,則可知是在程式的這個位置之後出錯。
調試程式時,必須保證期待寫入的每個輸出都确實被重新整理了。因為系統不會在程式崩潰時自動重新整理緩沖區,這就可能出現這樣的情況:程式做了寫輸出的工作,但寫的内容并沒有顯示在标準輸出上,仍然存儲在輸出緩沖區中等待輸出。
如果需要使用最後的輸出給程式錯誤定位,則必須确定所有要輸出的都已經輸出。為了確定使用者看到程式實際上處理的所有輸出,最好的方法是保證所有的輸出操作都顯式地調用了 flush 或 endl。
如果僅因為緩沖區沒有重新整理,程式員将浪費大量的時間跟蹤調試并沒有執行的代碼。基于這個原因,輸出時應多使用 endl 而非 '\n'。使用endl 則不必擔心程式崩潰時輸出是否懸而未決(即還留在緩沖區,未輸出到裝置中)。
将輸入和輸出綁在一起
當輸入流與輸出流綁在一起時,任何讀輸入流的嘗試都将首先重新整理其輸出流關聯的緩沖區。标準庫将 cout 與 cin 綁在一起,是以語句:
導緻 cout 關聯的緩沖區被重新整理。
互動式系統通常應確定它們的輸入和輸出流是綁在一起的。這樣做意味着可以保證任何輸出,包括給使用者的提示,都在試圖讀之前輸出。
tie 函數可用 istream 或 ostream 對象調用,使用一個指向 ostream 對象的指針形參。調用 tie 函數時,将實參流綁在調用該函數的對象上。如果一個流調用 tie 函數将其本身綁在傳遞給 tie 的 ostream 實參對象上,則該流上的任何 IO 操作都會重新整理實參所關聯的緩沖區。
一個 ostream 對象每次隻能與一個 istream 對象綁在一起。如果在調用tie 函數時傳遞實參 0,則打破該流上已存在的捆綁。