C++ 學習筆記之(8)-IO 庫
IO
庫定義了讀寫內置類型值的操作。此外,一些類,如string
,會自定義類似IO
操作,讀寫本身對象
IO
類
爲了支持不同種類的IO
處理操作,比如讀寫寬字符,string
類,文件等,在istream
和ostream
之外,標準庫還定義了其他一些IO
類型
- 以
w
開頭的類型用來處理wchar_t
類型數據,即寬字符語言
IO
對象無拷貝或賦值
進行
IO
操作的函數通常以引用方式傳遞和返回流讀寫
IO
對象會改變其狀態,故傳遞和返回的引用不能是const
的ofstream out1, out2; out1 = out2; // 錯誤:不能對流對象賦值 ofstream print(ofstream); // 錯誤:不能初始化 ofstream 參數 out2 = print(out2); // 錯誤:不能拷貝流對象
條件狀態
IO
類定義了一些函數和標誌,用來訪問和操縱流的條件狀態
查詢流的狀態
badbit
表示系統級錯誤,比如不可恢復的讀寫錯誤。一旦badbit
被置位,流就無法再使用failbit
:表示可恢復錯誤,比如期望讀取數值卻讀出字符等,可修正,流可以繼續使用eofbit
和failbit
:表示達到文件結束爲止,兩個都會被置位goodbit
值爲0
,表示流未發生錯誤
管理輸出緩衝
- 每個輸出流都管理一個緩衝區,用來保存程序讀寫的數據
- 導致緩衝刷新(即,數據真正寫到輸出設備或文件)的原因有很多:
- 程序正常結束,作爲
main
函數的return
操作的一部分,緩衝刷新被執行 - 緩衝區滿時,需要刷新緩衝,而後新的數據才能繼續寫入緩衝區
- 使用
endl
、flush
和ends
操縱符顯示刷新緩衝區 - 使用操縱符
unitbuf
設置流的內部狀態,清空緩衝區。默認情況下,cerr
是設置unitbuf
的,故寫到cerr
的內容都是立即刷新的 - 一個輸出流可能被關聯到另一個流,當讀寫被關聯的流時,關聯到的流的緩衝區會被刷新。默認
cin
和cerr
都關聯到cout
,故讀cin
或寫cerr
都會導致cout
的緩衝區被刷新
- 程序正常結束,作爲
- 關聯流使用
tie
函數 - 每個流同時最多關聯到一個流,但多個流可以同時關聯到同一個
ostream
cout << "hi!" << endl; // 輸出 hi 和一個換行,然後刷新緩衝區
cout << "hi!" << flush; // 輸出 hi,然後刷新緩衝區,不附加任何額外字符
cout << "hi!" << ends; // 輸出 hi 和一個空字符,然後刷新緩衝區
cout << unitbuf; // 開啓後,所有輸出操作後都會立即刷新緩衝區,無緩衝
cout << nounitbuf; // 回到正常的緩衝方式
文件輸入輸出
頭文件fstream
定義了三個類型來支持IO
,除了繼承自iostream
類型的行爲以外,fstream
還增加了一些新的成員管理與流關聯的文件
使用文件流對象
使用該文件流對象,將對象與文件關聯,進行文件讀寫操作
open
函數能將空文件流對象與文件關聯起來,若調用open
失敗,則failbit
會被置位。若想讓文件流關聯到另外的文件,則必須首先關閉已經關聯的文件,使用close
函數- 當一個
fstream
對象被被銷燬時,close
會自動被調用
文件模式
每個流都有一個關聯的 文件模式, 用來指出如何使用文件
- 只可以對
ofstream
或fstream
對象設定out
模式, 且ofstream
關聯文件默認以out
模式打開,fstream
文件默認以in
和out
模式打開 - 只可以對
ifstream
或fstream
對象設定in
模式, 且ifstream
關聯文件默認以in
模式打開 - 只有當
out
也被設定時纔可以設定trunc
模式 - 只要
trunc
沒被設定,就可以設定app
模式。在app
模式下,即使沒有顯示指定out
模式,文件頁以輸出方式打開 - 默認情況下,以
out
模式打開的文件也會被截斷。要保留文件內容,可以同時指定app
模式或in
模式 ate
和binary
模式可用於任何類型的文件流對象,且可以和其他模式組合使用
文件打開時,都要設置文件模式,可顯示設置,也可隱式設置。當未指定模式時,會使用默認值
string
流
sstream
頭文件,定義了三個類型來支持內存IO
, 這些類型可以向string
讀寫數據
結語
C++ 使用標準庫類來處理面向流的輸入和輸出
iostream
處理控制檯IO
fstream
處理命名文件IO
sstringstream
完成內存string
的IO
- 類
fstream
和stringstream
都是繼承自類iostream
的,輸入類都繼承自istream
, 輸出類都繼承自ostream
.