C++流與標準IO庫

1. 流

數據在計算機設備和內存之間移動,其基本單位爲字符,故將其形象地稱爲流。C++中把輸入輸出流定義爲類,這裏的輸入、輸出是針對內存而言的。流類的對象稱爲流對象。每個流對象在內存中有自己的緩衝區用於暫存數據。流對象不能複製或賦值,但可以將其引用或指向流對象的指針作爲函數的參數或者返回值。

C++ primer(第四版)中主要講了三類流:標準輸入輸出流、文件流和字符串流。顧名思義,與流的交互對象分別爲標準設備、外設和字符串。

2.標準輸入/輸出流

頭文件:iostream/istream/ostream。後兩者是iostream的子類,分別對應標準輸入流和標準輸出流。iostream對象既可用於輸入又可以用於輸出。

2.1 標準輸出流

常用流對象:cout、cerr和clog。其中cerr負責向標準輸出(屏幕)輸出錯誤信息(字符串形式)。與clog的區別的前者不會經過緩衝區而直接輸出至屏幕。

緩衝區:暫存數據。內存中的數據首先存在輸出緩存區中,然後再輸出至標準輸出(屏幕)。

以下情況下會刷新輸出緩衝區:

a) 程序正常結束。若程序非正常退出且未作其它措施,則流緩衝區不會刷新。

b) 緩衝區已滿。

c) 顯式調用函數來刷新。可以通過endl、ends和flush操作符來顯示刷新。endl會插入換行符,ends會插入一個空字符(NULL),flush不會添加任何字符。

d) unitbuf設置流狀態:cout << unutbuf << ... << nounitbuf; 則...中的每一次輸出都會刷新一次緩衝區,直到nounitbuf操作符取消強制每次刷新。

e) 輸入流與輸出流相關聯(tie),讀輸入流時將會刷新輸出緩衝區。cin.tie(&cout); ostream *pos = cin.tie(); cin.tie(0).表示了cin與cout之間的綁定與解綁定操作。一 個ostreram對象一次只能被一個istream對象所綁定。

輸出對象:可以爲C++內置對象,或者重定義了輸出操作符的自定義對象。

輸出格式控制:可以通過使用控制符(需要include<iomanip>)或者流對象的內置函數:

a) 數值進制:cout << hex << a << dec << b << oct << c << setbase(int) <<d; 或者 cout.setf(ios::hex)/cout.setf(ios::dec)/cout.setf(ios::oct);其中setbase(int)的參數 取值爲8,10或16。若通過調用輸出流對象的內置函數輸出,則會帶有前綴(0x/0)。設置進制之後的整數輸出一直按此進制,直到顯式改變進制(cout內置函數方 式需要調用cout.unsetf(...))。

b) 寬度設置:cout << setw(int) << obj; 或者cout.width(int);用於設置輸出對象的最小寬度。

c) 默認填充: cout << setfill(char) << obj; 或者cout.fill(char); 用於不夠指定寬度時空白字符的填充。

d) 小數輸出格式:cout << setiosflags(ios::scientific) << a ; 或者cout.setf(ios::scientific);ios::scientific:科學計數法;ios::fixed:普通小數。

e) 小數精度: cout << setprecision(int) << a; 或者cout.precision(int)。科學計數法中參數表示小數點後有效數字位數,小數表示中參數表示總共的有效位數。

f) bool值輸出字符串:cout << boolalpha << b;

注:b和c設置之後僅對下一次輸入有效;cout.setf的參數可以爲用“|”隔開的設置組合。例如進制和表示法、精度的組合。

其他方法:可以用put方法實現字符的輸出:cout.put(ch) 或者 putchar(ch);其中前者需要include<stdio.h>。

2.2標準輸入流

常用對象:cin。

緩衝區:同標準輸出流,標準設備的輸入線暫存於內存中的輸入緩衝區,然後再輸入值內存中的相應位置。

緩衝區的刷新:fflush(cin);

流成員函數:

a) cin.get() :在標準輸入中讀取一個字符並且返回該字符。

b) cin.get(ch) :在標準輸入中讀取一個字符並且賦值給ch。

c) cin.get(char *p, int n, char del); 用於在標準輸入中讀取n-1個字符至p指向的內存中。若前n-1個字符中出現了字符del,則停止讀入。

d) getchar函數:主要作用是將cin後移一位,越過無用的字符(比如空格)。

字符串的輸入:遇到空格、製表或換行時停止。或者可以調用getline()函數來實現整行的讀取:cin.getline(str); 或者getline(cin, str);

其他成員:eof()表示文件尾; ignore(int n, char del) 表示忽略前n個字符或者del及其之前的m(m<n)個字符; cin.peek() 返回當前字符,但是流指向的位置不變;

2.3 流狀態

狀態常量:strm::badbit; strm::failbit; strm::eofbit;

常量類型:strm::iostate

狀態函數:strm.bad(); strm.fail(); strm.eof(); strm.good(); 只有前三個均爲false的時候strm.good()纔是true。

狀態設置:strm.clear(); 將狀態設置爲good()狀態。

    strm.clear(flag); 將flag位設爲true,其他位設爲false。(可以同時設置多個狀態,用“|”隔開)

    strm.setstate(flag);將flag設爲true。(可以同時設置多個狀態,用“|”隔開)

    strm.rdstate(); 讀取狀態。

說明:當遇到文件尾的時候,會爲eof()或bad(),若輸入錯誤,則會爲fail()。

3.文件流

3.1 頭文件:fstream; 流類型:fstream/ifstream/ofstream

3.2 使用:構造函數中傳遞函數名(C風格字符串)或者調用open函數(參數亦爲C風格字符串)。檢查文件是否打開成功,可以直接用if來判斷。讀取或者寫入完畢後應當        close(),close()之後應該clear()以恢復流狀態爲正確狀態。

3.3 文件模式:

in/out 通用: ate(定位至文件尾), binary(二進制讀寫方法)

in : in(讀取)

out: out(寫入),app(追加), trunc(清除其他文件流)

模式設置中同時包含in和out時表示既可以讀又可以寫,但是若再加上(“|”隔開)trunc,則等同於僅有out模式。

4. 字符串流

4.1 頭文件 sstream. 類型:stringstream/istringstream/ostringstream

4.2 stringstream 的使用:

a) 構造函數:stringstream strm; stringstream strm(str);

b) 返回string對象: strm.str();

c) 改變string對象:strm.str(str);

4.3 類型轉換:

步驟:由stringstream對象讀入string對象,然後再輸出爲不同類型的對象賦值即可。類型必須對應:

stringstream strm;

string str("this a1 234 b 45");

string s1, s2, s3;

int i1, i2;

strm.str(str);

strm >> s1 >> s2 >> i1 >> s3 >> i2;如此才能實現一一對應。空格或者製表符或者換行符是必要的間隔。

5. 輸入輸出操作符:

>> 和 << 的箭頭方向即表示了數據流的流動方向:

對於標準輸入輸出來說,cin >> a;  cout << b; 分別表示數據出輸入緩衝區和進入輸出緩衝區;

對於文件的輸入輸出:if  >> s; 和 of << s; 分別表示在文件中讀數據(經文件輸入緩衝區)到s和將s(經文件輸出緩衝區)輸入至文件。

對於stringstream:strm >> s; 和 strm << s 則分別表示爲s賦值和讀取s。

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