国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

詳解C++編程中的文件流與字符串流

2020-05-23 14:13:55
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

這篇文章主要介紹了C++編程中的文件流與字符串流,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下

C++文件流類(lèi)與文件流對(duì)象

文件流是以外存文件為輸入輸出對(duì)象的數(shù)據(jù)流。輸出文件流是從內(nèi)存流向外存文件的數(shù)據(jù),輸入文件流是從外存文件流向內(nèi)存的數(shù)據(jù)。每一個(gè)文件流都有一個(gè)內(nèi)存緩沖區(qū)與之對(duì)應(yīng)。

請(qǐng)區(qū)分文件流與文件的概念,不用誤以為文件流是由若干個(gè)文件組成的流。文件流本身不是文件,而只是以文件為輸入輸出對(duì)象的流。若要對(duì)磁盤(pán)文件輸入輸出,就必須通過(guò)文件流來(lái)實(shí)現(xiàn)。

在C++的I/O類(lèi)庫(kù)中定義了幾種文件類(lèi),專(zhuān)門(mén)用于對(duì)磁盤(pán)文件的輸入輸出操作。

除了標(biāo)準(zhǔn)輸入輸出流類(lèi)istream、ostream和iostream類(lèi)外,還有3個(gè)用于文件操作的文件類(lèi):

ifstream類(lèi),它是從istream類(lèi)派生的,用來(lái)支持從磁盤(pán)文件的輸入。

ofstream類(lèi),它是從ostream類(lèi)派生的,用來(lái)支持向磁盤(pán)文件的輸出。

fstream類(lèi),它是從iostream類(lèi)派生的,用來(lái)支持對(duì)磁盤(pán)文件的輸入輸出。

要以磁盤(pán)文件為對(duì)象進(jìn)行輸入輸出,必須定義一個(gè)文件流類(lèi)的對(duì)象,通過(guò)文件流對(duì)象將數(shù)據(jù)從內(nèi)存輸出到磁盤(pán)文件,或者通過(guò)文件流對(duì)象從磁盤(pán)文件將數(shù)據(jù)輸入到內(nèi)存。

其實(shí)在用標(biāo)準(zhǔn)設(shè)備為對(duì)象的輸入輸出中,也是要定義流對(duì)象的,如cin、cout就是流對(duì)象,C++是通過(guò)流對(duì)象進(jìn)行輸入輸出的。由于cin、cout已在iostream.h中事先定義,所以用戶不需自己定義。在用磁盤(pán)文件時(shí),由于情況各異,無(wú)法事先統(tǒng)一定義,必須由用戶自己定義。此外,對(duì)磁盤(pán)文件的操作是通過(guò)文件流對(duì)象(而不是cin和cout)實(shí)現(xiàn)的。文件流對(duì)象是用文件流類(lèi)定義的,而不是用istream和ostream類(lèi)來(lái)定義的。可以用下面的方法建立一個(gè)輸出文件流對(duì)象:

 

 
  1. ofstream outfile; 

如同在頭文件iostream中定義了流對(duì)象cout —樣,現(xiàn)在在程序中定義了outfile為 ofstream類(lèi)(輸出文件流類(lèi))的對(duì)象。但是有一個(gè)問(wèn)埋還未解決:在定義 cout 時(shí)已將它和標(biāo)準(zhǔn)輸出設(shè)備(顯示器)建立關(guān)聯(lián),而現(xiàn)在雖然建立了一個(gè)輸出文件流對(duì)象,但是還未指定它向哪一個(gè)磁盤(pán)文件輸出,需要在使用時(shí)加以指定。

C++對(duì)字符串流的讀寫(xiě)

文件流是以外存文件為輸入輸出對(duì)象的數(shù)據(jù)流,字符串流不是以外存文件為輸入輸出的對(duì)象,而以內(nèi)存中用戶定義的字符數(shù)組(字符串)為輸入輸出的對(duì)象,即將數(shù)據(jù)輸出到內(nèi)存中的字符數(shù)組,或者從字符數(shù)組(字符串)將數(shù)據(jù)讀入。字符串流也稱為內(nèi)存流。

字符串流也有相應(yīng)的緩沖區(qū),開(kāi)始時(shí)流緩沖區(qū)是空的。如果向字符數(shù)組存入數(shù)據(jù),隨著向流插入數(shù)據(jù),流緩沖區(qū)中的數(shù)據(jù)不斷增加,待緩沖區(qū)滿了(或遇換行符),一起存入字符數(shù)組。如果是從字符數(shù)組讀數(shù)據(jù),先將字符數(shù)組中的數(shù)據(jù)送到流緩沖區(qū),然后從緩沖區(qū)中提取數(shù)據(jù)賦給有關(guān)變量。

在字符數(shù)組中可以存放字符,也可以存放整數(shù)、浮點(diǎn)數(shù)以及其他類(lèi)型的數(shù)據(jù)。在向字符數(shù)組存入數(shù)據(jù)之前,要先將數(shù)據(jù)從二進(jìn)制形式轉(zhuǎn)換為ASCII代碼,然后存放在緩沖區(qū), 再?gòu)木彌_區(qū)送到字符數(shù)組。從字符數(shù)組讀數(shù)據(jù)時(shí),先將字符數(shù)組中的數(shù)據(jù)送到緩沖區(qū),在賦給變量前要先將ASCII代碼轉(zhuǎn)換為二進(jìn)制形式。總之,流緩沖區(qū)中的數(shù)據(jù)格式與字符數(shù)組相同。這種情況與以標(biāo)準(zhǔn)設(shè)備(鍵盤(pán)和顯示器)為對(duì)象的輸入輸出是類(lèi)似的,鍵盤(pán)和顯示器都是按字符形式輸入輸出的設(shè)備,內(nèi)存中的數(shù)據(jù)在輸出到顯示器之前,先要轉(zhuǎn)換為 ASCII碼形式,并送到輸出緩沖區(qū)中。從鍵盤(pán)輸入的數(shù)據(jù)以ASCII碼形式輸入到輸入緩沖區(qū),在賦給變量前轉(zhuǎn)換為相應(yīng)變量類(lèi)型的二進(jìn)制形式,然后賦給變量。對(duì)于字符串流的輸入輸出的情況,如不清楚,可以從對(duì)標(biāo)準(zhǔn)設(shè)備的輸入輸出中得到啟發(fā)。

文件流類(lèi)有ifstream,ofstream和fstream,而字符串流類(lèi)有istrstream,ostrstream和strstream。文件流類(lèi)和字符串流類(lèi)都是ostream,istream和iostream類(lèi)的派生類(lèi),因此對(duì)它們的操作方法是基本相同的。向內(nèi)存中的一個(gè)字符數(shù)組寫(xiě)數(shù)據(jù)就如同向文件寫(xiě)數(shù)據(jù)一樣,但有3點(diǎn)不同:

輸出時(shí)數(shù)據(jù)不是流向外存文件,而是流向內(nèi)存中的一個(gè)存儲(chǔ)空間。輸入時(shí)從內(nèi)存中的存儲(chǔ)空間讀取數(shù)據(jù)。在嚴(yán)格的意義上說(shuō),這不屬于輸入輸出,稱為讀寫(xiě)比較合適。 因?yàn)檩斎胼敵鲆话阒傅氖窃谟?jì)算機(jī)內(nèi)存與計(jì)算機(jī)外的文件(外部設(shè)備也視為文件)之間 的數(shù)據(jù)傳送。但由于C++的字符串流采用了 C++的流輸入輸出機(jī)制,因此往往也用輸入和輸出來(lái)表述讀寫(xiě)操作。

字符串流對(duì)象關(guān)聯(lián)的不是文件,而是內(nèi)存中的一個(gè)字符數(shù)組,因此不需要打開(kāi)和關(guān)閉文件。

每個(gè)文件的最后都有一個(gè)文件結(jié)束符,表示文件的結(jié)束。而字符串流所關(guān)聯(lián)的字符數(shù)組中沒(méi)有相應(yīng)的結(jié)束標(biāo)志,用戶要指定一個(gè)特殊字符作為結(jié)束符,在向字符數(shù)組寫(xiě)入全部數(shù)據(jù)后要寫(xiě)入此字符。

字符串流類(lèi)沒(méi)有open成員函數(shù),因此要在建立字符串流對(duì)象時(shí)通過(guò)給定參數(shù)來(lái)確立字符串流與字符數(shù)組的關(guān)聯(lián)。即通過(guò)調(diào)用構(gòu)造函數(shù)來(lái)解決此問(wèn)題。建立字符串流對(duì)象的方法與含義如下。

建立輸出字符串流對(duì)象

ostrstream類(lèi)提供的構(gòu)造函數(shù)的原型為:

 

 
  1. ostrstream::ostrstream(char *buffer,int n,int mode=ios::out); 

buffer是指向字符數(shù)組首元素的指針,n為指定的流緩沖區(qū)的大小(一般選與字符數(shù)組的大小相同,也可以不同),第3個(gè)參數(shù)是可選的,默認(rèn)為ios::out方式。可以用以下語(yǔ)句建立輸出字符串流對(duì)象并與字符數(shù)組建立關(guān)聯(lián):

 

 
  1. ostrstream strout(ch1,20); 

作用是建立輸出字符串流對(duì)象strout,并使strout與字符數(shù)組ch1關(guān)聯(lián)(通過(guò)字符串流將數(shù)據(jù)輸出到字符數(shù)組ch1),流緩沖區(qū)大小為20。

建立輸入字符串流對(duì)象

istrstream類(lèi)提供了兩個(gè)帶參的構(gòu)造函數(shù),原型為:

 

 
  1. istrstream::istrstream(char *buffer); 
  2. istrstream::istrstream(char *buffer,int n); 

buffer是指向字符數(shù)組首元素的指針,用它來(lái)初始化流對(duì)象(使流對(duì)象與字符數(shù)組建立關(guān)聯(lián))。可以用以下語(yǔ)句建立輸入字符串流對(duì)象:

 

 
  1. istrstream strin(ch2); 

作用是建立輸入字符串流對(duì)象strin,將字符數(shù)組ch2中的全部數(shù)據(jù)作為輸入字符串流的內(nèi)容。

 

 
  1. istrstream strin(ch2,20); 

流緩沖區(qū)大小為20,因此只將字符數(shù)組ch2中的,20個(gè)字符作為輸入字符串流的內(nèi)容。

建立輸入輸出字符串流對(duì)象

strstream類(lèi)提供的構(gòu)造函數(shù)的原型為:

 

 
  1. strstream::strstream(char *buffer,int n,int mode); 

可以用以下語(yǔ)句建立輸入輸出字符串流對(duì)象:

 

 
  1. strstream strio(ch3,sizeof(ch3),ios::in|ios::out); 

作用是建立輸入輸出字符串流對(duì)象,以字符數(shù)組ch3為輸入輸出對(duì)象,流緩沖區(qū)大小與數(shù)組ch3相同。

以上個(gè)字符串流類(lèi)是在頭文件strstream中定義的,因此程序中在用到istrstream、ostrstream和strstream類(lèi)時(shí)應(yīng)包含頭文件strstream(在GCC中,用頭文件strstream)。

[例] 將一組數(shù)據(jù)保存在字符數(shù)組中。

 

 
  1. #include <strstream> 
  2. using namespace std; 
  3. struct student 
  4. int num; 
  5. char name[20]; 
  6. float score; 
  7. }; 
  8. int main( ) 
  9. student stud[3]={1001,"Li",78,1002,"Wang",89.5,1004,"Fun",90}; 
  10. char c[50]; //用戶定義的字符數(shù)組 
  11. ostrstream strout(c,30); //建立輸出字符串流,與數(shù)組c建立關(guān)聯(lián),緩沖區(qū)長(zhǎng) 
  12. for(int i=0;i<3;i++) //向字符數(shù)組c寫(xiě)個(gè)學(xué)生的數(shù)據(jù) 
  13. strout<<stud[i].num<<stud[i].name<<stud[i].score; 
  14. strout<<ends; //ends是C++的I/O操作符,插入一個(gè)'//0' 
  15. cout<<"array c:"<<c<<endl; //顯示字符數(shù)組c中的字符 

運(yùn)行時(shí)在顯示器上的輸出如下:

 

 
  1. array c: 
  2. 1001Li781002Wang89.51004Fun90 

以上就是字符數(shù)組c中的字符。可以看到:

1) 字符數(shù)組c中的數(shù)據(jù)全部是以ASCII代碼形式存放的字符,而不是以二進(jìn)制形式表示的數(shù)據(jù)。

2) 在建立字符串流strout時(shí)指定流緩沖區(qū)大小為30字節(jié),與字符數(shù)組c的大小不同,這是允許的,這時(shí)字符串流最多可以傳送30個(gè)字符給字符數(shù)組c。請(qǐng)思考:如果將流 緩沖區(qū)大小改為10字節(jié),即:

 

 
  1. ostrstream.strout( c ,10); 

運(yùn)行情況會(huì)怎樣?流緩沖區(qū)只能存放10個(gè)字符,將這10個(gè)字符寫(xiě)到字符數(shù)組c中。運(yùn)行時(shí)顯示的結(jié)果是:

 

 
  1. 1001Li7810 

字符數(shù)組c中只有10個(gè)有效字符。一般都把流緩沖區(qū)的大小指定與字符數(shù)組的大小 相同。

3) 字符數(shù)組c中的數(shù)據(jù)之間沒(méi)有空格,連成一片,這是由輸出的方式?jīng)Q定的。如果以后想將這些數(shù)據(jù)讀回賦給程序中相應(yīng)的變量,就會(huì)出現(xiàn)問(wèn)題,因?yàn)闊o(wú)法分隔兩個(gè)相鄰的數(shù)據(jù)。為解決此問(wèn)題,可在輸出時(shí)人為地加入空格。如

 

 
  1. for(int i=0;i<3;i++) 
  2. strout<<" "<<stud[i].num<<" "<<stud[i].name<<" "<<stud[i].score; 

同時(shí)應(yīng)修改流緩沖區(qū)的大小,以便能容納全部?jī)?nèi)容,今改為字節(jié)。這樣,運(yùn)行時(shí)將輸出:

 

 
  1. 1001 Li 78 1002 Wang 89.5 1004 Fun 90 

再讀入時(shí)就能清楚地將數(shù)據(jù)分隔開(kāi)。

[例] 在一個(gè)字符數(shù)組c中存放了個(gè)整數(shù),以空格相間隔,要求將它們放到整型數(shù)組中,再按大小排序,然后再存放回字符數(shù)組c中。

 

 
  1. #include <strstream> 
  2. using namespace std; 
  3. int main( ) 
  4. char c[50]="12 34 65 -23 -32 33 61 99 321 32"
  5. int a[10],i,j,t; 
  6. cout<<"array c:"<<c<<endl; //顯示字符數(shù)組中的字符串 
  7. istrstream strin(c,sizeof(c)); //建立輸入串流對(duì)象strin并與字符數(shù)組c關(guān)聯(lián) 
  8. for(i=0;i<10;i++) 
  9. strin>>a[i]; //從字符數(shù)組c讀入個(gè)整數(shù)賦給整型數(shù)組a 
  10. cout<<"array a:"
  11. for(i=0;i<10;i++) 
  12. cout<<a[i]<<" "//顯示整型數(shù)組a各元素 
  13. cout<<endl; 
  14. for(i=0;i<9;i++) //用起泡法對(duì)數(shù)組a排序 
  15. for(j=0;j<9-i;j++) 
  16. if(a[j]>a[j+1]) 
  17. {t=a[j];a[j]=a[j+1];a[j+1]=t;} 
  18. ostrstream strout(c,sizeof(c)); //建立輸出串流對(duì)象strout并與字符數(shù)組c關(guān)聯(lián) 
  19. for(i=0;i<10;i++) 
  20. strout<<a[i]<<" "//將個(gè)整數(shù)存放在字符數(shù)組c 
  21. strout<<ends; //加入'//0' 
  22. cout<<"array c:"<<c<<endl; //顯示字符數(shù)組c 
  23. return 0; 

運(yùn)行結(jié)果如下:

 

 
  1. array c: 12 34 65 -23 -32 33 61 99 321 32(字符數(shù)組c原來(lái)的內(nèi)容) 
  2. array a: 12 34 65 -23 -32 33 61 99 321 32 (整型數(shù)組a的內(nèi)容) 
  3. array c: -32 –12 32 33 34 61 65 99 321 (字符數(shù)組c最后的內(nèi)容) 

對(duì)字符串流的幾點(diǎn)說(shuō)明:

1) 用字符串流時(shí)不需要打開(kāi)和關(guān)閉文件。

2) 通過(guò)字符串流從字符數(shù)組讀數(shù)據(jù)就如同從鍵盤(pán)讀數(shù)據(jù)一樣,可以從字符數(shù)組讀入字符數(shù)據(jù),也可以讀入整數(shù)、浮點(diǎn)數(shù)或其他類(lèi)型數(shù)據(jù)。如果不用字符串流,只能從字符數(shù)組逐個(gè)訪問(wèn)字符,而不能按其他類(lèi)型的數(shù)據(jù)形式讀取數(shù)據(jù)。這是用字符串流訪問(wèn)字符數(shù)組的優(yōu)點(diǎn),使用方便靈活。

3) 程序中先后建立了兩個(gè)字符串流strin和strout,與字符數(shù)組c關(guān)聯(lián)。strin從字符數(shù)組c中獲取數(shù)據(jù),strout將數(shù)據(jù)傳送給字符數(shù)組。分別對(duì)同一字符數(shù)組進(jìn)行操作。甚至可以對(duì)字符數(shù)組交叉進(jìn)行讀寫(xiě),輸入字符串流和輸出字符串流分別有流指針指示當(dāng)前位 置,互不干擾。

4) 用輸出字符串流向字符數(shù)組c寫(xiě)數(shù)據(jù)時(shí),是從數(shù)組的首地址開(kāi)始的,因此更新了 數(shù)組的內(nèi)容。

5) 字符串流關(guān)聯(lián)的字符數(shù)組并不一定是專(zhuān)為字符串流而定義的數(shù)組,它與一般的字符數(shù)組無(wú)異,可以對(duì)該數(shù)組進(jìn)行其他各種操作。

通過(guò)以上對(duì)字符串流的介紹,大家可以看到:與字符串流關(guān)聯(lián)的字符數(shù)組相當(dāng)于內(nèi)存中的臨時(shí)倉(cāng)庫(kù),可以用來(lái)存放各種類(lèi)型的數(shù)據(jù)(以ASCII形式存放),在需要時(shí)再?gòu)闹凶x回來(lái)。它的用法相當(dāng)于標(biāo)準(zhǔn)設(shè)備(顯示器與鍵盤(pán)),但標(biāo)準(zhǔn)設(shè)備不能保存數(shù)據(jù),而字符數(shù)組中的內(nèi)容可以隨時(shí)用ASCII字符輸出。它比外存文件使用方便,不必建立文件(不 需打開(kāi)與關(guān)閉),存取速度快。但它的生命周期與其所在的模塊(如主函數(shù))相同,該模塊的生命周期結(jié)束后,字符數(shù)組也不存在了。因此只能作為臨時(shí)的存儲(chǔ)空間。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阳西县| 普格县| 凤阳县| 运城市| 青岛市| 曲阜市| 龙海市| 宜宾市| 韶山市| 余江县| 太白县| 高邑县| 枣强县| 开平市| 南部县| 孟州市| 宜春市| 康平县| 淳化县| 金湖县| 太仓市| 朔州市| 喀什市| 贺州市| 扎鲁特旗| 昌图县| 永兴县| 乌审旗| 汨罗市| 招远市| 通江县| 宁陵县| 宜昌市| 延安市| 平塘县| 团风县| 军事| 五台县| 什邡市| 乌兰察布市| 确山县|