程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++中的IO庫(一)

C++中的IO庫(一)

編輯:C++入門知識

時間:2014.03.16

地點:基地二樓

---------------------------------------------------------------------------

一、常見IO設施概述

先來簡單總結下常用的IO設施

1. istream 輸入流類型,提供輸入操作

2.ostream 輸出流類型,提供輸出操作

3. cin 一個istream對象,從標准輸入讀取數據

4. cout 一個ostream對象,向標准輸出寫入數據

5. cerr 一個ostream對象,用於輸出程序錯誤信息,寫入到標准錯誤

6. >>運算符,從一個istrem對象讀取輸入數據

7. <<運算符,向一個ostream對象寫入輸出數據

8. getling函數,從一個給定的istream讀取一行數據,存入給定的string對象中

對於getling函數以下給出詳細用法:

一般我們習慣用cin>> 這樣的格式來獲取輸入,為什麼要getline呢。原因是我們希望能在最終得到的字符串中保留輸入時的空白符,這是cin>>就滿足不了需求了,要用到getline。getline函數的參數是一個輸入流和一個string對象。函數會從給定的輸入流中讀取內容,直到遇上換行符,而且換行符也會被讀進來。然後把所讀的內容存入string對象,但換行符不存,它實際上將會被丟棄。getline遇到換行符就結束讀取操作返回結果。即便是一開始就換行也是如此。比如一開始就是個換行符的話,getline讀進換行符,檢測到已經是換行符了,就結束讀取操作,返回內容,但由於此時什麼內容也沒有,因此是個空的string。

和輸入運算符一樣,getline也會返回流參數,我們曉得輸入運算符是能作為判別條件的,所以getline的結果也一樣可以。例如可用getline的結果作為條件,讓程序一次輸出一整行。

int main(){
  string line;
  while(getline(cin,line){
      cout<  另外還要介紹的的頭文件 iostream中定義的是用於讀寫流的基本類型——普通流,頭文件fstream定義了讀寫命名文件的類型——文件流,頭文件sstream則定義的是讀寫內存string對象的類型——string流。

一般情況下我們可以將一個派生類對象當做基類對象來使用。類型ifstream和istringstream對象都繼承自istream,ofstream和ostringstream都繼承自ostream。於是我們可以像使用istream對象一樣來使用它們。比如可以對一個ifstream或istringstream對象調用getline,也可以使用>>從ifstream或istringstream對象中讀取數據。

---------------------------------------------------------------------------

二、IO對象無拷貝無賦值

對IO對象進行拷貝和賦值是無意義的,所以不可以這樣操作,比如:

ofstring out1,out2;
out1=out2;   //錯,不能對流對象賦值
ofstream print(ofstream);  //錯誤,不能初始化ofstream參數
out2=print(out2);  //不能拷貝流對象
因為不能拷貝IO對象,顯然將形參或返回類型設置為流類型是不可以的,因為形參和返回設計對象的拷貝,所以,一般設計IO操作的函數以引用方式傳遞和返回流。另外,讀寫一個IO對象時會改變流的狀態,所以傳遞和返回的引用不能是const。

---------------------------------------------------------------------------

三、條件狀態

IO操作常可能發生錯誤,為了應對這一問題,IO類定義了一些函數和標志,根據這些流的條件狀態以協助程序員處理錯誤。一下總結了常用的IO庫條件狀態的函數和標志

strm::iostate iostate是一種機器相關的類型,提供表達條件狀態的完整功能

strm::badbit 用來指明流已經崩潰

strm::failbit 用來指出一個IO操作失敗

strm::eofbit 指出流到了文件結束

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中的所有狀態復位,流的狀態設置為有效,返回void

s.clera(flags) 根據給定的flags標志位,將流s中對應條件狀態復位,flags的類型為strm::iostate,返回void

s.setstate(flags) 根據給定的flag標志位將流s中對應條件狀態置位,falgs同上

s.rdstate() 返回流s的當前的條件狀態,返回值類型為strm::iostate
一個錯誤操作的例子:

int val;
cin>>ival;
如果我們鍵入 HuNan,讀操作就會發生失敗,因為程序期待讀入一個int類型,但卻得到了一個字符H,這樣cin流就進入錯誤狀態。一個流一旦發生錯誤,後續的IO操作都會失敗。由於流可能處於錯誤狀態,因此代碼在使用一個流前一般需要檢查流是否處於良好狀態,最簡單的辦法就是將它當做一個條件來使用:

while(cin>>word)
  //.....
這樣while會循環檢查>>表達式返回的流狀態。如果輸入操作成功,流保存有效狀態,條件為真,繼續下一次循環。

---------------------------------------------------------------------------

四、查詢流的狀態

當有時我們想要知道流具體狀態是什麼比如流為什麼會失敗,針對導致的原因我們可能涉及不同的處理方式,於是我們要查詢流的狀態了。IO庫定義了一個與機器無關的iostate類型,提供了表達流狀態的完整功能。該類型應該作為一個位集合來使用:

badbit 表系統級錯誤,如不可恢復讀寫錯誤,一旦badbit被置位,流就無法再用了

failbit IO操作失敗,若被置位,如期望讀取數值卻讀到一個字符等錯誤,這種問題通常可以修正,流還可以繼續使用,如果到達文件結束,eofbit和failbit都會被置位。

goobit值為0,表示流未發生錯誤。

如果badbit failbit eofbit任意一個被置位,則檢測流狀態的條件會失敗。

標准庫中也定義了一組函數來查詢這些標志位的狀態。如上述總結。操作good,在所有錯誤位均未置位的情況下返回true,而bad fail和eof則在對應錯誤位被置位時返回true.,此外,在badbit被置位時,fail也返回true。即使用good和fail是確定流的總體狀態的正確方法。將流當做條件使用即等價於 !fail() 。eof和bad操作只能表示特定的錯誤。

---------------------------------------------------------------------------

五、管理條件狀態

流對象的rdstate成員函數返回一個istate值,對應流的當前狀態。setstate操作則可將給定條件位置位,表示發生了對應錯誤。clear是一個重載成員函數,有兩個版本,一個不接受任何參數,將清除所有錯誤標志位,即復位。執行clear()後調用good()會返回true.。一個簡單的示例如下:

#include
#include
#include
using namespace std;
int main(){
	auto old_state = cin.rdstate();    //獲取當前流狀態
	cout << "old_state  " << old_state << endl;
	int a;     
	cin >> a;                              //在這裡你可以輸入一個非int類型的值,特意破壞流的正確性
	auto current_state = cin.rdstate();    //在此獲取流狀態,此時顯示已經不正常了
	cout << "current_state  " << current_state << endl;
	cin.clear();                           //使流所有條件狀態復位,且流設為有效,這句很重要,否則後面對流的操作都會不成功,不信可試試
	cin.setstate(old_state);               //現在流有效了,重新使他恢復到最初始狀態
	auto nex_state = cin.rdstate();
	cout << "new_state  "<這裡說明下:一定要注意當流發生錯誤後,如果不clear()對流進行復位,那麼後面對流的操作都是不成功的。

而帶參數的clear()可以這樣使用,讓它接受一個iostate值,表示流的新狀態,於是我們可以哈斯用rdstate讀出的iostate值,即當前的條件狀態。然後用位操作將所需要復位來生成新的狀態。這裡我們要用到一個公式,即

(b)& (~b)=0

現在假如我們想將failbit和badbit復位,即置0,但eofbit保持不變,可以這樣做:

cin.clear(cin.rdstate()&~cin.failbit&~cin.badbit);
上面的位與操作是的表示狀態的failbit 和badbit會成為0,如此得到一個新的狀態,傳遞個clear()從而達到目的。



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved