1. 程式人生 > >C++ Primer 第8章 IO庫

C++ Primer 第8章 IO庫

隱式 關閉 strings 很多 當前 文件 兩個 讀寫 模式

C++語言不能直接處理輸入輸出,而是通過一族定義在標準庫中的類型處理IO。這些類型支持設備的IO操作,設備可以是控制臺、文件等。IO類可以處理char數據和寬字符類型,也可以處理string類型。

IO庫主要基於istream和ostream兩個類型進行擴充。istream表示輸入流,用於處理向程序的輸入數據,ostream表示輸出流,用於處理從程序中輸出數據。繼承自istream和ostream的其他IO類的操作方式與istream和ostream的操作方式相同。

IO對象無拷貝與賦值,因此不能拷貝IO對象,也不能對IO對象賦值,不能將形參和返回類型設置為IO對象,函數只能以引用的方式傳遞或返回IO對象,但引用類型不能是const類型。

IO對象可能會發生錯誤,有寫錯誤是可恢復的,有些則發生在系統深處,不可恢復。如int ival; cin>>ival;如果在標準輸入上鍵入Bob,讀操作就會失敗,cin會進入錯誤的狀態,通過檢測流對象的一些標誌或函數可以判斷流的狀態,並可能從錯誤中恢復。只有當流處於非錯誤狀態時才能進行操作,把流當做一個條件來使用可以簡單的實現流狀態檢測,如:while(cin>>word){};

通過iostate值可以確定流的狀態,這些值表示特定的位模式,可以與位運算符一起使用。對每個位的檢測都提供了特定的函數,如good(),fail()等,通過good和fail函數可以確定流的狀態。

clear可以用來重置標誌位,帶參數的clear接受一個表示新狀態的iostate值,不帶參數的clear清除所有錯誤標誌位。rdstate返回流的當前狀態,setstate將給定調鍵位置位,表示發生了錯誤。

每個輸出流都管理一個緩沖區,緩沖區的存在可以提升性能,有了緩沖區,操作系統可以把程序的多個輸出組合成單一的設備寫操作。導致緩沖刷新的原因有很多,緩沖刷新後才會真正把數據寫入到輸出設備。程序正常結束時,緩沖區刷新;緩沖區滿時,緩沖區將被刷新;使用操縱符endl可以顯示刷新緩沖區;使用unitbuf操縱符可使流每次都刷新緩沖區;當讀寫被關聯的流時,關聯到的流的緩沖區會被刷新。使用flush和ends操縱符可以刷新緩沖區。cout<<unitbuf設置流每次寫入數據後都立即刷新緩沖區,cout<<nounitbuf設置流恢復正常的緩沖策略。

註意,如果程序崩潰,輸出緩沖區不會刷新,因此在調試程序時要確保可能崩潰前的緩沖區都被刷新。

當一個輸入流被關聯到一個輸出流時,任何從輸入流讀取數據的操作都會刷新關聯的輸出流,默認情況下標準庫的cin關聯到cout。

可以將一個istream關聯到一個ostream,也可以將一個ostream關聯到另一個ostream。標準庫的cin對象默認關聯到cout對象,可以通過tie函數返回關聯的輸出流的指針,或通過tie帶參數的重載版本設置要關聯到的輸出流。

頭文件fstream中定義了三個類型用來支持文件IO,ifstream表示輸入流,用來讀取文件,ofstream表示輸出流,用來寫入文件,fstream可以讀寫給定文件。這些對象提供的操作與cin、cout對象一樣,同時還提供與文件管理的其他操作,包括open、close、帶mode參數的構造函數等。在創建文件流對象時,可以通過提供文件名來使流對象與特定的文件關聯。

可以向基類類型的引用或指針的參數傳遞派生類,因此可以使用ifstream對象傳遞給istream&類型的參數。一旦一個文件流已經打開,它會保持與對應文件的關聯,如果對已經打開的文件流調用open會失敗。若想使文件流關聯到另一個文件,需要首先關閉當前文件在打開另一個文件。

當一個fstream對象被銷毀時,close會自動被調用。

每個流都有一個關聯的文件模式,ofstream只能以out模式打開,ifstream只能以in模式打開,fstream可以以in模式打開也可以以out模式打開。與fstream關聯的文件默認以in和out模式打開。

以out模式打開文件會丟棄原有數據,為了保留原有數據,在構造對象時必須顯示指定app模式。對於一個文件流,每次打開文件時都可以改變文件模式。

註意,每次打開文件時都會設置文件模式,可能是顯示的設置,也可能是隱式的設置,當未指定任何模式時,將使用默認值。

sstream頭文件定義三個類型用來定義內存IO,istringstream用來從string讀取數據,ostringstream用來向string寫入數據。str()函數用來返回保存到流中的string對象,帶參數的str對象把參數表示的string拷貝到流中。

可以通過istringstream對象處理字符串,讀取字符串時可以通過>>運算符實現,如record>>info.name。通過ostringstream構造字符串,像使用流對象一樣向字符串流中輸入數據,最後通過str函數獲取構造的字符串。

每個io對象都維護一組狀態,當對象的狀態變為無效時,後續的所有操作都會失敗,知道流的錯誤被糾正,標準庫提供一組函數,用來檢驗和設置這些標誌。

C++ Primer 第8章 IO庫