C++基礎:C++風格的文件輸入輸出流

字號:

輸出主要由重載的左移操作符(<<)來完成,輸入主要由重載的右移操作符(>>)完成。
    >>a表示將數(shù)據(jù)放入a對象中。
    <  接下來我們繼續(xù)看一下C++風格的串流控制,C++引入了ostringstream、istringstream、stringstream這三個類,要使用他們創(chuàng)建對象就必須包含sstream.h頭文件。
    istringstream類用于執(zhí)行C++風格的串流的輸入操作。
    stringstream類同時可以支持C++風格的串流的輸入輸出操作。
    strstream類同時可以支持C風格的串流的輸入輸出操作。
    istringstream類是從istream(輸入流類)和stringstreambase(c++字符串流基類)派生而來,ostringstream是從ostream(輸出流類)和stringstreambase(c++字符串流基類)派生而來,stringstream則是從iostream(輸入輸出流類)和和stringstreambase(c++字符串流基類)派生而來。
    istringstream是由一個string對象構造而來,istringstream類從一個string對象讀取字符。
    istringstream的構造函數(shù)原形如下:istringstream::istringstream(string str);
    #include
    #include
    using namespace std;
    int main()
    {
    istringstream istr;
    istr.str("1 56.7");
    //上述兩個過程可以簡單寫成 istringstream istr("1 56.7");
    cout << istr.str()<    int a;
    float b;
    istr>>a;
    cout<  istr>>b;
    cout<    system("pause");
    }
    上例中,構造字符串流的時候,空格會成為字符串參數(shù)的內(nèi)部分界,例子中對a,b對象的輸入"賦值"操作證明了這一點,字符串的空格成為了整型數(shù)據(jù)與浮點型數(shù)據(jù)的分解點,利用分界獲取的方法我們事實上完成了字符串到整型對象與浮點型對象的拆分轉換過程。
    str()成員函數(shù)的使用可以讓istringstream對象返回一個string字符串(例如本例中的輸出操作(cout<    ostringstream同樣是由一個string對象構造而來,ostringstream類向一個string插入字符。
    ostringstream的構造函數(shù)原形如下:
    ostringstream::ostringstream(string str);
    示例代碼如下:#include
    #include
    #include
    using namespace std;
    int main()
    {
    ostringstream ostr;
    //ostr.str("abc");//如果構造的時候設置了字符串參數(shù),那么增長操作的時候不會從結尾開始增加,而是修改原有數(shù)據(jù),超出的部分增長
    ostr.put(’d’);
    ostr.put(’e’); 
    ostr<<"fg";
    string gstr = ostr.str();
    cout<    system("pause");
    }
    在上例代碼中,我們通過put()或者左移操作符可以不斷向ostr插入單個字符或者是字符串,通過str()函數(shù)返回增長過后的完整字符串數(shù)據(jù),但值得注意的一點是,當構造的時候對象內(nèi)已經(jīng)存在字符串數(shù)據(jù)的時候,那么增長操作的時候不會從結尾開始增加,而是修改原有數(shù)據(jù),超出的部分增長。
    對于stringstream了來說,不用我多說,大家也已經(jīng)知道它是用于C++風格的字符串的輸入輸出的。
    stringstream的構造函數(shù)原形如下:
    stringstream::stringstream(string str);
    示例代碼如下:#include
    #include
    #include
    using namespace std;
    int main()
    {
    stringstream ostr("ccc");
    ostr.put(’d’);
    ostr.put(’e’);
    ostr<<"fg";
    string gstr = ostr.str();
    cout<    char a;
    ostr>>a;
    cout<  system("pause");
    }除此而外,stringstream類的對象我們還常用它進行string與各種內(nèi)置類型數(shù)據(jù)之間的轉換。
    示例代碼如下:#include
    #include
    #include
    using namespace std;
    int main()
    {
    stringstream sstr;
    //--------int轉string-----------
    int a=100;
    string str;
    sstr<  sstr>>str; 
    cout<    //--------string轉char[]-------- 
    sstr.clear();//如果你想通過使用同一stringstream對象實現(xiàn)多種類型的轉換,請注意在每一次轉換之后都必須調(diào)用clear()
    成員函數(shù)。
    string name = "colinguan";
    char cname[200]; 
    sstr<    sstr>>cname;
    cout<    system("pause");
    }
    接下來我們來學習一下輸入/輸出的狀態(tài)標志的相關知識,C++中負責的輸入/輸出的系統(tǒng)包括了關于每一個輸入/輸出操作的結果的記錄信息。這些當前的狀態(tài)信息被包含在io_state類型的對象中。io_state是一個枚舉類型(就像open_mode一樣),以下便是它包含的值。
    goodbit 無錯誤
    Eofbit 已到達文件尾
    failbit 非致命的輸入/輸出錯誤,可挽回
    badbit 致命的輸入/輸出錯誤,無法挽回
    有兩種方法可以獲得輸入/輸出的狀態(tài)信息。一種方法是通過調(diào)用rdstate()函數(shù),它將返回當前狀態(tài)的錯誤標記。例如,假如沒有任何錯誤,則rdstate()會返回goodbit.
    下例示例,表示出了rdstate()的用法:
    #include
    using namespace std;
    int main()
    {
    int a;
    cin>>a;
    cout<    if(cin.rdstate() == ios::goodbit)
    {
    cout<<"輸入數(shù)據(jù)的類型正確,無錯誤!"<    }
    if(cin.rdstate() == ios_base::failbit)
    {
    cout<<"輸入數(shù)據(jù)類型錯誤,非致命錯誤,可清除輸入緩沖區(qū)挽回!"<    }
    system("pause");
    }
    另一種方法則是使用下面任何一個函數(shù)來檢測相應的輸入/輸出狀態(tài):
    bool bad();
    bool eof();
    bool fail();
    bool good();
    下例示例,表示出了上面各成員函數(shù)的用法:#include
    using namespace std;
    int main()
    {
    int a;
    cin>>a;
    cout<    if(cin.good())
    {
    cout<<"輸入數(shù)據(jù)的類型正確,無錯誤!"<    }
    if(cin.fail())
    {
    cout<<"輸入數(shù)據(jù)類型錯誤,非致命錯誤,可清除輸入緩沖區(qū)挽回!"<    }
    system("pause");
    }如果錯誤發(fā)生,那么流狀態(tài)既被標記為錯誤,你必須清除這些錯誤狀態(tài),以使你的程序能正確適當?shù)乩^續(xù)運行。要清除錯誤狀態(tài),需使用clear()函數(shù)。此函數(shù)帶一個參數(shù),它是你將要設為當前狀態(tài)的標志值。,只要將ios::goodbit作為實參。
    示例代碼如下:#include
    using namespace std;
    int main()
    {
    int a;
    cin>>a;
    cout<    cin.clear(ios::goodbit);
    cout<    system("pause");
    }
    通常當我們發(fā)現(xiàn)輸入有錯又需要改正的時候,使用clear()更改標記為正確后,同時也需要使用get()成員函數(shù)清除輸入緩沖區(qū),以達到重復輸入的目的。
    示例代碼如下:#include
    using namespace std;
    int main()
    {
    int a;
    while(1) //也可以寫成for(;1;)
    {
    cin>>a;
    if(!cin)//條件可改寫為cin.fail()
    {
    cout<<"輸入有錯!請重新輸入"<    cin.clear();
    cin.get();
    }
    else
    {
    cout<  break; 
    }
    }
    system("pause");
    }
    最后再給出一個對文件流錯誤標記處理的例子,鞏固學習,代碼如下:#include
    #include
    using namespace std;
    int main()
    {
    ifstream myfile("c:1.txt",ios_base::in,0);
    if(myfile.fail())
    {
    cout<<"文件讀取失敗或指定文件不存在!"<    }
    else
    {
    char ch;
    while(myfile.get(ch))
    {
    cout<    }
    if(myfile.eof())
    {
    cout<<"文件內(nèi)容已經(jīng)全部讀完"<    }
    while(myfile.get(ch))
    {
    cout<    }
    }
    system("pause");
    }