




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、信息學(xué)院信息技術(shù)教研室第13章 輸入輸出流本章主要內(nèi)容13.1 C+的輸入和輸出的輸入和輸出13.2 標(biāo)準(zhǔn)輸出流標(biāo)準(zhǔn)輸出流13.3 標(biāo)準(zhǔn)輸入流標(biāo)準(zhǔn)輸入流13.4 文件操作與文件流文件操作與文件流13.5 字符串流字符串流 13.1.1 輸入輸出的含義 程序的輸入與輸出v 程序的輸入指的是從輸入文件將數(shù)據(jù)傳送給程序。v 程序的輸出指的是從程序?qū)?shù)據(jù)傳送給輸出文件。13.1 C+的輸入和輸出v以終端為對象從鍵盤輸入數(shù)據(jù)運行結(jié)果輸出到顯示器屏幕上磁盤(光盤)可作為輸入輸出對象;而磁盤文件既可以作為輸入文件,也可以作為輸出文件。 C+的輸入與輸出包括以下3方面的內(nèi)容: 對系統(tǒng)指定的標(biāo)準(zhǔn)設(shè)備的輸入和輸出
2、。即從鍵盤輸入數(shù)據(jù),輸出到顯示器屏幕。這種輸入輸出稱為標(biāo)準(zhǔn)的輸入輸出,簡稱標(biāo)準(zhǔn)I/O。以外存磁盤文件為對象進(jìn)行輸入和輸出,即從磁盤文件輸入數(shù)據(jù),數(shù)據(jù)輸出到磁盤文件。以外存文件為對象的輸入輸出稱為文件的輸入輸出,簡稱文件I/O。對內(nèi)存中指定的空間進(jìn)行輸入和輸出。通常指定一個字符數(shù)組作為存儲空間(實際上可以利用該空間存儲任何信息)。這種輸入和輸出稱為字符串輸入輸出,簡稱串I/O。在C語言中v scanf進(jìn)行輸入v printf進(jìn)行輸出在C+語言中v通過I/O類庫來實現(xiàn)豐富的I/O功能13.1.3 C+的輸入輸出流流:stream在程序與設(shè)備之間的抽象概念在設(shè)備與內(nèi)存之間交換信息時出現(xiàn)的信息流v字符
3、流或文本流v二進(jìn)制數(shù)據(jù)流設(shè)備設(shè)備內(nèi)存內(nèi)存對“流”的理解 “流”是內(nèi)存與設(shè)備之間的一個對象程序讀操作:從“流”中讀程序?qū)懖僮鳎簩懙健傲鳌碑?dāng)中設(shè)備設(shè)備內(nèi)存內(nèi)存 C的基本流類體系 在C+中,輸入輸出流被定義為類。 C+的I/O庫中的類稱為流類(stream class)。 用流類定義的對象稱為流對象。v cinv coutcincoutiostream類的對象類的對象 1. iostream類庫中有關(guān)的類輸入輸出流輸入(input)和輸出(output)文件的輸入輸出 ifstream類 ofstream類 I/O類庫中還有其他類 2. 與iostream類庫有關(guān)的頭文件 iostream類庫的接口
4、分別由不同的頭文件來實現(xiàn)。v常用的有:l iostream 包含了對輸入輸出流進(jìn)行操作所需的基本信息。l fstream 用于用戶管理的文件的I/O操作。l strstream 用于字符串流I/O。l stdiostream 用于混合使用C和C+的I/O機制時。l iomanip 在使用格式化I/O時應(yīng)包含此頭文件。 3. 在iostream頭文件中定義的流對象在iostream頭文件中定義的類有l(wèi)ios,listream,lostream,liostream,listream _withassign, lostream_withassign,liostream_withassign 等。io
5、stream.h包含了對輸入輸出流進(jìn)行操作所需的基本信息。 4種流對象 cin是istream的派生類istream_withassign的對象,它是從標(biāo)準(zhǔn)輸入設(shè)備(鍵盤)輸入到內(nèi)存的數(shù)據(jù)流,稱為cin流或標(biāo)準(zhǔn)輸入流。cout是ostream的派生類ostream_withassign的對象,它是從內(nèi)存輸出到標(biāo)準(zhǔn)輸出設(shè)備(顯示器) 的數(shù)據(jù)流,稱為cout流或標(biāo)準(zhǔn)輸出流。 cerr和clog作用相似,均為向輸出設(shè)備(顯示器) 輸出出錯信息。 4. 在iostream頭文件中重載運算符 在istream和ostream類中分別有一組成員函數(shù)對位移運算符“”進(jìn)行重載,以便能用它輸入或輸出各種標(biāo)準(zhǔn)數(shù)據(jù)
6、類型的數(shù)據(jù)。對于不同的標(biāo)準(zhǔn)數(shù)據(jù)類型要分別進(jìn)行重載,如vostream operator (int ); /用于向輸出流插入一個int數(shù)據(jù)vostream operator (float ); /用于向輸出流插入一個float數(shù)據(jù)vostream operator (char ); /用于向輸出流插入一個char數(shù)據(jù)vostream operator (char *); /用于向輸出流插入一個字符串?dāng)?shù)據(jù)等如果在程序中有下面的表如果在程序中有下面的表達(dá)式達(dá)式: coutC+;上面的表達(dá)式相當(dāng)于上面的表達(dá)式相當(dāng)于cout.operator(C+)C+的值是其首字節(jié)地址,是字符型指針(char*)類型
7、,因此選擇調(diào)用上面最后一個運算符重載函數(shù),通過重載函數(shù)的函數(shù)體,將字符串插入到cout流中,函數(shù)返回流對象cout。 理解運算符“”的作用呢? 它們指出了數(shù)據(jù)移動的方向,例如v ava箭頭方向表示把數(shù)據(jù)放入a中。箭頭方向表示從a中拿出數(shù)據(jù)。13.2 標(biāo)準(zhǔn)輸出流 標(biāo)準(zhǔn)輸出流是流向標(biāo)準(zhǔn)輸出設(shè)備(顯示器)的數(shù)據(jù)。13.2.1 cout,cerr和clog流v預(yù)先定義的輸出流對象:lcout 標(biāo)準(zhǔn)輸出lcerr 標(biāo)準(zhǔn)錯誤輸出,沒有緩沖,發(fā)送給它的內(nèi)容立即被輸出。lclog 類似于cerr,但是有緩沖,緩沖區(qū)滿時被輸出。輸出流1. cout流對象vcout是console output的縮寫,意為在控制
8、臺(終端顯示器)的輸出。(1) cout不是C+預(yù)定義的關(guān)鍵字,它是ostream流類的對象,在iostream中定義。(2) 用“cout”輸出基本類型的數(shù)據(jù)時,可以不必考慮數(shù)據(jù)是什么類型,系統(tǒng)會判斷數(shù)據(jù)的類型,并根據(jù)其類型選擇調(diào)用與之匹配的運算符重載函數(shù)。v(3) cout流在內(nèi)存中對應(yīng)開辟了一個緩沖區(qū),用來存放流中的數(shù)據(jù),當(dāng)向cout流插入一個endl時,不論緩沖區(qū)是否已滿,都立即輸出流中所有數(shù)據(jù),然后插入一個換行符,并刷新流(清空緩沖區(qū))。v(4) 在iostream中只對“”運算符用于標(biāo)準(zhǔn)類型數(shù)據(jù)的輸入輸出進(jìn)行了重載,但未對用戶聲明的類型數(shù)據(jù)的輸入輸出進(jìn)行重載。 2. cerr流對象
9、vcerr流對象是標(biāo)準(zhǔn)錯誤流。cerr流已被指定為與顯示器關(guān)聯(lián)。cerr的作用是向標(biāo)準(zhǔn)錯誤設(shè)備(standard error device)輸出有關(guān)出錯信息。 cerr與標(biāo)準(zhǔn)輸出流cout的作用和用法差不多。v但有一點不同: lcout流通常是傳送到顯示器輸出,但也可以被重定向輸出到磁盤文件l而cerr流中的信息只能在顯示器輸出。cout 流流cerr 流流當(dāng)調(diào)試程序時,往往不希望程序運行時的出錯信息被送到其他文件,而要求在顯示器上及時輸出,這時應(yīng)該用cerr。cerr流中的信息是用戶根據(jù)需要指定的。v 例13.1 有一元二次方程ax2+bx+c=0,其一般解為 x1,2=(-bb2-4ac)
10、/2a,但若a=0,或b2-4ac0時,用此公式出錯。u要求:編程序,從鍵盤輸入a,b,c的值,求x1和x2。如果a=0或b2-4ac0,輸出出錯信息。#include #include using namespace std;int main( ) float a,b,c,disc; coutabc; if (a=0) cerra is equal to zero,error!endl; /將有關(guān)出錯信息插入cerr流,在屏幕輸出 elseif (disc=b*b-4*a*c)0) cerrdisc=b*b-4*a*c0endl; /將有關(guān)出錯信息插入cerr流,在屏幕輸出elsecoutx
11、1=(-b+sqrt(disc)/(2*a)endl;coutx2=(-b-sqrt(disc)/(2*a)endl; return 0;第第次次運行結(jié)果如下運行結(jié)果如下please input a,b,c: 0 2 3 a is equal to zero,error!第第次次運行結(jié)果如下運行結(jié)果如下please input a,b,c: 5 2 3 sc=b*b-4*a*c0第第次次運行結(jié)果如下運行結(jié)果如下please input a,b,c: 1 2.5 1.5 x1=-1x2=-1.5 3. clog流對象vclog流對象也是標(biāo)準(zhǔn)錯誤流,它是console log的縮寫。它的作用和ce
12、rr相同,都是在終端顯示器上顯示出錯信息。v區(qū)別:緩沖區(qū)緩沖區(qū)cerr 流流clog 流流不經(jīng)過緩沖區(qū)直接輸出先存放在緩沖區(qū)中,緩沖區(qū)滿后或遇endl時輸出13.2.2 格式輸出 在輸出數(shù)據(jù)時,有時希望數(shù)據(jù)按指定的格式輸出。有兩種方法可以達(dá)到此目的。v一種是第3章已介紹過的使用控制符的方法;v第2種是使用流對象的有關(guān)成員函數(shù)。1. 使用控制符控制輸出格式v輸出數(shù)據(jù)的控制符見書中表13.3。v應(yīng)當(dāng)注意,這些控制符是在頭文件iomanip中定義的,因而程序中應(yīng)當(dāng)包含iomanip。#include #include /不要忘記包含此頭文件using namespace std;int main()
13、int a; couta; coutdec:decaendl; /以十進(jìn)制形式輸出整數(shù) couthex:hexaendl; /以十六進(jìn)制形式輸出整數(shù)a coutoct:setbase(8)aendl; /以八進(jìn)制形式輸出整數(shù)a char *pt=China; /pt指向字符串China coutsetw(10)ptendl; /指定域?qū)挒?0,輸出字符串coutsetfill(*)setw(10)ptendl; /指定域?qū)?0,輸出字符串,空白處以*填充 double pi=22.0/7.0; /計算pi值 coutsetiosflags(ios:scientific)setprecision
14、(8); /按指數(shù)形式輸出,8位小數(shù) coutpi=piendl; /輸出pi值 coutpi=setprecision(4)piendl; /改為4位小數(shù) coutpi=setiosflags(ios:fixed)piendl; /改為小數(shù)形式輸出 return 0;例例13.2 用控制符控制輸出格式。用控制符控制輸出格式。運行結(jié)果如下運行結(jié)果如下input a:34 (輸入a的值)dec:34 (十進(jìn)制形式)hex:22 (十六進(jìn)制形式)oct:42 (八進(jìn)制形式) China (域?qū)挒?0)*China (域?qū)挒?0,空白處以*填充)pi=3.14285714e+00 (指數(shù)形式輸出,8
15、位小數(shù))pi=3.1429e+00 (指數(shù)形式輸出,4位小數(shù))pi=3.143 (小數(shù)形式輸出,精度仍為4)2. 用流對象的成員函數(shù)控制輸出格式調(diào)用流對象cout中用于控制輸出格式的成員函數(shù)來控制輸出格式。v 流成員函數(shù)setf 和控制符setiosflags括號中的參數(shù)表示格式狀態(tài),它是通過格式標(biāo)志來指定的。v 格式標(biāo)志在類ios中被定義為枚舉值。因此在引用這些格式標(biāo)志時要在前面加上類名ios和域運算符“:”。格式標(biāo)志見書中表13.5。#include using namespace std;int main( )int a=21 cout.setf(ios:showbase); /顯示基數(shù)
16、符號(0 x或0) coutdec:aendl; /默認(rèn)以十進(jìn)制形式輸出a cout.unsetf(ios:dec); /終止十進(jìn)制的格式設(shè)置 cout.setf(ios:hex); /設(shè)置以十六進(jìn)制輸出的狀態(tài) couthex:aendl; /以十六進(jìn)制形式輸出acout.unsetf(ios:hex); /終止十六進(jìn)制的格式設(shè)置 cout.setf(ios:oct); /設(shè)置以八進(jìn)制輸出的狀態(tài) coutoct:aendl; /以八進(jìn)制形式輸出acout.unseft(ios:oct); char *pt=China; /pt指向字符串China cout.width(10); /指定域?qū)挒?
17、0 coutptendl; /輸出字符串 cout.width(10); /指定域?qū)挒?0例例13.3 用流控制成員函數(shù)輸出數(shù)據(jù)。用流控制成員函數(shù)輸出數(shù)據(jù)。cout.fill(*); /指定空白處以*填充 coutptendl; /輸出字符串 double pi=22.0/7.0; /輸出pi值cout.setf(ios:scientific); /指定用科學(xué)記數(shù)法輸出coutpi=; /輸出pi=cout.width(14); /指定域?qū)挒?4coutpiendl; /輸出pi值cout.unsetf(ios:scientific); /終止科學(xué)記數(shù)法狀態(tài)cout.setf(ios:fixe
18、d); /指定用定點形式輸出cout.width(12); /指定域?qū)挒?2cout.setf(ios:showpos); /正數(shù)輸出“+”號cout.setf(ios:internal); /數(shù)符出現(xiàn)在左側(cè)cout.precision(6); /保留6位小數(shù)coutpiendl; /輸出pi,注意數(shù)符“+”的位置return 0;運行結(jié)果如下運行結(jié)果如下dec:21(十進(jìn)制形式十進(jìn)制形式)hex:0 x15 (十六進(jìn)制形式,以十六進(jìn)制形式,以0 x開頭開頭)oct:025 (八進(jìn)制形式,以八進(jìn)制形式,以0開頭開頭) China (域?qū)挒橛驅(qū)挒?0)*China (域?qū)挒橛驅(qū)挒?0,空白處以,
19、空白處以*填充填充)pi=*3.142857e+00 (指數(shù)形式輸出,域?qū)捴笖?shù)形式輸出,域?qū)?4,默認(rèn),默認(rèn)6位小數(shù)位小數(shù))+*3.142857 (小數(shù)形式輸出,精度為小數(shù)形式輸出,精度為6,最左側(cè)輸出數(shù)符,最左側(cè)輸出數(shù)符“+”) 13.2.3 用流成員函數(shù)put輸出字符 ostream類還提供了專用于輸出單個字符的成員函數(shù)put。v如: cout.put(a);v 或: cout.put(65+32);v可以在一個語句中連續(xù)調(diào)用put函數(shù)。如cout.put(71).put(79).pu(79).put(68).put(n);調(diào)用該函數(shù)的結(jié)果:a調(diào)用該函數(shù)的結(jié)果:GOODASCII碼碼v例1
20、3.4 有一個字符串BASIC,要求把它們按相反的順序輸出。#include using namespace std;int main( )char *a=BASIC;/字符指針指向B for(int i=4;i=0;i-) cout.put(*(a+i); /從最后一個字符開始輸出 cout.put(n); return 0;運行結(jié)果為:CISABv例13.4也可以改用putchar函數(shù)實現(xiàn)。#include /也可以用#include ,同時不要下一行using namespace std;int main( )char *a=BASIC; for(int i=4;i=0;i-) putc
21、har(*(a+i); putchar(n);運行結(jié)果為:CISAB13.3 標(biāo)準(zhǔn)輸入流標(biāo)準(zhǔn)輸入流是從標(biāo)準(zhǔn)輸入設(shè)備(鍵盤)流向程序(內(nèi)存)的數(shù)據(jù)。注意: 只有在輸入完數(shù)據(jù)再按回車鍵后,該行數(shù)據(jù)才被送入鍵盤緩沖區(qū),形成輸入流,提取運算符“”才能從中提取數(shù)據(jù)。 13.3.1 cin流cin是istream類的對象,它從標(biāo)準(zhǔn)輸入設(shè)備(鍵盤)獲取數(shù)據(jù);程序中的變量通過流提取符“”從流中提取數(shù)據(jù)。流提取符“”從流中提取數(shù)據(jù)時通常跳過輸入流中的空格、tab鍵、換行符等空白字符。例13.5 通過測試cin的真值,判斷流對象是否處于正常狀態(tài)。#include using namespace std;int m
22、ain( )float grade; coutgrade)/能從cin流讀取數(shù)據(jù)if(grade=85) coutgradeGOOD!endl;if(grade60) coutgradefail!endl;coutenter grade:; coutThe end.”提取100。賦給grade,進(jìn)行if語句的處理。然后,再遇到“/”,認(rèn)為是無效字符,cin返回0。循環(huán)結(jié)束,輸出“The end”在不同的C+系統(tǒng)下運行此程序,在最后的處理上有些不同。以上是在GCC環(huán)境下運行程序的結(jié)果,如果在VC+環(huán)境下運行此程序,在鍵入Ctrl+Z時,程序運行馬上結(jié)束,不輸出The end.。 13.3.2 用
23、于字符輸入的流成員函數(shù) 1. 用get函數(shù)讀入一個字符v 流成員函數(shù)get有3種形式:l 無參數(shù)的l 有一個參數(shù)的l 有3個參數(shù)的。 (1) 不帶參數(shù)的get函數(shù)v其調(diào)用形式為 cin.get() 用來從指定的輸入流中提取一個字符,函數(shù)的返回值就是讀入的字符。若遇到輸入流中的文件結(jié)束符,則函數(shù)值返回文件結(jié)束標(biāo)志EOF (End Of File) 。v例13.6 用get函數(shù)讀入字符。#include int main( ) int c; coutenter a sentence:endl; while(c=cin.get()!=EOF) cout.put(c); return 0;運行結(jié)果為:
24、enter a sentence:I study C+ very hard. (輸入一行字符)I study C+ very hard. (輸出該行字符)Z (程序結(jié)束)與C語言中的getchar函數(shù)功能相同 (2) 有一個參數(shù)的get函數(shù)v 其調(diào)用形式為 cin.get(ch) 其作用是從輸入流中讀取一個字符,賦給字符變量ch。如果讀取成功則函數(shù)返回非0值(真),如失敗(遇文件結(jié)束符) 則函數(shù)返回0值(假)。v例13.6可以改寫如下:#include int main( ) int c; coutenter a sentence:endl; while(cin.get(c) /讀取一個字符賦
25、給字符變量c,如果讀取成功,cin.get(c)為真 cout.put(c); coutendendl;return 0; (3) 有3個參數(shù)的get函數(shù)v 其調(diào)用形式為 cin.get(字符數(shù)組,字符個數(shù)n,終止字符) 或 cin.get(字符指針,字符個數(shù)n,終止字符) 其作用是從輸入流中讀取n-1個字符,賦給指定的字符數(shù)組(或字符指針指向的數(shù)組),如果在讀取n-1個字符之前遇到指定的終止字符,則提前結(jié)束讀取。如果讀取成功則函數(shù)返回非0值(真),如失敗(遇文件結(jié)束符) 則函數(shù)返回0值(假)。v 再將例13.6改寫如下: #include using namespace std;int ma
26、in( ) char ch20; coutenter a sentence:endl; cin.get(ch,10,n); /指定換行符為終止字符 coutchendl; return 0; 運行結(jié)果為:enter a sentence:I study C+ very hard.I study Cget函數(shù)中第3個參數(shù)可以省寫,此時默認(rèn)為n。下面兩行等價: cin.get(ch,10,n);cin.get(ch,10);終止字符也可以用其他字符。如cin.get(ch,10,x); 2. 用成員函數(shù)getline函數(shù)讀入一行字符 getline函數(shù)的作用是從輸入流中讀取一行字符,其用法與帶3個
27、參數(shù)的get函數(shù)類似。即v cin.getline(字符數(shù)組,字符個數(shù)n,終止標(biāo)志字符)或cin.getline(字符指針,字符個數(shù)n,終止標(biāo)志字符)v例13.7 用getline函數(shù)讀入一行字符。#include using namespace std;int main( ) char ch20; coutenter a sentence:ch; coutThe string read with cin is:chendl; cin.getline(ch,20,/); /讀19個字符或遇/結(jié)束 coutThe second part is:chendl; cin.getline(ch,20)
28、; /讀19個字符或遇/n結(jié)束 coutThe third part is:chendl; return 0;運行結(jié)果為:enter a sentence: I like C+./I study C+./I am happy.The string read with cin is:IThe second part is: like C+.The third part is:I study C+./I am h13.3.3 istream類的其他成員函數(shù)v 常用的有以下幾種: l 1. eof 函數(shù)l 2. peek函數(shù)l 3. putback函數(shù)l 4. ignore函數(shù) v 1. eof 函
29、數(shù)l eof是end of file的縮寫,表示“文件結(jié)束”。從輸入流讀取數(shù)據(jù),如果到達(dá)文件末尾(遇文件結(jié)束符),eof函數(shù)值為非零值(表示真),否則為0(假)。#include using namespace std;int main( )char c; while(!cin.eof( ) /eof( )為假表示未遇到文件結(jié)束符if(c=cin.get( )!= ) /檢查讀入的字符是否為空格字符 cout.put(c); return 0;例例13.8 逐個讀入一行字符,將其逐個讀入一行字符,將其中的非空格字符輸出。中的非空格字符輸出。運行結(jié)果為:C+ is very interestin
30、g.C+isveryinteresting.Z(結(jié)束)v 2. peek函數(shù)l peek是“觀察”的意思,peek函數(shù)的作用是觀測下一個字符。其調(diào)用形式為c=cin.peek( );cin.peek 函數(shù)的返回值是指針指向的當(dāng)前字符,但它只是觀測,指針仍停留在當(dāng)前位置,并不后移。如果要訪問的字符是文件結(jié)束符,則函數(shù)值是EOF(-1)。v 3. putback函數(shù)l 其調(diào)用形式為cin.putback(ch); 其作用是將前面用get或getline函數(shù)從輸入流中讀取的字符ch返回到輸入流,插入到當(dāng)前指針位置,以供后面讀取。例13.9 peek函數(shù)和putback函數(shù)的用法。#include u
31、sing namespace std;int main( )char c20; int ch; coutplease enter a sentence:endl; cin.getline(c,15,/); coutThe first part is:cendl;ch=cin.peek( ); /觀看當(dāng)前字符 coutThe next character(ASCII code) is:chendl; cin.putback(c0); /將I插入到指針?biāo)柑?cin.getline(c,15,/); coutThe second part is:cendl; return 0;運行結(jié)果為:plea
32、se enter a sentence: I am a boy./ am a student./The first part is:I am a boy.The next character(ASCII code) is:32 (下一個字符是空格)The second part is:I am a studentv 4. ignore函數(shù)l 其調(diào)用形式為 cin,ignore(n, 終止字符) 函數(shù)作用是跳過輸入流中n個字符,或在遇到指定的終止字符時提前結(jié)束(此時跳過包括終止字符在內(nèi)的若干字符)。如:ignore(5, A) /跳過輸入流中5個字符,遇A后就不再跳了也可以不帶參數(shù)或只帶一個參數(shù)
33、。如ignore( )ignore(1,EOF)(n默認(rèn)值為1,終止字符默認(rèn)為EOF)例13.10用ignore函數(shù)跳過輸入流中的字符。#include using namespace std;int main( ) char ch20; cin.get(ch,20,/); coutThe first part is:chendl; cin.get(ch,20,/); coutThe second part is:chendl; return 0;運行結(jié)果為:I like C+./I study C+./I am happy. The first part is:I like C+.The s
34、econd part is:(字符數(shù)組字符數(shù)組ch中沒有從輸入流中讀取有效字符中沒有從輸入流中讀取有效字符)先看不用先看不用ignore函數(shù)的情況函數(shù)的情況: 如果希望第二個cin.get函數(shù)能讀取I study C+.,就應(yīng)該設(shè)法跳過輸入流中第一個/,可以用ignore函數(shù)來實現(xiàn)此目的。#include using namespace std;int main( ) char ch20; cin.get(ch,20,/); coutThe first part is:chendl; cin.ignore( );/跳過輸入流中一個字符跳過輸入流中一個字符 cin.get(ch,20,/); c
35、outThe second part is:chendl; return 0;運行結(jié)果為:I like C+./I study C+./I am happy. The first part is:I like C+.The second part is:I study C+.用ignore函數(shù)將程序改為:13.4 文件操作與文件流 13.4.1 文件的概念 所謂“文件”,一般指存儲在外部介質(zhì)上數(shù)據(jù)的集合。一批數(shù)據(jù)是以文件的形式存放在外部介質(zhì)上的。操作系統(tǒng)是以文件為單位對數(shù)據(jù)進(jìn)行管理的。要向外部介質(zhì)上存儲數(shù)據(jù)也必須先建立一個文件(以文件名標(biāo)識),才能向它輸出數(shù)據(jù)。FileFile 外存文件包括磁
36、盤文件、光盤文件和U盤文件。目前使用最廣泛的是磁盤文件。對用戶來說,常用到的文件有兩大類v 一類是程序文件(program file)。v 一類是數(shù)據(jù)文件(data file)。l 程序中的輸入和輸出的對象就是數(shù)據(jù)文件。根據(jù)文件中數(shù)據(jù)的組織形式,可分為ASCII文件和二進(jìn)制文件。例:長整型數(shù)100000 的表示 13.4.2 文件流類與文件流對象文件流是以外存文件為輸入輸出對象的數(shù)據(jù)流。v輸出文件流是從內(nèi)存流向外存文件的數(shù)據(jù),v輸入文件流是從外存文件流向內(nèi)存的數(shù)據(jù)。v每一個文件流都有一個內(nèi)存緩沖區(qū)與之對應(yīng)。文件流與文件:v文件流本身不是文件,而只是以文件為輸入輸出對象的流。若要對磁盤文件輸入輸
37、出,就必須通過文件流來實現(xiàn)。在C+的I/O類庫中定義了幾種文件類,專門用于對磁盤文件的輸入輸出操作。除istream,ostream和iostream類外,還有3個用于文件操作的文件類:vifstream類l它是從istream類派生的。 用來支持從磁盤文件的輸入。vofstream類l它是從ostream類派生的。 用來支持向磁盤文件的輸出。vfstream類l它是從iostream類派生的。 用來支持對磁盤文件的輸入輸出。在用標(biāo)準(zhǔn)設(shè)備為對象的輸入輸出中,cin,cout是流對象,不需要用戶自己定義。在用磁盤文件時,由于情況各異,無法事先統(tǒng)一定義,必須由用戶自己定義,通過文件流對象(而不是c
38、in和cout)實現(xiàn)的,文件流對象是用文件流類定義的。可以用下面的方法建立一個輸出文件流對象: 現(xiàn)在在程序中定義了outfile為ofstream類(輸出文件流類)的對象。但是有一個問題還未解決: 在定義cout時已將它和標(biāo)準(zhǔn)輸出設(shè)備建立關(guān)聯(lián),而現(xiàn)在雖然建立了一個輸出文件流對象,但是還未指定它向哪一個磁盤文件輸出,需要在使用時加以指定。ofstream outfile; 13.4.3 文件的打開與關(guān)閉 1. 打開磁盤文件v打開文件是指在文件讀寫之前做必要的準(zhǔn)備工作,包括: l(1) 為文件流對象和指定的磁盤文件建立關(guān)聯(lián),以便使文件流流向指定的磁盤文件。l(2) 指定文件的工作方式。 以上工作可
39、以通過兩種不同的方法實現(xiàn)。v(1) 調(diào)用文件流的成員函數(shù)open。如ofstream outfile;/定義ofstream類(輸出文件流類)對象outfileoutfile.open(f1.dat,ios:out); /使文件流與f1.dat文件建立關(guān)聯(lián)調(diào)用成員函數(shù)open的一般形式為文件流對象.open(磁盤文件名,輸入輸出方式);磁盤文件名可以包括路徑,如c:newf1.dat,如缺省路徑,則默認(rèn)為當(dāng)前目錄下的文件。 (2) 在定義文件流對象時指定參數(shù)在聲明文件流類時定義了帶參數(shù)的構(gòu)造函數(shù),其中包含了打開磁盤文件的功能。因此,可以在定義文件流對象時指定參數(shù),調(diào)用文件流類的構(gòu)造函數(shù)來實現(xiàn)打
40、開文件的功能。如 ostream outfile(f1.dat,ios:out);一般多用此形式,比較方便。作用與open函數(shù)相同。輸入輸出方式是在ios類中定義的,它們是枚舉常量,有多種選擇,見書中表13.6。 2. 關(guān)閉磁盤文件在對已打開的磁盤文件的讀寫操作完成后,應(yīng)關(guān)閉該文件。關(guān)閉文件用成員函數(shù)close。如 outfile.close( );/將輸出文件流所關(guān)聯(lián)的磁盤文件關(guān)閉所謂關(guān)閉,實際上是解除該磁盤文件與文件流的關(guān)聯(lián),原來設(shè)置的工作方式也失效,這樣,就不能再通過文件流對該文件進(jìn)行輸入或輸出。此時可以將文件流與其他磁盤文件建立關(guān)聯(lián),通過文件流對新的文件進(jìn)行輸入或輸出。如 outfil
41、e.open(f2.dat,ios:app|ios:nocreate);此時文件流outfile與f2.dat建立關(guān)聯(lián),并指定了f2.dat的工作方式。 13.4.4 對ASCII文件的操作 如果文件的每一個字節(jié)中均以ASCII代碼形式存放數(shù)據(jù),即一個字節(jié)存放一個字符,這個文件就是ASCII文件(或稱字符文件)。327675個字符占個字符占5個字節(jié)個字節(jié)每個字符一個字節(jié)每個字符一個字節(jié)程序可以從ASCII文件中讀入若干個字符,也可以向它輸出一些字符。對ASCII文件的讀寫操作可以用以下兩種方法: v(1) 用流插入運算符“”輸入輸出標(biāo)準(zhǔn)類型的數(shù)據(jù)。v(2) 用文件流的put,get,geili
42、ne等成員函數(shù)進(jìn)行字符的輸入輸出。例13.11 有一個整型數(shù)組,含10個元素,從鍵盤輸入10個整數(shù)給數(shù)組,將此數(shù)組送到磁盤文件中存放。#include using namespace std;int main( )int a10; ofstream outfile(f1.dat,ios:out);/定義文件流對象,打開磁盤文件f1.dat if(!outfile) /如果打開失敗,outfile返回0值 cerropen error!endl; exit(1); coutenter 10 integer numbers:endl; for(int i=0;iai; outfileai ; /向
43、磁盤文件f1.dat輸出數(shù)據(jù) outfile.close(); /關(guān)閉磁盤文件f1.dat return 0;運行結(jié)果為:enter 10 integer numbers:1 3 5 2 4 6 10 8 7 9 例13.12 從例13.11建立的數(shù)據(jù)文件f1.dat中讀入10個整數(shù)放在數(shù)組中,找出并輸出10個數(shù)中的最大者和它在數(shù)組中的序號。#include int main( )int a10,max,i,order; ifstream infile(f1.dat,ios:in|ios:nocreate);/定義輸入文件流對象,以輸入方式打開磁盤文件f1.dat if(!infile) ce
44、rropen error!endl; exit(1); for(i=0;iai;/從磁盤文件讀入10個整數(shù), 順序存放在a數(shù)組中 coutai ; /在顯示器上順序顯示10個數(shù) coutendl; max=a0;order=0; for(i=1;imax) max=ai; /將當(dāng)前最大值放在max中 order=i; /將當(dāng)前最大值的元素序號放在order中 coutmax=maxendlorder=orderendl; infile.close(); return 0;運行結(jié)果為:1 3 5 2 4 6 10 8 7 9(在磁盤文件中存放的10個數(shù))max=10 (最大值為10)order=
45、6 (最大值是數(shù)組中序號為6的元素)#include using namespace std;void save_to_file( );void get_from_file( );int main( )save_to_file( ); /調(diào)用save_to_file( ),從鍵盤讀入一行字符并將其中的字母存入磁盤文件f2.datget_from_file( ); /調(diào)用get_from_file(),從f2.dat讀入字母字符,改為大寫字母,再存入f3.dat return 0;例13.13 從鍵盤讀入一行字符,把其中的字母字符依次存放在磁盤文件f2.dat中。再把它從磁盤文件讀入程序,將其中
46、的小寫字母改為大寫字母,再存入磁盤文件f3.dat。/ save_to_file函數(shù)從鍵盤讀入一行字函數(shù)從鍵盤讀入一行字符,并將其中的字母存入磁盤文件符,并將其中的字母存入磁盤文件void save_to_file( )ofstream outfile(f2.dat); /定義輸出文件流對象outfile,以輸出方式打開磁盤文件f2.datif(!outfile) cerropen f2.dat error!=65 & ci=97 & ci=122) /如果是字母字符outfile.put(ci); /將字母字符存入磁盤文件f2.datcoutci; /同時送顯示器顯示 cou
47、tendl; outfile.close(); /關(guān)閉f2.datsave_to_file( )/從磁盤文件f2.dat讀入字母字符,將其中的小寫字母改為大寫字母,再存入f3.datvoid get_from_file()char ch; ifstream infile(f2.dat,ios:in|ios:nocreate); /定義輸入文件流outfile,以輸入方式打開磁盤文件f2.dat if(!infile) cerropen f2.dat error!endl; exit(1); ofstream outfile(f3.dat); /定義輸出文件流outfile,以輸出方式打開磁盤文
48、件f3.dat if(!outfile) cerropen f3.dat error!=97 & ch=122) /判斷ch是否為小寫字母ch=ch-32; /將小寫字母變?yōu)榇髮懽帜?outfile.put(ch); /將該大寫字母存入磁盤文件f3.dat coutch; /同時在顯示器輸出 coutTYPE f3.dat (假設(shè)當(dāng)前目錄是D:C+ )在顯示屏上會輸出NEWBEIJINGGREATOLYPICCHINA如果用GCC編譯環(huán)境,可選擇File菜單中的DOS Shell菜單項,即可進(jìn)入DOS環(huán)境。想從DOS返回GCC主窗口,從鍵盤輸入exit即可。 (2) 編一程序?qū)⒋疟P文件
49、內(nèi)容讀入內(nèi)存,然后輸出到顯示器。可以編一個專用函數(shù)。#include using namespace std;void (char *filename)ifstream infile(filename,ios:in|ios:nocreate); if(!infile) cerropen error!endl; exit(1); char ch; while(infile.get(ch)cout.put(ch); coutendl; infile.close();然后在調(diào)用時給出文件名即可: int main( )(f3.dat); /將f3.dat的入口地址傳給形參filename retur
50、n 0;運行時輸出運行時輸出f3.dat中的字符中的字符: NEWBEIJINGGREATOLYPICCHINA 13.4.5 對二進(jìn)制文件的操作二進(jìn)制文件v 又稱為字節(jié)文件。v 占用的字節(jié)數(shù)由數(shù)據(jù)類型決定v 例如:0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12個字節(jié)個字節(jié) 1. 用成員函數(shù)read和write讀寫二進(jìn)制文件v對二進(jìn)制文件的讀寫主要用istream類的成員函數(shù)read和write來實現(xiàn)。這兩個成員函數(shù)的原型為 istream& read(char *buffer,int len);ostream& write(const char * buff
51、er,int len);字符指針buffer指向內(nèi)存中一段存儲空間。len是讀寫的字節(jié)數(shù)。調(diào)用的方式為-a. write(p1,50);b. read(p2,30);例13.14 將一批數(shù)據(jù)以二進(jìn)制形式存放在磁盤文件中。#include using namespace std;struct studentchar name20; int num; int age; char sex;int main( )student stud3=Li,1001,18,f,Fun,1002,19,m,Wang,1004,17,f; ofstream outfile(stud.dat,ios:binary);
52、if(!outfile) cerropen error!endl; abort( );/退出程序 for(int i=0;i3;i+) outfile.write(char*)&studi,sizeof(studi); outfile.close( );return 0;可一次輸出結(jié)構(gòu)體數(shù)組的3個元素,將for循環(huán)的兩行改為以下一行:outfile.write(char*)&stud0,sizeof(stud);執(zhí)行一次write函數(shù)即輸出了結(jié)構(gòu)體數(shù)組的全部數(shù)據(jù)。例13.15 將剛才以二進(jìn)制形式存放在磁盤文件中的數(shù)據(jù)讀入內(nèi)存并在顯示器上顯示。int main( )student
53、 stud3; int i; ifstream infile(stud.dat,ios:binary); if(!infile) cerropen error!endl; abort( ); for(i=0;i3;i+)infile.read(char*)&studi,sizeof(studi); infile.close( ); for(i=0;i3;i+) coutNO.i+1endl; coutname:endl; coutnum:studi.numendl; coutage:studi.ageendl; coutsex:studi.sexendlendl;
54、return 0; #include using namespace std;struct student string name; int num; int age; char sex;int main()運行時輸出運行時輸出f3.dat中的字符中的字符: NO.1name: Linum: 1001age: 18sex: fNO.2name: Funnum: 1001age: 19sex: mNO.3name: Wangnum: 1004age: 17sex: f請思考: 能否一次讀入文件中的全部數(shù)據(jù)?如infile.read(char*)&stud0,sizeof(stud); 2
55、. 與文件指針有關(guān)的流成員函數(shù)在磁盤文件中有一個文件指針,用來指明當(dāng)前應(yīng)進(jìn)行讀寫的位置。對于二進(jìn)制文件,允許對指針進(jìn)行控制,使它按用戶的意圖移動到所需的位置,以便在該位置上進(jìn)行讀寫。110010文件指針文件指針 *文件指針文件指針 *文件流提供一些有關(guān)文件指針的成員函數(shù)。 v(1) 這些函數(shù)名的第一個字母或最后一個字母不是g就是p,g代表輸入,p代表輸出。(參考p451)v(2) 函數(shù)參數(shù)中的“文件中的位置”和“位移量”已被指定為long型整數(shù),以字節(jié)為單位。“參照位置”可以是下面三者之一: lios:beg文件開頭(beg是begin的縮寫),這是默認(rèn)值。lios:cur指針當(dāng)前的位置(cu
56、r是current的縮寫)。lios:end文件末尾。它們是在ios類中定義的枚舉常量。e.g:infile.seekg(100); /輸入文件中的指針向前移到100字節(jié)位置infile.seekg(-50,ios:cur); /輸入文件中的指針從當(dāng)前位置后移50字節(jié)outfile.seekp(-75,ios:end); /輸出文件中的指針從文件尾后移75字節(jié) 3. 隨機訪問二進(jìn)制數(shù)據(jù)文件一般情況下讀寫是順序進(jìn)行的,即逐個字節(jié)進(jìn)行讀寫。但是對于二進(jìn)制數(shù)據(jù)文件來說,可以利用上面的成員函數(shù)移動指針,隨機地訪問文件中任一位置上的數(shù)據(jù),還可以修改文件中的內(nèi)容。 例13.16 有5個學(xué)生的數(shù)據(jù),要求:
57、v(1) 把它們存到磁盤文件中;v(2) 將磁盤文件中的第1,3,5個學(xué)生數(shù)據(jù)讀入程序,并顯示出來;v(3) 將第3個學(xué)生的數(shù)據(jù)修改后存回磁盤文件中的原有位置。v(4) 從磁盤文件讀入修改后的5個學(xué)生的數(shù)據(jù)并顯示出來。 要實現(xiàn)以上要求,需要解決3個問題: (1) 由于同一磁盤文件在程序中需要頻繁地進(jìn)行輸入和輸出,因此可將文件的工作方式指定為輸入輸出文件,即 ios:in|ios:out|ios:binary(2) 正確計算好每次訪問時指針的定位,即正確使用seekg或seekp函數(shù)。(3) 正確進(jìn)行文件中數(shù)據(jù)的重寫(更新)。可寫出以下程序: #include using namespace s
58、td;struct student int num; char name20; float score;int main()for(int i=0;i5;i+)/向磁盤文件輸出5個學(xué)生的數(shù)據(jù) iofile.write(char *)&studi,sizeof(studi); int main( )student stud5=1001,Li,85,1002,Fun,97.5,1004,Wang,54,1006,Tan,76.5,1010,ling,96; fstream iofile(stud.dat,ios:in|ios:out|ios:binary); /用fstream類定義輸入輸
59、出二進(jìn)制文件流對象iofile if(!iofile) cerropen error!endl; abort( ); student stud15; /用來存放從磁盤文件讀入的數(shù)據(jù) for(int i=0;i5;i=i+2) iofile.seekg(i*sizeof(studi),ios:beg); /定位于第0,2,4學(xué)生數(shù)據(jù)開頭 iofile.read(char *)&stud1i/2,sizeof(stud10); /先后讀入3個學(xué)生的數(shù)據(jù),存放在stud10,stud1和stud2中coutstud1i/2.num stud1i/2.name stud1i/2.scoreen
60、dl;/輸出stud10,stud1和stud2各成員的值coutendl; stud2.num=1012; /修改第3個學(xué)生(序號為2)的數(shù)據(jù) strcpy(,Wu); stud2.score=60; iofile.seekp(2*sizeof(stud0),ios:beg); /定位于第3個學(xué)生數(shù)據(jù)的開頭 iofile.write(char *)&stud2,sizeof(stud2); /更新第3個學(xué)生數(shù)據(jù) iofile.seekg(0,ios:beg); /重新定位于文件開頭for(int i=0;i5;i+) iofile.read(char *)&studi,sizeof(studi); /讀入5個學(xué)生的數(shù)據(jù) coutstudi.num
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生鮮羊肉店轉(zhuǎn)讓合同協(xié)議
- 電瓶車轉(zhuǎn)賣協(xié)議合同
- 電影股權(quán)投資合同協(xié)議
- 2025至2030年中國純棉針織服裝數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國電導(dǎo)體配件數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國片/粒狀類干燥殺菌機數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國淡水漂數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國木工單排銑床數(shù)據(jù)監(jiān)測研究報告
- 煤礦從業(yè)人員應(yīng)知應(yīng)會培訓(xùn)課件煤與瓦斯突出防治技術(shù)
- 2025至2030年中國無堿玻璃絲纖維短切絲數(shù)據(jù)監(jiān)測研究報告
- 《中國糖尿病防治指南(2024版)》解讀
- 2025年關(guān)于美發(fā)學(xué)員合同
- 糖尿病患者的足部護(hù)理
- 土地流轉(zhuǎn)合同補充協(xié)議書
- 七年級語文下冊《登幽州臺歌》課件
- 兼職勞務(wù)協(xié)議合同模板
- 2025-2030中國改性塑料市場盈利能力預(yù)測及發(fā)展機遇規(guī)模研究報告
- 2025全國國家版圖知識競賽題庫及答案(300題)中小學(xué)組試題及答案
- 2025年河南機電職業(yè)學(xué)院高職單招語文2019-2024歷年真題考點試卷含答案解析
- 《旅行社經(jīng)營與管理》電子教案 5-1 旅行社接待業(yè)務(wù)1
- (二模)東北三省三校2025年高三第二次聯(lián)合模擬考試 英語試卷(含答案解析)
評論
0/150
提交評論