C++標準IO庫梳理參考

一、io庫的基本工具

• istream(輸入流)類型,提供輸入操作。
• ostream(輸出流)類型,提供輸出操作。
• cin:讀入標準輸入的 istream 對象。
• cout:寫到標準輸出的 ostream 對象。
• cerr:輸出標準錯誤的 ostream 對象。cerr 常用於 程序錯誤信息。
• >> 操作符,用於從 istream 對象中讀入輸入。
• << 操作符,用於把輸出寫到 ostream 對象中。
• getline 函數,需要分別取 istream 類型和 string 類型的兩個引用形 參,其功能是從 istream 對象讀取一個單詞(空格分隔),然後寫入 string 對象中。

二、io庫的條件狀態控制

參照C++Primer中的函數表
這裏寫圖片描述
這裏寫圖片描述
上述反應了輸入輸出流的條件狀態

//例子1
if(cin)
   //符合語法,表示可以用cin
while(cin>>n)
   //合法用法,檢查了流的狀態,如果輸入成功條件爲true
   //當出現系統級故障,讀入無效數據或者遇到結束符eof時都會返回false

上面的例子1只能驗證輸入是否有效,而某些程序則需要更詳細地訪問或控制流的狀態,此時,除了知道流處於錯誤狀態外,還必須瞭解它遇到了哪種類型的錯誤。 這就用到了表中的類型和函數。
流的狀態由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof 中的任意一個爲 true,則該流處於錯誤狀態。如果這三個條件沒有一個爲 true,則 good 操作將返回 true。

#include<iostream>
#include<stdexcept>
using namespace std;
int main()
{
    int i;
    while (cin >> i, !cin.eof())//逗號操作符:首先計算它的每一個操作數,然後返回右邊操作數作爲整個操作的結果,cin.eof():如果到達終止符,返回true,這裏表示沒有到達終止符
    {
        if (cin.bad())
            throw runtime_error("IO stream Corrupted"); //系統出現故障,輸入流崩潰
        if (cin.fail()) //輸入類型不符合,可修正,所以continue
        {
            cerr << "bad data, try again" << endl;
            cin.clear();//重置cin但是不清除內容
            cin.sync();//清楚錯誤內容
            //cin.clear(istream::failbit); //此處爲C++primer的寫法,程序會陷入死循環,原因是cin.clear(istream::failbit);就是使failbit位設置爲1,而把eofbit和badbit位清除爲0。
            continue;
        }
        cout << i << endl; //輸入成功,可以正確使用i
    }
}

下面是函數返回和調用istream的例子

#include<iostream>
#include<stdexcept>
using namespace std;
istream& fun(istream &i)
{
    int k;
    while (i>>k,!i.eof())
    {
        if (i.bad())
        {
            throw runtime_error("Corrupted");
        }
        if (i.fail())
        {
            cerr << "unexpected data,try again" << endl;
            i.clear();
            i.sync();
            continue;
        }
        cout << k << endl;
    }
    i.clear();
    return i;
}
int main()
{
    int k;
    fun(cin);
    system("pause");
}

輸出緩衝區的刷新例子

cout << "zlk_flush" << flush; //直接刷新
cout << "zlk_ends" << ends; //空一格再刷新
cout << "zlk_endl" << endl; //空一行再刷新

三、iostream,fstream,sstream

1、iostream 爲讀寫控制窗口
2、fstream爲讀寫以命名文件
3、sstream爲讀寫存儲在內存的string對象
其類之間的派生關係爲:
這裏寫圖片描述

1、iostream:
istream類和ostream類以及iostream類不可自行創建對象,只能用iostream頭文件裏的全局變量cin 和cout 進行流輸入和流輸出。

2、fstream
文件流的使用例子:

#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main()
{   
    string s;
    string file_in_str;
    string file_out_str;
    file_in_str = "E:\\testin.txt";
    string next_file = "E:\\testin2.txt";
    file_out_str = "E:\\testout.txt";
    //ifstream filein(file_in_str.c_str);  //另外一種打開方式
    //ofstream fileout(file_out_str.c_str); 
    ifstream filein;
    ofstream fileout;
    filein.open(file_in_str); //調用open方法綁定文件,當要給filein綁定新文件前要調用close()函數
    fileout.open(file_out_str); 
    //filein.close();
    if (!filein) //當open操作失敗,filein爲0
    {
        cerr << "錯誤:打開文件失敗:" << file_in_str << endl;
    }
    vector<string> kk;
    while (getline(filein, s)) //讀輸入流的一個行
    //while (filein>>s) //讀輸入流的一個單詞(遇到空格停止)
    {
        kk.push_back(s);
    }
    for (vector<string>::iterator i = kk.begin(); i < kk.end(); i++)
    {
        cout << *i << endl;
    }
    filein.close();//關閉文件
    filein.clear();//刷新緩衝區

}

上例中filein.open()的文件打開還支持文件打開方式,放到第二個參數就好,下面是打開方式列表:
這裏寫圖片描述
這裏寫圖片描述
還有可用的組合方式:
這裏寫圖片描述

3、sstream
sstream的基本思路可以吧fstream中綁定的文件換成字符串,然後從字符串中讀取。
stringstream的基本使用:

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    string s1, s2;
    while (getline(cin, s1))
    {
        stringstream stri(s1); //給stingstream綁定一個string對象

        cout << stri.str() << endl; //stri.str()爲string流所有內容(一直到結束符)
        while (stri >> s2)          //從string流s1中讀單詞,讀到流末尾結束
        {
            cout << s2 << endl;
        }
    }
}

該類型流主要是爲了類型轉化,例如,有一個數值型數據集合,要獲取它們的 string 表 示形式,或反之。詳情請看下面例子:

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    int a = 10, b = 24;
    string s="99";
    ostringstream oss;  
    oss.str(s);  //綁定字符串s
    oss << a << b;  //輸入到字符串的時候不會從99的結尾接着輸出,而是直接修改原來的數據
    string res = oss.str();  //將int型的a和b輸入到字符串res中了
    cout << res << endl;//輸出爲1024
}

用istringstream從string中讀取int(float也可以)

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    string a = "1001 23";
    istringstream iss;
    iss.str(a);  //綁定字符串a
    cout << istr.str() << endl;
    int x, y, z;
    iss >> x >> y;
    z = x + y;
    cout << z << endl;  
}

ENDL;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章