文章目錄
- IO庫類型和頭文件
- IO對象無拷貝或賦值
- IO流的條件狀態
- 文件輸入輸出
- ifstream 示例
- ofstream 示例
- 文件模式
- 以out模式打開文件會丟棄已有數據
- 每次調用open時都會確定文件模式
- ofstream 保留源文件 追加數據 示例
- string流
- istringstream示例
- ostringstream示例
IO庫類型和頭文件
為了支持不同種類的IO處理操作,標準庫定義了一些IO類型。
iostream定義了用于讀寫流的基本類型。fstream定義了讀寫命名文件的類型。sstream定義了讀寫內存string對象的類型。
類型ifstream和istringstream都繼承自istream,因此,我們可以像使用istream對象一樣來使用ifstream和istringstream。
IO對象無拷貝或賦值
由于不能拷貝IO對象,因此我們也不能將形參或返回類型設置為流類型。進行IO操作的函數通常以引用方式傳遞和返回流。讀寫一個IO對象會改變其狀態,因此傳遞和返回的引用不能是const的。
IO流的條件狀態
一個流一旦發生錯誤,其上后續的IO操作都會失敗。只有當一個流處于無錯狀態時,我們才可以從它讀取數據,向它寫入數據。由于流可能處于錯誤狀態,因此代碼通常應該在使用一個流之前檢查它是否處于良好狀態。確定一個流對象的狀態的最簡單的方法是將它當做一個條件使用。
badbit表示系統級錯誤,如不可恢復的讀寫錯誤。通常情況下,一旦badbit被置位,流就無法再使用了。在發生可恢復錯誤后,failbit被置位,如期望讀取數值卻讀出一個字符等錯誤。這種問題通常是可以修正的,流還可以繼續使用。如果到達文件結束位置,eofbit和failbit都會被置位。goodbit的值為0,表示流未發生錯誤。如果badbit、failbit和eofbit任一個被置位,則檢測流狀態的條件會失敗。
文件輸入輸出
頭文件fstream定義了三個類型來支持文件IO:ifstream從一個給定文件讀取數據,ofstream向一個給定文件寫入數據,以及fstream可以讀寫給定文件。
創建文件流對象時,我們可以提供文件名(可選的)。如果提供了一個文件名,則open成員函數會自動被調用,示例如下:
ifstream in(ifile); // 構造一個ifstream并打開給定文件ifile,在新c++標準中,文件名ifile既可以是庫類型string對象,也可以是C風格字符數組
ofstream out; // 輸出文件流未關聯到任何文件
在要求使用基類型對象的地方,我們可以用繼承類型的對象來替代。這意味著,接受一個iostream類型引用(或指針)參數的函數,可以用一個對應的fstream(或sstream)類型來調用。也就是說,如果有一個函數接受一個ostream&參數,我們在調用這個函數時,可以傳遞給它一個ofstream對象,對istream&和ifstream也是類似的。
流如果調用open失敗,failbit會被置位。對一個已經打開的文件流調用open會失敗,并會導致failbit被置位。隨后的試圖使用文件流的操作都會失敗。為了將文件流關聯到另外一個文件,必須首先關閉已經關聯的文件。一旦文件成功關閉,我們就可以打開新的文件關聯新的文件。
當一個fstream對象被銷毀時,close會自動被調用。
ifstream 示例
打開string文件,按行存儲元素,str即是每一行的string
ifstream in("text.txt");
string str;
getline(in,str);
將每一個單詞作為一個獨立的元素進行存儲
ifstream in("text.txt");
string str;
in>>str;
ofstream 示例
ofstream ofs("test.txt");
ofs << "hello"<<" world"<<endl;
文件模式
每個流都有一個關聯的文件模式,用來指出如何使用文件。
以out模式打開文件會丟棄已有數據
默認情況下,我們打開一個ofstream時,文件的內容會被丟棄。阻止一個ofstream清空給定文件內容的方法是同時指定app模式。
保留被ofstream打開的文件中已有數據的唯一方法是顯式指定app或in模式。
每次調用open時都會確定文件模式
通常情況下,out模式意味著同時使用trunc模式,即當前文件內容將被清空。當指定app模式時,文件中的已有數據得以保留,所有寫操作都在文件末尾進行。
ofstream 保留源文件 追加數據 示例
ofstream ofs("test.txt",ofstream::app);
ofs << "hello"<<" world"<<endl;
string流
sstream頭文件定義了三個類型來支持內存IO,這些類型可以向string寫入數據,從string讀取數據,就像string是一個IO流一樣。
istringstream從string讀取數據,ostringstream向string寫入數據,而頭文件stringstream既可以從string讀取數據也可以向string寫入數據。
istringstream示例
以整行為元素讀取文件,存入vector中,并用istringstream從vector中讀取元素,每次讀取一個單詞
ifstream ifs("test.txt");string str;vector<string>vec;while (getline(ifs,str)) {vec.push_back(str);}for (auto a:vec) {istringstream vecStr(a);string tmp;while(vecStr >> tmp)cout << tmp<<endl;}
ostringstream示例
ostringstream os;
os << "hello" << " world" << endl;
cout << os.str();
此時界面上會顯示hello world