C++文件流存取結(jié)構(gòu)體數(shù)組操作實例及解析_第1頁
免費預(yù)覽已結(jié)束,剩余1頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、c+文件流存取結(jié)構(gòu)體數(shù)組操作實例及解析前面已經(jīng)介紹,二進(jìn)制文件不是以ascii代碼存放數(shù)據(jù)的,它將內(nèi)存中數(shù)據(jù)存儲形式不加轉(zhuǎn)換地傳送到磁盤文件,因此它又稱為內(nèi)存數(shù)據(jù)的映像文件。由于文件中的信息不是字符數(shù)據(jù),而是字節(jié)中的二進(jìn)制形式的信息,因此它又稱為字節(jié)文件。 對二進(jìn)制文件的操作也需要先打開文件,用盡后要關(guān)閉文件。在打開時要用ios:binary指定為以二進(jìn)制形式傳送和存儲。二進(jìn)制文件除了可以作為輸入文件或輸出文件外,還可以是既能輸入又能輸出的文件。這是和ascii文件不同的地方。 1用成員函數(shù)read和讀寫二進(jìn)制文件 對二進(jìn)制文件的讀寫主要用eam類的成員函數(shù)read和write來實現(xiàn)。這兩個成

2、員函數(shù)的原型為 istream read(char *buffer,inllea); ostream write(coastchar*buffer,intlen); 字符指針buffer指向內(nèi)存中一段存儲空間。len是讀寫的字節(jié)數(shù)。調(diào)用的方式為 a.write(pl,50); b.read(p2,30); 上面第一行中的a是輸出文件流對象,wrtte函數(shù)將字符指針pl所給出的地址開頭的50個字節(jié)的內(nèi)容不加轉(zhuǎn)換地寫到磁盤文件中。在其次行中,b是輸入文件流對象,read函數(shù)從b所關(guān)聯(lián)的磁盤文件中,讀人30個字節(jié)(或遇eof結(jié)束),存放在字符指針p2所指的一段空間內(nèi)。 例14 將一批數(shù)據(jù)以二進(jìn)制形式

3、存放在磁盤文件中。 可以寫出下面的程序: ilude fstream using namespace std; struct student char name20; int num; int age; char s; ; int main() student stud3= li ,1001,18, f , fun ,1002,19, m , wang ,1004,17, f ofstream out( stud.dat ,ios:binary); if(!outfile) cerr open error! endl; abort(); /退出程序 for(int i=0;i i+) outf

4、ile.write(char *) studi,sizeof(studi); outfile.close(); return 0; 定義了結(jié)構(gòu)體類型student,它包括4個成員。用student定義結(jié)構(gòu)體數(shù)組stud,并對其初始化。建立輸出文件流對象outfile,打開磁盤文件stud.dat(假如本來無此文件,則建立新文件,假如已有同名文件則將其原有內(nèi)容刪除,以便重新寫人數(shù)據(jù))。將stud.dat文件的工作方式定為二進(jìn)制文件。 用成員函數(shù)write向stud.dat輸出數(shù)據(jù),先前面給出的write函數(shù)的原型可以看出:第1個形參是指向char型常變量的指針變量buffer,之所以用const

5、聲明,是由于不允許通過指針轉(zhuǎn)變其指向數(shù)據(jù)的值。形參要求相應(yīng)的實參是字符指針或字符串的首地址?,F(xiàn)在要將結(jié)構(gòu)體數(shù)組的一個元素(包含4個成員)一次輸?shù)酱疟P文件stud.dat。 studi是結(jié)構(gòu)體數(shù)組第i個元素的首地址,但這是指向結(jié)構(gòu)體的指針,與形參類型不匹配。因此要用(char。)把它強制轉(zhuǎn)換為字符指針。第2個參數(shù)是指定一次輸出的字節(jié)數(shù)。sizeof (studi)的值是結(jié)構(gòu)體數(shù)組的一個元素的字節(jié)數(shù)。調(diào)用一次write函數(shù),就將從 stud 開頭的結(jié)構(gòu)體數(shù)組的一個元素輸出到磁盤文件中,執(zhí)行3次循環(huán)輸出結(jié)構(gòu)休數(shù)組的3個元素。 其實可以一次輸出結(jié)構(gòu)體數(shù)組的3個元素,將for循環(huán)的兩行政為以下一行: o

6、utfile.write(char*) studo,sizeof(stud); 執(zhí)行一次write函數(shù)即輸出了結(jié)構(gòu)體數(shù)組的所有數(shù)據(jù)。 abort函數(shù)的作用是退出程序,與exit函數(shù)的作用相同。 可以看到,用這種辦法一次可以輸出一批數(shù)據(jù),效率較高。在輸出的數(shù)據(jù)之間不必加入空格,在一次輸出之后也不必加回車換行符。在以后從該文件讀人數(shù)據(jù)時不是靠空格作為數(shù)據(jù)的間隔,而是用字節(jié)數(shù)來控制。 例15 將剛才以二進(jìn)制形式存放在磁盤文件中的數(shù)據(jù)讀人內(nèi)存并在顯示器上顯示。 include fstream using namespace std; struct student char name20; int nu

7、m; int age; char sex; ; int main() student stud3; int i; ifstream infile( stud.dat ,ios:binary); if(!infile) cerr open error! endl; abort(); for(i=0;i i+) infile.read(char*) studi,sizeof(studi); infile.close(); for(i=0;i i+) cout no. i+1 endl; cout name: endl; cout num: studi.num endl; co

8、ut age: studi.age endl; cout sex: studi.sex endl endl; return 0; 運行時在顯示器上顯示: no1 name:li num:1001 age:18 sex:t no2 name:fun num:1001 age:19 sex:m no3 name:wang num:1004 age:17 sex:t 有了例714的基礎(chǔ),讀者看懂這個程序是不會有什么困難的。 請思量:能否 次讀人文件中的所有數(shù)據(jù),如 infileread(char*) studo,sizeof(stud); 答案是可以的,將指定數(shù)目的字節(jié)讀入內(nèi)存,依次存放在以地址 s

9、tud0開頭的存儲空間中。要注重讀人的數(shù)據(jù)的格式要與存放它的空間的格式匹配。因為磁盤文件中的數(shù)據(jù)是從內(nèi)存中結(jié)構(gòu)體數(shù)組元素得來的,因此它仍然保留結(jié)構(gòu)體元素的數(shù)據(jù)格式。現(xiàn)在再讀人內(nèi)存,存放在同樣的結(jié)構(gòu)體數(shù)組中,這必定是匹配的。假如把它放到一個整型數(shù)組中,就不匹配了,會出錯。 2與文件指針有關(guān)的流成員函數(shù) 在磁盤文件中有一個文件指針,用來指明當(dāng)前應(yīng)舉行讀寫的位置。在輸入時每讀人一個字節(jié),指針就向后移動一個字節(jié)。在輸出時每向文件輸出一個字節(jié),指針就向后移動一個字節(jié),隨著輸出文件中字節(jié)不斷增強,指針不斷后移。對于二進(jìn)制文件,允許對指針舉行控制,使它按用戶的意圖移動到所需的位置,以便在該位置上舉行瀆寫。文

10、件流提供一些有關(guān)文件指針的成員函數(shù)。為了查閱便利,將它們歸納為表7,并作須要的解釋。 解釋: (1)讀者很簡單發(fā)覺:這些函數(shù)名的第一個字母或最后一個字母不是g就是p。帶g的是用于輸入的函數(shù)(g是get的第一個字母,以g作為輸入的標(biāo)識,簡單理解和記憶),帶p的是用于輸出的函數(shù)(p是put的第一個字母,以p作為輸出的標(biāo)識)。例如有兩個tell函數(shù),tellg用于輸人文件,tellp用于輸出文件。同樣,seekg用于輸入文件,seekp用于輸出文件。以上函數(shù)見名知意,一看就明了,不必死記。 假如是既可輸入又可輸出的文件,則隨意用seekg或seekp。 (2)函數(shù)參數(shù)中的 文件中的位置 和 位移量

11、已被指定為long型整數(shù),以字節(jié)為單位。 參照位置 可以是下面三者之一: ios:beg 文件開始(beg是begin的縮寫),這是默認(rèn)值。 ios :cur 指針當(dāng)前的位置(cur是current的縮寫)。 ios :end 文件末尾。 它們是在los類中定義的枚舉常量。 舉例如下: infile.seekg(100); /輸入文件中的指針向前移到100字節(jié)位置 infile.seekg(-50,ios:cur);/輸入文件中的指針從當(dāng)前位置后移50字節(jié) outfile.seekp(-75,ios:end);/輸出文件中的指針從文件尾后移50字節(jié) 3隨機拜訪二進(jìn)制數(shù)據(jù)文件 普通狀況下讀寫是挨

12、次舉行的,即逐個字節(jié)舉行瀆寫。但是對于二進(jìn)制數(shù)據(jù)文件來說,可以利用上面的成員函數(shù)移動指針,隨機地拜訪文件中任一位置上的數(shù)據(jù),還可以修改文件中的內(nèi)容。 例16 有5個同學(xué)的數(shù)據(jù),要求: (1)把它們存到磁盤文件中; (2)將磁盤文件中的第l,3,5個同學(xué)數(shù)據(jù)讀人程序,并顯示出來; (3)將第3個同學(xué)的數(shù)據(jù)修改后存回磁盤文件中的原有位置; (4)從磁盤文件讀入修改后的5個同學(xué)的數(shù)據(jù)并顯示出來。 要實現(xiàn)以上要求,需要解決3個問題: (1)因為同一磁盤文件在程序中需要頻繁地舉行輸入和輸出,因此可將文件的工作方式指定為輸入輸出文件,即ios:in|ios:out|ios:binary。 (2)正確計算好

13、每次拜訪時指針的定位,即正確用法seekg或seekp函數(shù)。 (3)正確舉行文件中數(shù)據(jù)的重寫(更新)。 可寫出以下程序: include fstream using namespace std; struct student int num; char name20; float score; ; int main() int i; 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|

14、ios:binary); /用fstream類定義輸入輸出二進(jìn)制文件流對象iofile if(!iofile) cerr open error! endl; abort(); for(i=0;i i+) /向磁盤文件輸出5個同學(xué)的數(shù)據(jù) iofile.write(char *) studi,sizeof(studi); student stud15; /用來存放從磁盤文件讀入的數(shù)據(jù) for(i=0;i i=i+2) iofile.seekg(i*sizeof(studi),ios:beg); /定位于第0,2,4同學(xué)數(shù)據(jù)開始 iofile.read(char *) stud1i/2,sizeof

15、(stud1i); /先后讀人3個同學(xué)的數(shù)據(jù),存放在studlo,stud1和stud2中 cout stud1i/2.num stud1i/2.name stud1i/2.score endl; /輸出studl0,stud1)和stud2各成員的值 cout endl; stud2.num=1012; /修改第3個同學(xué)(序號為2)的數(shù)據(jù) stry(, wu stud2.score=60; iofile.seekp(2*sizeof(stud0),ios:beg); /定位于第3個同學(xué)數(shù)據(jù)的開始 iofile.write(char *) stud2,sizeof(stud

16、2); /更新第3個同學(xué)數(shù)據(jù) iofile.seekg(0,ios:beg); /重新定位于文件開始 for(i=0;i i+) iofile.read(char *) studi,sizeof(studi);/讀入5個同學(xué)的數(shù)據(jù) cout studi.num studi.score endl; iofile.close(); return 0; 運行狀況如下: 1001 li 85 (第1個同學(xué)數(shù)據(jù)) 1004 wang 54 (第3個同學(xué)數(shù)據(jù)) 1010 ling 96 (第5個學(xué)牛數(shù)據(jù)) 1001 li 85 (輸出修改后5個同學(xué)數(shù)據(jù)) 1002 fun 975 1012 wu 60 (巳修改的第3個同學(xué)數(shù)據(jù)) 1006 tan 765 1010 ling 96 本程序也可以將磁盤文件studdat先后定義為輸出文件和輸人文件,在結(jié)束第一次的輸出之后關(guān)閉該文件,然后再按輸入方式打開它,輸入完后再關(guān)閉它,然后再按輸出方式打開,再關(guān)閉,再按輸入方式打開它,輸入完后再關(guān)閉。明顯這是很煩瑣和不便利的。 在程序中把它指定為輸入輸出型的二進(jìn)制文件。這樣,不僅可以向文件添加新的數(shù)據(jù)或讀人數(shù)據(jù),還可以修改(更新)數(shù)據(jù)。利用這些功能,可以實現(xiàn)比較復(fù)雜的輸入輸出任務(wù),請注重,不能用ifstream或ofstream類定義輸入輸出的二進(jìn)制文件流對象,而應(yīng)該用fstr

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論