IO庫
在前面已經(jīng)用過了大部分的IO庫設(shè)施:
- istream類型
- ostream類型
- cin炸站,一個istream對象
- cout曹宴,一個ostream對象
- cerr,一個ostream對象,用于輸出程序錯誤消息
- >>運算符竹伸,用于從istream對象讀入數(shù)據(jù)
- <<運算符,用于向ostream對象輸出數(shù)據(jù)
- getline函數(shù)簇宽,從一個給的的istream讀取一行數(shù)據(jù)存入給定的string對象中勋篓。
8.1 IO類
到目前為止用到的IO類型和對象都是操縱char數(shù)據(jù)的。但是除此之外還有讀寫文件的類型及讀寫string對象的類型魏割。
8.1.1 IO對象無拷貝或賦值
不能夠拷貝或?qū)O對象賦值譬嚣,也不能將形參或返回類型設(shè)置為流類型。IO操作的函數(shù)通常以引用方式傳遞和返回流钞它,讀寫一個IO對象會改變其狀態(tài)拜银,因此傳遞和返回的引用不能說const的。
8.1.2 條件狀態(tài)
IO操作可能會引發(fā)錯誤遭垛,產(chǎn)生錯誤時IO的狀態(tài)會發(fā)生改變尼桶,所以IO庫有些函數(shù)和標志可以幫助我們訪問和操縱流的條件狀態(tài)。
查詢流的狀態(tài):IO庫定義了一個與機器無關(guān)的iostate類型耻卡,提供了表達流狀態(tài)的完整功能疯汁。
其中badbit表示系統(tǒng)級錯誤,如不可恢復(fù)的讀寫錯誤卵酪,一旦被置位流就無法再使用了幌蚊。在發(fā)生可恢復(fù)錯誤后,failbit被置位溃卡,這個是可以修正的溢豆。如果到達文件結(jié)束位置,eofbit和failbit會被置位瘸羡。goodbit為0漩仙,表示流未發(fā)生錯誤。
管理條件狀態(tài):流對象的rdstate成員返回一個iostate值犹赖,對應(yīng)流的當(dāng)前狀態(tài)队他。setstate操作將給定條件值置位,表示發(fā)生了對應(yīng)錯誤峻村。clear函數(shù)不接受參數(shù)的版本復(fù)位所有錯誤標志麸折,帶參數(shù)的clear成員函數(shù)接受一個iostate值,可以復(fù)位單一的條件狀態(tài)位粘昨。
8.1.3 管理輸出緩沖
每個輸出流都管理一個緩沖區(qū)垢啼,用于保存程序讀寫的程序窜锯。因為操作系統(tǒng)中存在緩沖機制,將程序中多個輸出操作組合成單一的系統(tǒng)級寫操作芭析,這樣可以避免頻繁且零碎的設(shè)備寫操作锚扎,提升系統(tǒng)性能。
導(dǎo)致緩沖刷新(系統(tǒng)寫操作)的原因有很多:
- 程序正常結(jié)束
- 緩沖區(qū)滿
- 用操縱符endl來顯示刷新緩沖區(qū)
- 在每個輸出操作之后馁启,可以用操縱符unitbuf設(shè)置流的內(nèi)部狀態(tài)驾孔,來清空緩沖區(qū)。默認情況下进统,對cerr是設(shè)置unitbuf的助币,所以寫道cerr的內(nèi)容是立即刷新的。
- 一個輸出流可能被關(guān)聯(lián)到另一個流螟碎。這時讀寫被關(guān)聯(lián)的流時眉菱,關(guān)聯(lián)到的流的緩沖區(qū)也會被刷新。
刷新輸出緩沖區(qū):用操縱符endl可以完成換行和緩沖區(qū)的刷新掉分。IO庫中還有兩個類似的操縱符:flush和ends俭缓。flush刷新緩沖區(qū),但不輸出任何額外的字符酥郭;ends向緩沖區(qū)插入一個空字符华坦,然后刷新緩沖區(qū)。
unitbuf操縱符:使用unitbuf操縱符可以讓流在每次寫操作后都進行一次flush操作不从。而nounitbuf操縱符則重置流惜姐,使其恢復(fù)使用正常的系統(tǒng)管理的緩沖區(qū)刷新機制。
cout<<unitbuf;
cout<<nounitbuf;
關(guān)聯(lián)輸入和輸出流:當(dāng)一個輸入流被關(guān)聯(lián)到一個輸出流時,任何試圖從輸入流讀數(shù)據(jù)的操作都會先刷新關(guān)聯(lián)的輸出流。
tie有兩個重載的版本犀变;一個版本不帶參數(shù)握截,返回指向輸出流的指針倚舀。如果本對象當(dāng)前關(guān)聯(lián)到一個輸出流,則返回的就是指向這個流的指針,如果對象未關(guān)聯(lián)到流,則返回空指針孟抗。tie的第二個版本接受一個指向ostream的指針,將自己關(guān)聯(lián)到此ostream钻心。
cin.tie(&cout);
ostream *old_tie=cin.tie(nullptr);
cin.tie(&cerr);
cin.tie(old_tie);
每個流最多可以關(guān)聯(lián)一個流凄硼,但是多個流可以關(guān)聯(lián)到同一個流。