• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            【C++常識】C++的iostream標準庫介紹

            為什么需要iostream 我們從一開始就一直在利用C++的輸入輸出在做著各種練習,輸入輸出是由iostream庫提供的,所以討論此標準庫是有必要的,它與C語言的 stdio庫不同,它從一開始就是用多重繼承與虛擬繼承實現的面向對象的層次結構,作為一個c++的標準庫組件提供給程序員使用。

              iostream為內置類型類型對象提供了輸入輸出支持,同時也支持文件的輸入輸出,類的設計者可以通過對iostream庫 的擴展,來支持自定義類型的輸入輸出操作。

              為什么說要擴展才能提供支持呢?我們來一個示例。 %CODE{"cpp"}% #include <stdio.h> #include using namespace std;

            class Test { public: Test(int a=0,int b=0) { Test::a=a; Test::b=b; } int a; int b; }; int main() { Test t(100,50); printf("%???",t);//不明確的輸出格式 scanf("%???",t);//不明確的輸入格式 cout<<t<<endl;//同樣不夠明確 cin>>t;//同樣不夠明確 system("pause"); } %ENDCODE% 由于自定義類的特殊性,在上面的代碼中,無論你使用c風格的輸入輸出,或者是c++的輸入輸出都不是不明確的一個表示,由于c語言沒有運算符重載機 制,導致stdio庫的不可擴充性,讓我們無法讓printf()和scanf()支持對自定義類對象的擴充識別,而c++是可以通過運算符重載機制擴充 iostream庫的,使系統能能夠識別自定義類型,從而讓輸入輸出明確的知道他們該干什么,格式是什么。

              在上例中我們之所以用printf與cout進行對比目的是為了告訴大家,C與C++處理輸入輸出的根本不同,我們從c遠的輸 入輸出可以很明顯看出是函數調用方式,而c++的則是對象模式,cout和cin是ostream類和istream類的對象。

            1 iostream: istream 和 ostream

              C++中的iostream庫主要包含下圖所示的幾個頭文件:
            IOSstream 庫
            fstream iomainip
            ios iosfwd
            iostream istream
            ostream sstream
            streambuf strstream

              我們所熟悉的輸入輸出操作分別是由istream(輸入流)和ostream(輸出流)這兩個類提供的,為了允許雙向的輸入/ 輸出,由istream和ostream派生出了iostream類。

              類的繼承關系見下圖:

            iostream庫定義了以下三個標準流對象:

            1. cin,表示標準輸入(standard input)的istream類對象。cin使我們可以從設備讀如數據。
            2. cout,表示標準輸出(standard output)的ostream類對象。cout使我們可以向設備輸出或者寫數據。
            3. cerr,表示標準錯誤(standard error)的osttream類對象。cerr是導出程序錯誤消息的地方,它只能允許向屏幕設備寫數據。

              輸出主要由重載的左移操作符(<<)來完成,輸入主要由重載的右移操作符(>>)完成:

            1. >>a表示將數據放入a對象中。
            2. <<a表示將a對象中存儲的數據拿出。

              這些標準的流對象都有默認的所對應的設備,見下表:
            C++對象名 設備名稱 C中標準設備名 默認含義
            cin 鍵盤 stdin 標準輸入
            cout 顯示器屏幕 stdout 標準輸出
            cerr 顯示器屏幕 stderr 標準錯誤輸出
              上表中的意思表明cin對象的默認輸入設備是鍵盤,cout對象的默認輸出設備是顯示器屏幕。

              那么原理上C++有是如何利用cin/cout對象與左移和右移運算符重載來實現輸入輸出的呢?

              下面我們以輸出為例,說明其實現原理:

            1. cout是ostream類的對象,因為它所指向的是標準設備(顯示器屏幕),所以它在iostream頭文件中作為全 局對象進行定義。
            2. ostream cout(stdout);//其默認指向的C中的標準設備名,作為其構造函數的參數使用。
            3. 在iostream.h頭文件中,ostream類對應每個基本數據類型都有其友元函數對左移操作符進行了友 元函數的重載。
              • ostream& operator<<(ostream &temp,int source);
              • ostream& operator<<(ostream &temp,char *ps);
              • ... 等等

              一句輸出語句:cout<<"www.cndev-lab.com";,事實上調用的就是 ostream& operator<<(ostream &temp,char *ps);這個運算符重載函數,由于返回的是流對象的引用,引用可以作為左值使用,所以當程序中有類似cout<<"www.cndev- lab.com"<<"中國軟件開發實驗室";這樣的語句出現的時候,就能夠構成連續輸出。

              由于iostream庫不光支持對象的輸入輸出,同時也支持文件流的輸入輸出,所以在詳細講解左移與右移運算符重載只前,我們 有必要先對文件的輸入輸出以及輸入輸出的控制符有所了解。

            2 fstream: ifstream 和 ofstream

              和文件有關系的輸入輸出類主要在fstream.h這個頭文件中被定義,在這個頭文件中主要被定義了三個類,由這三個類控制對文件的 各種輸入輸出操作,他們分別是ifstream、ofstream、fstream,其中fstream類是由iostream類派生而來,他們之間的繼 承關系見下圖所示。

            由于文件設備并不像顯示器屏幕與鍵盤那樣是標準默認設備,所以它在fstream.h頭文件中是沒有像cout那樣預先定義的全局 對象,所以我們必須自己定義一個該類的對象,我們要以文件作為設備向文件輸出信息(也就是向文件寫數據),那么就應該使用ofstream類。

              ofstream類的默認構造函數原形為: %CODE{"cpp"}% ofstream::ofstream(const char *filename,int mode = ios::out,int openprot = filebuf::openprot); %ENDCODE%

            • filename:  要打開的文件名
            • mode:    要打開文件的方式
            • prot:    打開文件的屬性

              其中mode和openprot這兩個參數的可選項表見下表:
            mode 屬性表
            ios::app 以追加的方式打開文件
            ios::ate 文件打開后定位到文件尾,ios:app就包含有此屬性
            ios::binary 以二進制方式打開文件,缺省的方式是文本方式。兩種方式的區別見前文
            ios::in 文件以輸入方式打開
            ios::out 文件以輸出方式打開
            ios::trunc 如果文件存在,把文件長度設為0
              可以用“或”把以上屬性連接起來,如ios::out|ios::binary。
            openprot 屬性表
            屬性 含義
            0 普通文件,打開訪問
            1 只讀文件
            2 隱含文件
            4 系統文件
              可以用“或”或者“+”把以上屬性連接起來 ,如3或1|2就是以只讀和隱含屬性打開文件。

            實例代碼如下: %CODE{"cpp"}% #include using namespace std;

            int main() { ofstream myfile("c:\\1.txt",ios::out|ios::trunc,0); myfile<<"中國軟件開發實驗室"<<endl<<"網址:"<<"www.cndev- lab.com"; myfile.close() system("pause"); } %ENDCODE% 文件使用完后可以使用close成員函數關閉文件。

              ios::app為追加模式,在使用追加模式的時候同時進行文件狀態的判斷是一個比較好的習慣。

              示例如下:

            %CODE{"cpp"}% #include #include using namespace std; int main() { ofstream myfile("c:\\1.txt",ios::app,0); if(myfile)//或者寫成myfile.fail() { cout<<"文件打開失敗,目標文件狀態可能為只讀!"; system("pause"); exit(1); } myfile<<"中國軟件開發實驗室"<<endl<<"網址:"<<"www.cndev- lab.com"<<endl; myfile.close(); } %ENDCODE%

              在定義ifstream和ofstream類對象的時候,我們也可以不指定文件。以后可以通過成員函數open()顯式的把一 個文件連接到一個類對象上。

              例如:

            %CODE{"cpp"}% #include #include using namespace std; int main() { ofstream myfile; myfile.open("c:\\1.txt",ios::out|ios::app,0); if(myfile)//或者寫成myfile.fail() { cout<<"文件創建失敗,磁盤不可寫或者文件為只讀!"; system("pause"); exit(1); } myfile<<"中國軟件開發實驗室"<<endl<<"網址:"<<"www.cndev- lab.com"<<endl; myfile.close(); } %ENDCODE% 下面我們來看一下是如何利用ifstream類對象,將文件中的數據讀取出來,然后再輸出到標準設備中的例子。

              代碼如下: %CODE{"cpp"}% #include #include #include using namespace std; int main() { ifstream myfile; myfile.open("c:\\1.txt",ios::in,0); if(myfile) { cout<<"文件讀錯誤"; system("pause"); exit(1); } char ch; string content; while(myfile.get(ch)) { content+=ch; cout.put(ch);//cout<<ch;這么寫也是可以的 } myfile.close(); cout<<content; system("pause"); } %ENDCODE% 上例中,我們利用成員函數get(),逐一的讀取文件中的有效字符,再利用put()成員函數,將文件中的數據通過循環逐一輸出到標準設備(屏幕) 上, get()成員函數會在文件讀到默尾的時候返回假值,所以我們可以利用它的這個特性作為while循環的終止條件,我們同時也在上例中引入了C++風格的 字符串類型string,在循環讀取的時候逐一保存到content中,要使用string類型,必須包含string.h的頭文件。

             

            我們在簡單介紹過ofstream類和ifstream類后,我們再來看一下fstream類,fstream類是由 iostream派生而來,fstream類對象可以同對文件進行讀寫操作。

              示例代碼如下: %CODE{"cpp"}% #include #include using namespace std; int main() { fstream myfile; myfile.open("c:\\1.txt",ios::out|ios::app,0); if(myfile) { cout<<"文件寫錯誤,文件屬性可能為只讀!"<<endl; system("pause"); exit(1); } myfile<<"中國軟件開發實驗室"<<endl<<"網址:"<<"www.cndev- lab.com"<<endl; myfile.close();

            myfile.open("c:\\1.txt",ios::in,0); if(myfile) { cout<<"文件讀錯誤,文件可能丟失!"<<endl; system("pause"); exit(1); } char ch; while(myfile.get(ch)) { cout.put(ch); } myfile.close(); system("pause"); } %ENDCODE% 由于fstream類可以對文件同時進行讀寫操作,所以對它的對象進行初始話的時候一定要顯式的指定mode和openprot參數。

              接下來我們來學習一下串流類的基礎知識,什么叫串流類?

            3 strstream: ostrstream 和 istrstream

              簡單的理解就是能夠控制字符串類型對象進行輸入輸出的類,C++不光可以支持C++風格的字符串流控制,還可以支持C風格的字符串流 控制。

              我們先看看看C++是如何對C風格的字符串流進行控制的,C中的字符串其實也就是字符數組,字符數組內的數據在內存中的位置的 排列是連續的,我們通常用 char str[size]或者char *str的方式聲明創建C風格字符數組,為了能讓字符數組作為設備并提供輸入輸出操作,C++引入了ostrstream、istrstream、 strstream這三個類,要使用他們創建對象就必須包含strstream.h頭文件。

            • istrstream類用于執行C風格的串流的輸入操作,也就是以字符串數組作為輸入設備。
            • ostrstream類用于執行C風格的串流的輸出操作,也就是一字符串數組作為輸出設備。
            • strstream類同時可以支持C風格的串流的輸入輸出操作。

              istrstream類是從istream(輸入流類)和strstreambase(字符串流基類)派生而 來,ostrstream是從 ostream(輸出流類)和strstreambase(字符串流基類)派生而來,strstream則是從iostream(輸入輸出流類)和和 strstreambase(字符串流基類)派生而來。

              他們的繼承關系如下圖所示:

              串流同樣不是標準設備,不會有預先定義好的全局對象,所以不能直接操作,需要通過構造函數創建對象。

            類istrstream的構造函數原形如下: %CODE{"cpp"}% istrstream::istrstream(const char *str,int size); %ENDCODE% 參數1表示字符串數組,而參數2表示數組大小,當size為0時,表示istrstream類對象直接連接到由str所指向的內存空間并以\0結尾的 字符串。

              下面的示例代碼就是利用istrstream類創建類對象,制定流輸入設備為字符串數組,通過它向一個字符型對象輸入數據。代 碼如下: %CODE{"cpp"}% #include #include using namespace std; int main() { char *name = "www.cndev-lab.com"; int arraysize = strlen(name)+1; istrstream is(name,arraysize); char temp; is>>temp; cout<<temp; system("pause"); } %ENDCODE% 類ostrstream用于執行串流的輸出,它的構造函數如下所示: %CODE{"cpp"}% ostrstream::ostrstream(char *_Ptr,int streamsize,int Mode = ios::out); %ENDCODE%   第一個參數是字符數組,第二個是說明數組的大小,第三個參數是指打開方式。

              我們來一個示例代碼: %CODE{"cpp"}% #include #include using namespace std; int main() { int arraysize=1; char *pbuffer=new char[arraysize]; ostrstream ostr(pbuffer,arraysize,ios::out); ostr<<arraysize<<ends;//使用ostrstream輸出到流對象的時候,要用ends結束字符串 cout<<pbuffer; delete[] pbuffer; system("pause"); } %ENDCODE% 上面的代碼中,我們創建一個c風格的串流輸出對象ostr,我們將arraysize內的數據成功的以字符串的形式輸出到了ostr對象所指向的 pbuffer指針的堆空間中,pbuffer也正是我們要輸出的字符串數組,在結尾要使用ends結束字符串,如果不這么做就有溢出的危險。

            4 stringstream

            對于stringstream了來說,不用我多說,大家也已經知道它是用于C++風格的字符串的輸入輸出的。 stringstream的構造函數原形如下: %CODE{"cpp"}%   stringstream::stringstream(string str); %ENDCODE%   示例代碼如下: %CODE{"cpp"}% #include #include #include using namespace std;

            int main() { stringstream ostr("ccc"); ostr.put('d'); ostr.put('e'); ostr<<"fg"; string gstr = ostr.str(); cout<<gstr<<endl;

            char a; ostr>>a; cout<<a

            system("pause"); } %ENDCODE% 除此而外,stringstream類的對象我們還常用它進行string與各種內置類型數據之間的轉換。示例代碼如下: %CODE{"cpp"}% #include #include #include using namespace std;

            int main() { stringstream sstr; //--------int轉string----------- int a=100; string str; sstr<<a; sstr>>str; cout<<str<<endl; //--------string轉char[]-------- sstr.clear();//如果你想通過使用同一stringstream對象實現多種類型的轉換,請注意在每一次轉換之后都必須調用clear() 成員函數。 string name = "colinguan"; char cname[200]; sstr<<name; sstr>>cname; cout<<cname; system("pause"); } %ENDCODE% 接下來我們來學習一下輸入/輸出的狀態標志的相關知識.

            5 io_state 輸入/輸出的狀態標志

            C++中負責的輸入/輸出的系統包括了關于每一個輸入/輸出操作的結果的記錄信息。這些當前的狀態信息被包含在io_state類型的對 象中。io_state是一個枚舉類型(就像open_mode一樣),以下便是它包含的值。
            • goodbit 無錯誤
            • Eofbit 已到達文件尾
            • failbit 非致命的輸入/輸出錯誤,可挽回
            • badbit 致命的輸入/輸出錯誤,無法挽回

            有兩種方法可以獲得輸入/輸出的狀態信息。一種方法是通過調用rdstate()函數,它將返回當前狀態的錯誤標記。例如,假如沒 有任何錯誤,則rdstate()會返回goodbit.下例示例,表示出了rdstate()的用法: %CODE{"cpp"}% #include using namespace std;

            int main() { int a; cin>>a; cout<<cin.rdstate()<<endl; if(cin.rdstate() == ios::goodbit) { cout<<"輸入數據的類型正確,無錯誤!"<<endl; } if(cin.rdstate() == ios_base::failbit) { cout<<"輸入數據類型錯誤,非致命錯誤,可清除輸入緩沖區挽回!"<<endl; } system("pause"); } %ENDCODE%   另一種方法則是使用下面任何一個函數來檢測相應的輸入/輸出狀態: %CODE{"cpp"}% bool bad(); bool eof(); bool fail(); bool good(); %ENDCODE%

              下例示例,表示出了上面各成員函數的用法: %CODE{"cpp"}% #include using namespace std;

            int main() { int a; cin>>a; cout<<cin.rdstate()<<endl; if(cin.good()) { cout<<"輸入數據的類型正確,無錯誤!"<<endl; } if(cin.fail()) { cout<<"輸入數據類型錯誤,非致命錯誤,可清除輸入緩沖區挽回!"<<endl; } system("pause"); } %ENDCODE% 如果錯誤發生,那么流狀態既被標記為錯誤,你必須清除這些錯誤狀態,以使你的程序能正確適當地繼續運行。要清除錯誤狀態,需使用clear()函數。 此函數帶一個參數,它是你將要設為當前狀態的標志值。,只要將ios::goodbit作為實參。

              示例代碼如下: %CODE{"cpp"}% #include using namespace std;

            int main() { int a; cin>>a; cout<<cin.rdstate()<<endl; cin.clear(ios::goodbit); cout<<cin.rdstate()<<endl; system("pause"); } %ENDCODE% 通常當我們發現輸入有錯又需要改正的時候,使用clear()更改標記為正確后,同時也需要使用get()成員函數清除輸入緩沖區,以達到重復輸入的目 的。

              示例代碼如下: %CODE{"cpp"}% #include using namespace std;

            int main() { int a; while(1) { cin>>a; if(cin)//條件可改寫為cin.fail() { cout<<"輸入有錯!請重新輸入"<<endl; cin.clear(); cin.get(); } else { cout<<a; break; } } system("pause"); } %ENDCODE%   最后再給出一個對文件流錯誤標記處理的例子,鞏固學習,代碼如下: %CODE{"cpp"}% #include #include using namespace std;

            int main() { ifstream myfile("c:\\1.txt",ios_base::in,0); if(myfile.fail()) { cout<<"文件讀取失敗或指定文件不存在!"<<endl; } else { char ch; while(myfile.get(ch)) { cout<<ch; } if(myfile.eof()) { cout<<"文件內容已經全部讀完"<<endl; } while(myfile.get(ch)) { cout<<ch; } } system("pause"); } %ENDCODE%  


            posted on 2010-03-26 22:03 LynnRaymond 閱讀(2214) 評論(0)  編輯 收藏 引用 所屬分類: C/C++語言

            <2007年11月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            導航

            統計

            常用鏈接

            留言簿

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久午夜福利无码1000合集| 免费一级做a爰片久久毛片潮| 久久亚洲精品成人av无码网站| 99久久国产综合精品女同图片| 无码AV中文字幕久久专区| 国产精品一区二区久久| 欧洲国产伦久久久久久久| 久久久久久九九99精品| 99久久精品免费观看国产| 国产成人无码精品久久久性色 | 亚洲日韩中文无码久久| 国产精品久久自在自线观看| 亚洲人成无码www久久久| 国产精品久久久久国产A级| 亚洲欧美成人久久综合中文网 | 久久99精品国产99久久| 亚洲美日韩Av中文字幕无码久久久妻妇 | 996久久国产精品线观看| 欧美成人免费观看久久| 国产精品日韩深夜福利久久| 精品久久久无码21p发布| 久久伊人影视| 91精品国产91久久久久久蜜臀| 色狠狠久久AV五月综合| 中文国产成人精品久久亚洲精品AⅤ无码精品| 久久久久亚洲AV无码专区体验| 久久强奷乱码老熟女网站| 久久久91精品国产一区二区三区| 亚洲精品乱码久久久久久蜜桃图片 | 青青青青久久精品国产h| 人妻精品久久久久中文字幕69| 伊人 久久 精品| 日韩精品久久久久久久电影| 无码人妻久久一区二区三区蜜桃| 久久久网中文字幕| 婷婷久久综合九色综合九七| 少妇被又大又粗又爽毛片久久黑人 | 国产福利电影一区二区三区久久久久成人精品综合 | 99久久精品毛片免费播放| 国产精品久久成人影院| 狠狠狠色丁香婷婷综合久久五月|