目錄結構:
1.IO類
除了istream和ostream之外,標准庫還定義了其它的一些類型。如下表:
頭文件 | 類型 |
iostream | istream,wistream 從流讀取數據 ostream,wostream 向流寫入數據 iostream,wiostream 讀寫流 |
fstream | ifstream,wifstream 從文件讀取數據 ofstream,wofstream 向文件寫入數據 fstream,wfstream 讀寫文件 |
sstream | istringstream,wistringstream 從string讀取數據 ostringstream,wostringstream 向string寫入數據 stringstream,wstringstream 讀寫string |
為了支持寬字符的語言,標准庫還定義了一組類型和對象來操作wchar_t類型的數據。寬字符版本和函數的名字以一個w開始。例如,wcin,wcout和cerr,分別對應cin,cout,cerr的寬字符版本。
下面這種圖片更詳細的列舉了,c++中流的基本體系:
1.1 IO對象無拷貝狀態
不能拷貝和對IO對象賦值:
fstream out1,out2; out1 = out2; //錯誤,不能對流對象賦值 ofstream print(ofstream); //錯誤,不能初始化ofstream參數 out2 = print(out2); //錯誤,不能拷貝流對象
由於不能拷貝IO對象,因此我們也不能將形參或返回類型設置為流類型。進行IO操作的函數通常以引用的方式傳遞和返回流。
1.2 條件狀態
C++類提供了一些列的函數和標志,可以幫助我們訪問和操縱流的條件狀態,下表列舉了一些函數和標志:
strm::iostate | strm流的iostate類靜態成員,提供了表達式狀態的完整功能 |
strm::badbit | strm流的badbit類靜態成員,指出流已經崩潰 |
strm::failbit | strm流的failbit類靜態成員,指出流操作失敗了 |
strm::eofbit | strm流的eofbit類靜態成員,指出流達到了文件末尾 |
strm::goodbit | strm流的goodbit類靜態成員,指出流處於正常狀態,未發生任何錯誤 |
s.eof() | 若流s的eofbit置位,則返回true |
s.fail() | 若流s的failbit或badbit置位,則返回true |
s.bad() | 若流s的badbit置位,則返回true |
s.good() | 若流s處於有效狀態,則返回true |
s.clear() | 將流s中的所有條件狀態位復位,將流的狀態設置為有效。 |
s.clear(flags) | 根據給定的flags標志位,將流s中對應的條件狀態位復位。flags的類型是strm::flags |
s.setstate(flags) | 根據給定的flags標志位,將流s中的對應條件狀態位置位。flags的類型是strm::flags |
s.rdstate() | 返回流s的當前條件狀態,返回值類型為strm::iostate。 |
我們可以使用如下的代碼判斷流的狀態:
std::ifstream strm; if(strm.good()){ //繼續操作 }
由於流重載了布爾運算符,
explicit operator bool() const;
如果failbit和badbit被置位,則返回false。否則返回true。
有了布爾運算符,我們就可以輕松的判斷流的狀態。
std::ifstream is; is.open ("test.txt"); if (is) { //編譯器會編譯為if(is.good()) // 操作文件 } else { std::cerr << "Error opening 'test.txt'\n"; }
2.文件流
頭文件fstream定義了三個類型來支持文件IO,ifstream從一個給定的文件讀取數據,ofstream從一個向一個給定的文件寫入數據,以及fstream可以讀寫文件。
讀寫文件的步驟:
1.創建文件流對象
2.打開文件
3.讀寫數據
4.關閉文件
例如:
#include <fstream> // std::fstream int main () { std::fstream fs;//創建對象 fs.open ("test.txt");//打開文件 fs << " more lorem ipsum";//寫入數據 fs.close();//關閉文件 return 0; }
2.1 文件模式
每個流都有一個關聯的模式,用來指出如何使用文件。例如:
in | 以讀的方式打開 |
out | 以寫的方式打開 |
app | 每次寫操作前均定位到文件末尾 |
ate | 打開文件立即定位到文件末尾 |
trunc | 截斷文件 |
binary | 以二進制方式進行 |
當打開一個文件的時候,可以指定一個文件模式,指定模式有如下限制:
1.只可以對ofstream或fstream對象設定out模式
2.只可以對ifstream或fstream對象設定in模式
3.只有當out模式被設定時才可以設定trunc模式
4.只要trunc沒有被設定,就可以設定app模式。在app模式下,即使沒有顯式指定out模式,文件也總是以輸出方式打開。
5.默認情況下,即使我們沒有指定trunc模式,以out模式打開的文件也會被截斷。為了保留以out模式打開的文件的內容,我們必須同時指定app模式,這樣只會將數據追加到文件末尾;或者同時指定in模式,即打開文件同時進行讀寫操作
6.ate和binary模式可以用於任何類型的文件流對象,且可以與其他任何文件模式組合使用。
每個文件流都有一個默認的文件模式,ifstream關聯的文件默認以in模式打開,ofstream關聯的文件默認以out模式打開,fstream關聯的文件默認以in和out模式打開。
例如:
ofstream out; // 未指定文件打開模式 out.open("test.txt"); // 模式隱含設置為輸出和截斷 out.close(); // 關閉out out.open("test2.txt",ofstream::app); //模式為輸出和追加 out.close(); //關閉out
3.string流
sstring頭文件定義了三個類型來支持內存IO操作,這些類型可以向string寫入數據,從string讀取數據,就像string是一個IO流一樣。
istringstream從string讀取數據,ostringstream向string寫入數據,stringstream既可以向string寫入數據也可以向string讀取數據。
下面是關於stringstream的常規操作:
sstream strm | 是一個未綁定的stringstream對象 |
sstream strm(s) | strm是一個stringstream對象,保存了string s的拷貝。 |
strm.str() | 返回strm所保存的string的拷貝 |
strm.str(s) | 將string s拷貝到stream中 |
例如:
#include <string> // std::string #include <iostream> // std::cout #include <sstream> // std::stringstream, std::stringbuf int main () { std::stringstream ss; //創建stringstream對象 ss.str ("Example string"); //將字符串拷貝到stringstream中 std::string s = ss.str(); //獲得stringstream中保存的字符串 std::cout << s << '\n'; //輸出 std::string word; while(ss >> word)//從stringstream中讀取每一個單詞 std::cout << word << '\n'; std::cout << std::endl; return 0; }