?? 11章 c++輸入輸出流.txt
字號(hào):
4
5 int main()
6 {
7 int i = 1000;
8 double d = 0.0947625;
9
10 cout << "The value of the flags variable is:"
11 << cout.flags()
12 << "\nPrint int and double in original format:\n"
13 << i << '\t' << d << "\n\n";
14 long originalFormat =
15 cout.flags( ios::oct | ios::scientific );
16 cout << "The value of the flags variable is:"
17 << cout.flags()
18 << "\nPrint int and double in a new format\n"
19 << "specified using the flags member function:\n"
20 << i << '\t' << d << "\n\n";
21 cout.flags( originalFormat );
22 cout << "The value of the flags variable is:"
23 << cout.flags()
24 << "\nPrint values in original format again:\n"
25 << i << '\t' << d << endl;
26 return 0;
27 }
輸出結(jié)果:
The value of the flags variable is: 0
Print int and double in original format:
1000 0.0947628
The value of the flags variable is: 4040
Print iht and double in a new format
Specified using the flags member function:
1750 9.476280e-002
The value of the flags variable is: 0
Print values in original format again:
1000 0.0947628
圖 11.28 演示成員函數(shù)flags
成員函數(shù)serf設(shè)置參數(shù)所指定的格式標(biāo)志,并返回long類型的標(biāo)志設(shè)置值,例如:
long previousFlagSettings=
cout.setf(ios::showpoint | ios::showpos);
帶兩個(gè)long型參數(shù)的setf成員函數(shù).例如:
cout.setf(ios::left,ios::adjustfield);
首先清除ios::adjustfield位,然后設(shè)置ios::left標(biāo)志。該版本的setf用于與ios::basefield(用ios::dec、
ios::oct和ios::hex表示)、ios::floatfield(用ios::scientific和ios::fixed表示)和ios::adjustfiald(用ios::
left、ios::right和ios::internal表示)相關(guān)的位段。
成員函數(shù)unsetf清除指定的標(biāo)志并返回清除前的標(biāo)志值。
11.8 流錯(cuò)誤狀態(tài)
可以用類ios中的位測(cè)試流的狀態(tài)。類ios是輸入/輸出類istream、ostream和iostream的基類。
當(dāng)遇到文件結(jié)束符時(shí),輸人流中自動(dòng)設(shè)置eofbit。可以在程序中使用成員函數(shù)eof確定是否已經(jīng)到達(dá)文件尾。如果cin遇到了文件結(jié)束符,那么函數(shù)調(diào)用:
cin.eof()
返回true,否則返回false。
當(dāng)流中發(fā)生格式錯(cuò)誤時(shí),雖然會(huì)設(shè)置failbit,但是字符并末丟失。成員函數(shù)fail判斷流操作是否失敗,這種錯(cuò)誤通常可修復(fù)。
當(dāng)發(fā)生導(dǎo)致數(shù)據(jù)丟失的錯(cuò)誤時(shí),設(shè)置badbit。成員函數(shù)bad判斷流操作是否失敗,這種嚴(yán)重錯(cuò)誤通常不可修復(fù)。
如果eofbit、failbit或badbit都沒有設(shè)置,則設(shè)置goodbit。
如果函數(shù)bad、fail和eof全都返回false,則成員函數(shù)good返回true。程序中應(yīng)該只對(duì)“好”的流進(jìn)行I/O操作。
成員函數(shù)rdstate返回流的錯(cuò)誤狀態(tài)。例如.函數(shù)調(diào)用cout.rdstate將返回流的狀態(tài),隨后可以用一條switch語句測(cè)試該狀態(tài),測(cè)試工作包括檢查ios::eofbit、ios::badbit、ios::failbit和ios::goodbit。
測(cè)試流狀態(tài)的較好方法是使用成員函數(shù)eof、bad、fail和good,使用這些函數(shù)不需要程序員熟知特定的狀態(tài)位。
成員函數(shù)clear通常用于把—個(gè)流的狀態(tài)恢復(fù)為“好”,從而可以對(duì)該流繼續(xù)執(zhí)行I/O操作。由于clear的默認(rèn)參數(shù)為ios::goodbit,所以下列語句:
cin.clear();
清除cin,并為流設(shè)置goodbit。下列語句:
cin.clear(ios::failbit)
實(shí)際上給流設(shè)置了failbit。在用自定義類型對(duì)cin執(zhí)行輸入操作或遇到問題時(shí),用戶可能需要這么做。clear這個(gè)名字用在這里似乎并不合適,但規(guī)定就是如此。
圖11.29中的程序演示了成員函數(shù)rdstate、eof、fail、bad、good和clear的使用。
只要badbit和failbit中有一個(gè)被置位,成員函數(shù)operator!就返回true。只要badbit和failbit中有一個(gè)被置位,成員函數(shù)operator void*就返回false。這些函數(shù)可用于文件處理過程中測(cè)試選擇結(jié)構(gòu)或循環(huán)結(jié)構(gòu)條件的true/false情況。
1 // Fig. 11.29: fig11_29.cpp
2 // Testing error states.
3 #include <iostream.h>
4
5 int main()
6 {
7 int x;
8 cout << "Before a bad input operation:"
9 << "\ncin.rdstate(): " << cin.rdstate()
10 << "\n cin.eof(): "<< cin.eof()
11 << "In cin.fail(): "<< cin.fail()
12 << "\n cin.bad(): " << cin.bad()
13 << "\n cin.good(): "<< cin.good()
14 << "\n\nExpects an integer, but enter a character: ";
15 cin >> x;
16
17 cout << "\nEnter a bad input operation:"
18 << "\ncin.rdstate(): "<< cin.rdstate()
19 << "\n cin.eof(): "<< cin.eof()
20 << "\n cin.fail(): " << cin.fail()
21 << "\n cin.bad(): "<< cin.badO
22 << "\n cin.geed() " << cin.good() << "\n\n";
23
24 cin.clear();
25
26 cout << "After cin.clear()"
27 << "\ncin.fail(): "<< cin.fail()
28 << "\ncin.good(): "<< cin.good{) << endl;
29 return 0;
30 }
輸出結(jié)果:
Before a bad input operation:
cin.rdstate(): 0
cin.eof(): 0
cin.fail() 0
tin.bad(): 0
cin.good(): 0
Expects an integer, but enter a character: A
After a bad input operation:
cin.eof(): 0
cin.fail(): 2
cin.bad(): 0
cin.good(): 0
After cin.clear()
cin. fail():0
cin.good(): 1
圖 11.29 測(cè)試錯(cuò)誤狀態(tài)
11.9 把輸出流連到輸入流上
交互式應(yīng)用程序通常要分別用類istream和ostream輸入和輸出數(shù)據(jù)。當(dāng)提示信息出現(xiàn)在屏幕上時(shí),用戶輸入一個(gè)數(shù)據(jù)來響應(yīng)。顯然,提示信息必須在執(zhí)行輸入操作前出現(xiàn)。在有輸出緩沖區(qū)的情況下,只有在緩沖區(qū)已滿時(shí)、在程序中明確地刷新輸出緩沖區(qū)時(shí)或因程序結(jié)束而自動(dòng)刷新輸出緩沖區(qū)時(shí),輸出信息才會(huì)顯示到屏幕上。為保證輸出要在下一個(gè)輸入前顯示,C++提供了成員函數(shù)tie,該函數(shù)可以實(shí)現(xiàn)輸入/輸出操作的同步,也就是把這兩個(gè)操作“系在一起”。例如,函數(shù)調(diào)用:
cin.tie(&cout);
把cout(ostream的對(duì)象)連到cin(istream的對(duì)象)上。實(shí)際上,C++為了建立用戶的標(biāo)準(zhǔn)輸入/輸出環(huán)境而自動(dòng)執(zhí)行了這個(gè)操作,所以這個(gè)專門的調(diào)用其實(shí)是多余的。但是,用戶可以顯式地把其他配對(duì)的輸入/輸出流“系”在一起。使用函數(shù)調(diào)用:
inputStream.tie(0);
可以從一個(gè)輸出流中解開輸入流inputStream。
小 結(jié)
●I/O操作是以對(duì)數(shù)據(jù)類型敏感的方式執(zhí)行的。
C++的I/O操作是以字節(jié)流的形式實(shí)現(xiàn)的。流實(shí)際上就是字節(jié)序列。
●輸入/輸出系統(tǒng)的任務(wù)實(shí)際上就是以一種穩(wěn)定、可靠的方式在設(shè)備與內(nèi)存之間傳輸數(shù)據(jù)。
●C++提供了低級(jí)和高級(jí)I/O功能。低級(jí)I/O功能通常只在設(shè)備和內(nèi)存之間傳輸一些字節(jié)。高級(jí)I/O功能把若干個(gè)字節(jié)組合成有意義的單位,如整數(shù)、浮點(diǎn)數(shù)、字符、字符串以及用戶自定義類型的數(shù)據(jù)。
●C++提供了無格式I/O和格式化I/O兩種操作。無格式I/O傳輸速度快,但使用起來較為麻煩。格式化I/O按不同的類型對(duì)數(shù)據(jù)進(jìn)行處理,但需要增加額外的處理時(shí)間,不適于處理大容量的數(shù)據(jù)傳輸。
●頭文件iostream.h包括了操作所有輸入/輸出流所需的基本信息,因此在大多數(shù)C++程序中都應(yīng)該包含這個(gè)頭文件。
●在執(zhí)行格式化I/O時(shí),如果流中帶有含參數(shù)的流操縱算子,頭文件iomanip.h所包含的信息是有用的。
●頭文件fstream.h包含了文件處理操作所需的信息。
●類istream支持流的輸入操作。
●類ostream支持流的輸出操作。
●類iostream同時(shí)支持流的輸入、輸出操作。
●類istream和ostream是通過單一繼承從基類ios派生出來的。
●類iostream是通過多重繼承從類istream和ostream派生出來的。
●重載的左移位運(yùn)算符(<<)表示流的輸出,稱為流插入運(yùn)算符。
●重載的右移位運(yùn)算符(>>)表示流的輸入,稱為流讀取運(yùn)算符。
●cin是類istream的對(duì)象,它與標(biāo)準(zhǔn)輸人設(shè)備(通常指鍵盤)“連”在一起。
●cout是類ostream的對(duì)象,它與標(biāo)準(zhǔn)輸出設(shè)備(通常指顯示器)“連”在一起。
●cerr是類ostream的對(duì)象,它與標(biāo)準(zhǔn)錯(cuò)誤輸出設(shè)備“連”在一起。對(duì)象cerr的輸出是非緩沖輸出,每一條出錯(cuò)信息都 會(huì)被立即顯示出來。
●流操縱算子endl用來插入一個(gè)換行符,并同時(shí)刷新輸出緩沖區(qū)。
●C++編譯器能夠自動(dòng)識(shí)別輸入、輸出數(shù)據(jù)的類型。
●默認(rèn)情況下,地址是以十六進(jìn)制格式顯示的。
●可以將指針強(qiáng)制轉(zhuǎn)換為void*類型從而輸出指針變量中的地址。
●成員函數(shù)put用于輸出單個(gè)字符,可以連續(xù)調(diào)用pul函數(shù)。
●流的輸入通過流讀取運(yùn)算符>>實(shí)現(xiàn),該運(yùn)算符自動(dòng)跳過輸入流中的空白字符。
●當(dāng)遇到輸入流中的文件結(jié)束符時(shí),運(yùn)算符>>返回false。
●當(dāng)輸入出現(xiàn)格式錯(cuò)誤時(shí),流讀取運(yùn)算符就會(huì)設(shè)置輸入流的failbit狀態(tài)位;如果操作失敗則設(shè)置badbit狀態(tài)位。
●我們通常在while循環(huán)結(jié)構(gòu)的首部用流讀取運(yùn)算符輸入一系列值。當(dāng)遇到文件結(jié)束符時(shí),流讀取運(yùn)算符返回0。
●不帶參數(shù)的get函數(shù)讀取(輸入)一個(gè)字符,并返回該字符;當(dāng)遇到輸人流中的文件結(jié)束符時(shí).返回EOF。
●帶一個(gè)字符型參數(shù)的get成員函數(shù)輸入一個(gè)字符。當(dāng)遇到文件結(jié)束符時(shí),函數(shù)返回EOF,否則返回對(duì)istream對(duì)象的引用,并用該引用再次調(diào)用get函數(shù)。
●帶有三個(gè)參數(shù)的get成員函數(shù),其三個(gè)參數(shù)分別是接收字符的字符數(shù)組、字符數(shù)組的大小和分隔符(默認(rèn)值為'\n')。函數(shù)或者在讀取比指定的最大字符數(shù)少一個(gè)字符后結(jié)束,或者在遇
到分隔符時(shí)結(jié)束。空字符終止輸入的字符串。函數(shù)不把分隔符放到字符數(shù)組中,但是分隔符仍然會(huì)保留在輸入流中。
●成員函數(shù)getline與帶三個(gè)參數(shù)的get函數(shù)類似。getline要去除輸入流中的分隔符,但是不把它存放在字符串中。
●成員函數(shù)ignore用于在需要時(shí)跳過流中指定數(shù)量的字符(默認(rèn)個(gè)數(shù)是1),或在遇到指定的分隔符(默認(rèn)分隔符是EOF)時(shí)結(jié)束。
●成員函數(shù)putback將最后一次用get從輸人流中讀取的字符放回到輸入流中。
●peek成員函數(shù)從輸入流返回下一個(gè)字符,但不從流中刪除這個(gè)字符。
●C++使用的是類型安全的I/O操作。如果>>或<<運(yùn)算符接收到了非法的數(shù)據(jù)類型,那么系統(tǒng)將設(shè)置各種錯(cuò)誤標(biāo)志位,用戶可根據(jù)這些標(biāo)志位來判斷操作I/O的成功與失敗。
●調(diào)用成員函數(shù)read、write可實(shí)現(xiàn)無格式輸入/輸出。這兩個(gè)函數(shù)分別把一定量的字節(jié)輸入內(nèi)存和從內(nèi)存中輸出。這些字節(jié)都是未經(jīng)任何格式化的,僅僅是以原始數(shù)據(jù)形式輸入或輸出。
●成員函數(shù)gcount返回函數(shù)read從輸入流中讀取的字符個(gè)數(shù)。
●成員函數(shù)read把指定個(gè)數(shù)的字符輸入到字符數(shù)組中。如果讀取的字符個(gè)數(shù)少于指定的數(shù)目,就設(shè)置標(biāo)志位failbit。
●如下方法可改變流中整數(shù)的基數(shù):使用流操縱算子hex可設(shè)置十六進(jìn)制基數(shù)(基數(shù)為16)、使用流操縱算子oct可設(shè)置八進(jìn)制基數(shù)(基數(shù)為8)、使用流操縱算子dec可恢復(fù)十進(jìn)制基數(shù)。只有顯式地改變流的基數(shù),否則流的基數(shù)是不變的。
●流操縱算子setbase也可以為整數(shù)輸出設(shè)置基數(shù)。流操縱算子setbase帶有一個(gè)整數(shù)參數(shù)10、8或16。
●流操縱算子setprecision或成員函數(shù)percision控制浮點(diǎn)數(shù)小數(shù)點(diǎn)后面的位數(shù)。設(shè)置了精度以后,該精度對(duì)之后所有的輸出操作都有效,直到再一次設(shè)置精度為止。無參數(shù)的成員函數(shù)percision返回當(dāng)前的精度。
●使用任伺參數(shù)化的流操縱算子都必須在程序中包含頭文件iomanip.h。
●成員函數(shù)width設(shè)置當(dāng)前域?qū)挷⒎祷匾郧霸O(shè)置的域?qū)挕H绻@示數(shù)據(jù)所需的寬度比設(shè)置的域?qū)捫。瘴挥锰畛渥址畛洹S驅(qū)捲O(shè)置僅對(duì)下一次流讀取或流插入操作有效;然后域?qū)掚[式設(shè)為0(可以輸出任意長度的序列值)。長度大于域?qū)挼闹狄部梢酝暾敵觥2粠?shù)的函數(shù)width返回當(dāng)前域?qū)挕A鞑倏v算子setw也可以用來設(shè)置城寬。
●在輸入操作中,流操縱算子setw用于設(shè)置字符串長度的最大值。如果輸入子一個(gè)長度大于最大值的字符串,那么該字符串將被分為若干個(gè)長度不大于限定值的字符串。
●用戶可以建立自己的流操縱算子。
●成員函數(shù)setf、unsetf和flags控制標(biāo)志設(shè)置。
●skipws標(biāo)志指示>>跳過輸入流中的空白字符。流操縱算子ws還可用于跳過輸入流中的前導(dǎo)空白字符。
●格式標(biāo)志在類ios中被定義為枚舉值。
●雖然成員函數(shù)flags、setf和unsetf可以控制格式標(biāo)志,但是許多程序員更喜歡使用流操縱算子。程序員可以用按位或操作(|)把各種標(biāo)志選項(xiàng)結(jié)合在一個(gè)long類型的值中。調(diào)用成員函數(shù)flags并指定要進(jìn)行或操作的標(biāo)志選項(xiàng)就可以在流中設(shè)置這些標(biāo)志,并返回一個(gè)包括以前標(biāo)志選項(xiàng)的long類型的值。返回值通常要保存起來,以便用保存值調(diào)用flags來恢復(fù)以前的選項(xiàng)。
●flags函數(shù)必須指定一個(gè)代表所有標(biāo)志設(shè)置的值。而帶有一個(gè)參數(shù)的函數(shù)setf指定的標(biāo)志與現(xiàn)存的標(biāo)志設(shè)置進(jìn)行或操作,形成新的格式狀態(tài)。
●設(shè)置showpoint標(biāo)志是為了強(qiáng)制輸出浮點(diǎn)數(shù)的小數(shù)點(diǎn)和由精度指定的有效數(shù)字的個(gè)數(shù)。
●left標(biāo)志可以使輸出域左對(duì)齊并把填充字符放在輸出數(shù)據(jù)的右邊,riiht標(biāo)志可以使輸出域右對(duì)齊并把填充字符放在輸出數(shù)據(jù)的左邊。
●internal標(biāo)志指示將一個(gè)數(shù)的符號(hào)位(設(shè)置了ios::showbase標(biāo)志時(shí)為基數(shù))在域?qū)拑?nèi)左對(duì)齊,數(shù)值右對(duì)齊,中間的空白由填充字符填充。
●left、right和internal標(biāo)志包含在ios::adjustfield中。
●成員函數(shù)fill用于設(shè)置與left、right和internal一起使用的使輸出域?qū)R的填充字符;如果沒有特別指定,空格即為填充字符。fill函數(shù)返回以前設(shè)置的填充字符。流操縱算子setfill同樣也可設(shè)置填充字符。
●靜態(tài)成員ios::basefield包括oct、hex和dec位,這些位分別指定把整數(shù)作為八進(jìn)制、十六進(jìn)制和十進(jìn)制值處理。如果沒有設(shè)置這些位,則流插入運(yùn)算默認(rèn)整數(shù)為十進(jìn)制數(shù),流讀取運(yùn)算按提供的方式處理數(shù)據(jù)。
●設(shè)置showbase標(biāo)志可強(qiáng)制輸出整數(shù)值的基數(shù)。
●ios::scientific和ios::fixed標(biāo)志包含在靜態(tài)數(shù)據(jù)成員ios::floafield中。這些標(biāo)志用于控制浮點(diǎn)數(shù)的輸出格式。設(shè)置scientific標(biāo)志使浮點(diǎn)數(shù)按照科學(xué)記數(shù)法格式輸出,設(shè)置fixed標(biāo)志使浮點(diǎn)
數(shù)按照precision成員函數(shù)指定的精度輸出。
●函數(shù)調(diào)用cout.setf(O,ios::floatfield)恢復(fù)浮點(diǎn)數(shù)的默認(rèn)顯示格式。
●設(shè)置1os::uppercase標(biāo)志用來使大寫的x和E分別同十六進(jìn)制整數(shù)和以科學(xué)記效法表示的浮點(diǎn)數(shù)一起輸出。一旦設(shè)置ios::uppercase標(biāo)志,十六進(jìn)制數(shù)中的所有字母都轉(zhuǎn)換成大寫。
●無參數(shù)的成員函數(shù)flags只返回格式標(biāo)志的當(dāng)前設(shè)置(long類型的值)。帶一個(gè)long類型參數(shù)的成員函數(shù)flags按參數(shù)指定的格式設(shè)置標(biāo)志并返回以前的標(biāo)志設(shè)置。
●成員函數(shù)setf設(shè)置參數(shù)所指定的格式標(biāo)志,井返回前一次的標(biāo)志設(shè)置值(long類型的值)。成員函數(shù)setf(long、setbits、long resetBits)清除resetBits中的位,然后設(shè)置resetBit位。
●成員函數(shù)unsetf清除已設(shè)置的標(biāo)志并返回清除前的標(biāo)志值。
●參數(shù)化的流操縱算子setiosflags與成員函數(shù)flags執(zhí)行同樣的功能。
●參數(shù)化的流操縱算予resetiosflags與成員函數(shù)unsetf執(zhí)行同樣的功能。
●流的狀態(tài)可以用類ios中的位來檢測(cè)。
●當(dāng)遇到文件結(jié)束符時(shí),輸入流中會(huì)被自動(dòng)設(shè)置eofbit。可以在程序中用成員函數(shù)eof確定是否設(shè)置了eofbit。
●當(dāng)流中發(fā)生格式錯(cuò)誤時(shí)雖然會(huì)設(shè)置failbit,但是字符并未丟失。成雖函數(shù)fail判斷流操作是否失敗,這種錯(cuò)誤通常可恢復(fù)。
●當(dāng)發(fā)生導(dǎo)致數(shù)據(jù)丟失的流格式錯(cuò)誤時(shí),設(shè)置badbit。成員函數(shù)bad判斷流操作是否失敗,這種嚴(yán)重錯(cuò)誤通常不可修復(fù)。
●如果函數(shù)bad、fail和eof全都返回false,則成員函數(shù)good返回true。應(yīng)該只對(duì)“好”的流進(jìn)行I/O操作。
●成員函數(shù)rdstate返回流的錯(cuò)誤狀態(tài)。
●成員函數(shù)clear通常用于把一個(gè)流的狀態(tài)恢復(fù)為“好”,從而可以對(duì)該流繼續(xù)執(zhí)行I/O操作。
●為保證輸出在下一個(gè)輸入前顯示,C++提供了成員函數(shù)如tie,該函數(shù)可以實(shí)現(xiàn)輸入/輸出操作的同步。
術(shù) 語
bad member function bad成員函數(shù) end-of-file 文件尾
badbit endl
cerr eof member function eof成員函數(shù)
cin eofbit
clear member function clear成員函數(shù) extensibility 可擴(kuò)展性
clog fail member function fail成員函數(shù)
cout failbit
dec stream manipulator dec流操縱算子 field width 域?qū)?default fill character(space) 默認(rèn)填充字符(空格) fillcharacter 填充字符
default precision 默認(rèn)精度 fill member function fill成員函數(shù)
flags member function flags成員函數(shù) ostream class ostrearm類
fush member function flush成員函數(shù) padding 填充
nush stream manipulator flush流操縱算子 parameterized stream manipulator 參
format flags 格式標(biāo)志 數(shù)化流操縱算子
fomat states 格式狀態(tài) peek member funotion peek成員函數(shù)
fomatted I/O 格式化I/O precision member function precision成員函數(shù)
fstream class fstream類 predefined streams 預(yù)定義的流
gcount member function gcount成員函數(shù) put mereber function put成員函數(shù)
get member function
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -