亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解C++編程中對二進制文件的讀寫操作

2020-05-23 14:13:55
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了C++編程中對二進制文件的讀寫操作,是C++入門學習中的基礎知識,需要的朋友可以參考下

二進制文件不是以ASCII代碼存放數據的,它將內存中數據存儲形式不加轉換地傳送到磁盤文件,因此它又稱為內存數據的映像文件。因為文件中的信息不是字符數據,而是字節中的二進制形式的信息,因此它又稱為字節文件。

對二進制文件的操作也需要先打開文件,用完后要關閉文件。在打開時要用ios::binary指定為以二進制形式傳送和存儲。二進制文件除了可以作為輸入文件或輸出文件外,還可以是既能輸入又能輸出的文件。這是和ASCII文件不同的地方。

用成員函數read和write讀寫二進制文件

對二進制文件的讀寫主要用istream類的成員函數read和write來實現。這兩個成員函數的原型為

 

 
  1. istream& read(char *buffer,int len); 
  2. ostream& write(const char * buffer,int len); 

字符指針buffer指向內存中一段存儲空間。len是讀寫的字節數。調用的方式為:

 

 
  1. a. write(p1,50); 
  2. b. read(p2,30); 

上面第一行中的a是輸出文件流對象,write函數將字符指針p1所給出的地址開始的50個字節的內容不加轉換地寫到磁盤文件中。在第二行中,b是輸入文件流對象,read 函數從b所關聯的磁盤文件中,讀入30個字節(或遇EOF結束),存放在字符指針p2所指的一段空間內。

[例] 將一批數據以二進制形式存放在磁盤文件中。

 

 
  1. #include <fstream> 
  2. using namespace std; 
  3. struct student 
  4. char name[20]; 
  5. int num; 
  6. int age; 
  7. char sex; 
  8. }; 
  9. int main( ) 
  10. student stud[3]={"Li",1001,18,'f',"Fun",1002,19,'m',"Wang",1004,17,'f'}; 
  11. ofstream outfile("stud.dat",ios::binary); 
  12. if(!outfile) 
  13. cerr<<"open error!"<<endl; 
  14. abort( );//退出程序 
  15. for(int i=0;i<3;i++) 
  16. outfile.write((char*)&stud[i],sizeof(stud[i])); 
  17. outfile.close( ); 
  18. return 0; 

用成員函數write向stud.dat輸出數據,從前面給出的write函數的原型可以看出: 第1個形參是指向char型常變量的指針變量buffer,之所以用const聲明,是因為不允許通過指針改變其指向數據的值。形參要求相應的實參是字符指針或字符串的首地址。現在要將結構體數組的一個元素(包含4個成員)一次輸出到磁盤文件stud.dat。&tud[i] 是結構體數組第i個元素的首地址,但這是指向結構體的指針,與形參類型不匹配。因此 要用(char *)把它強制轉換為字符指針。第2個參數是指定一次輸出的字節數。sizeof (stud[i])的值是結構體數組的一個元素的字節數。調用一次write函數,就將從&tud[i]開始的結構體數組的一個元素輸出到磁盤文件中,執行3次循環輸出結構體數組的3個元素。

其實可以一次輸出結構體數組的個元素,將for循環的兩行改為以下一行:

 

 
  1. outfile.write((char*)&stud[0],sizeof(stud)); 

執行一次write函數即輸出了結構體數組的全部數據。

abort函數的作用是退出程序,與exit作用相同。

可以看到,用這種方法一次可以輸出一批數據,效率較高。在輸出的數據之間不必加入空格,在一次輸出之后也不必加回車換行符。在以后從該文件讀入數據時不是靠空格作為數據的間隔,而是用字節數來控制。

[例] 將剛才以二進制形式存放在磁盤文件中的數據讀入內存并在顯示器上顯示。

 

 
  1. #include <fstream> 
  2. using namespace std; 
  3. struct student 
  4. string name; 
  5. int num; 
  6. int age; 
  7. char sex; 
  8. }; 
  9. int main( ) 
  10. student stud[3]; 
  11. int i; 
  12. ifstream infile("stud.dat",ios::binary); 
  13. if(!infile) 
  14. cerr<<"open error!"<<endl; 
  15. abort( ); 
  16. for(i=0;i<3;i++) 
  17. infile.read((char*)&stud[i],sizeof(stud[i])); 
  18. infile.close( ); 
  19. for(i=0;i<3;i++) 
  20. cout<<"NO."<<i+1<<endl; 
  21. cout<<"name:"<<stud[i].name<<endl; 
  22. cout<<"num:"<<stud[i].num<<endl;; 
  23. cout<<"age:"<<stud[i].age<<endl; 
  24. cout<<"sex:"<<stud[i].sex<<endl<<endl; 
  25. return 0; 

運行時在顯示器上顯示:

 

 
  1. NO.1 
  2. name: Li 
  3. num: 1001 
  4. age: 18 
  5. sex: f 
  6.  
  7. NO.2 
  8. name: Fun 
  9. num: 1001 
  10. age: 19 
  11. sex: m 
  12.  
  13. NO.3 
  14. name: Wang 
  15. num: 1004 
  16. age: 17 
  17. sex: f 

請思考,能否一次讀入文件中的全部數據,如:

 

 
  1. infile.read((char*)&stud[0],sizeof(stud)); 

答案是可以的,將指定數目的字節讀入內存,依次存放在以地址&tud[0]開始的存儲空間中。要注意讀入的數據的格式要與存放它的空間的格式匹配。由于磁盤文件中的數據是從內存中結構體數組元素得來的,因此它仍然保留結構體元素的數據格式。現在再讀入內存,存放在同樣的結構體數組中,這必然是匹配的。如果把它放到一個整型數組中,就不匹配了,會出錯。

與文件指針有關的流成員函數

在磁盤文件中有一個文件指針,用來指明當前應進行讀寫的位置。在輸入時每讀入 一個宇節,指針就向后移動一個字節。在輸出時每向文件輸出一個字節,指針就向后移動 一個字節,隨著輸出文件中字節不斷增加,指針不斷后移。對于二進制文件,允許對指針進行控制,使它按用戶的意圖移動到所需的位置,以便在該位置上進行讀寫。文件流提供 一些有關文件指針的成員函數。為了查閱方便,將它們歸納為下表:

詳解C++編程中對二進制文件的讀寫操作

幾點說明:

1) 這些函數名的第一個字母或最后一個字母不是g就是p。帶 g的是用于輸入的函數(g是get的第一個字母,以g作為輸入的標識,容易理解和記憶), 帶p的是用于輸出的函數(P是put的第一個字母,以P作為輸出的標識)。例如有兩個 tell 函數,tellg用于輸入文件,tellp用于輸出文件。同樣,seekg用于輸入文件,seekp用于輸出文件。以上函數見名知意,一看就明白,不必死記。

如果是既可輸入又可輸出的文件,則任意用seekg或seekp。

2) 函數參數中的“文件中的位置”和“位移量”已被指定為long型整數,以字節為單位。“參照位置”可以是下面三者之一:

ios::beg 文件開頭(beg是begin的縮寫),這是默認值。

ios::cur 指針當前的位置(cur是current的縮寫)。

ios::end 文件末尾。

它們是在ios類中定義的枚舉常量。舉例如下:

infile.seekg(100); //輸入文件中的指針向前移到字節位置

infile.seekg(-50,ios::cur); //輸入文件中的指針從當前位置后移字節

outfile.seekp(-75,ios::end); //輸出文件中的指針從文件尾后移字節

隨機訪問二進制數據文件

一般情況下讀寫是順序進行的,即逐個字節進行讀寫。但是對于二進制數據文件來說,可以利用上面的成員函數移動指針,隨機地訪問文件中任一位置上的數據,還可以修改文件中的內容。

[例] 有個學生的數據,要求:

把它們存到磁盤文件中;

將磁盤文件中的第,3,5個學生數據讀入程序,并顯示出來;

將第個學生的數據修改后存回磁盤文件中的原有位置。

從磁盤文件讀入修改后的個學生的數據并顯示出來。

要實現以上要求,需要解決個問題:

由于同一磁盤文件在程序中需要頻繁地進行輸入和輸出,因此可將文件的工作方式指定為輸入輸出文件,即ios::in|ios::out|ios::binary。

正確計算好每次訪問時指針的定位,即正確使用seekg或seekp函數。

正確進行文件中數據的重寫(更新)。

可寫出以下程序:

 

 
  1. #include <fstream> 
  2. using namespace std; 
  3. struct student 
  4. int num; 
  5. char name[20]; 
  6. float score; 
  7. }; 
  8. int main( ) 
  9. student stud[5]={1001,"Li",85,1002,"Fun",97.5,1004,"Wang",54,1006,"Tan",76.5,1010,"ling",96}; 
  10. fstream iofile("stud.dat",ios::in|ios::out|ios::binary); 
  11. //用fstream類定義輸入輸出二進制文件流對象iofile 
  12. if(!iofile) 
  13. cerr<<"open error!"<<endl; 
  14. abort( ); 
  15. for(int i=0;i<5;i++) //向磁盤文件輸出個學生的數據 
  16. iofile.write((char *)&stud[i],sizeof(stud[i])); 
  17. student stud1[5]; //用來存放從磁盤文件讀入的數據 
  18. for(int i=0;i<5;i=i+2) 
  19. iofile.seekg(i*sizeof(stud[i]),ios::beg); //定位于第,2,4學生數據開頭 
  20. //先后讀入個學生的數據,存放在stud1[0],stud[1]和stud[2]中 
  21. iofile.read((char *)&stud1[i/2],sizeof(stud1[0])); 
  22. //輸出stud1[0],stud[1]和stud[2]各成員的值 
  23. cout<<stud1[i/2].num<<" "<<stud1[i/2].name<<" "<<stud1[i/2].score<<endl; 
  24. cout<<endl; 
  25. stud[2].num=1012; //修改第個學生(序號為)的數據 
  26. strcpy(stud[2].name,"Wu"); 
  27. stud[2].score=60; 
  28. iofile.seekp(2*sizeof(stud[0]),ios::beg); //定位于第個學生數據的開頭 
  29. iofile.write((char *)&stud[2],sizeof(stud[2])); //更新第個學生數據 
  30. iofile.seekg(0,ios::beg); //重新定位于文件開頭 
  31. for(int i=0;i<5;i++) 
  32. iofile.read((char *)&stud[i],sizeof(stud[i])); //讀入個學生的數據 
  33. cout<<stud[i].num<<" "<<stud[i].name<<" "<<stud[i].score<<endl; 
  34. iofile.close( ); 
  35. return 0; 

運行情況如下:

 

 
  1. 1001 Li 85(第個學生數據) 
  2. 1004 Wang 54 (第個學生數據) 
  3. 1010 ling 96 (第個學生數據) 
  4.  
  5. 1001 Li 85 (輸出修改后個學生數據) 
  6. 1002 Fun 97.5 
  7. 1012 Wu 60 (已修改的第個學生數據) 
  8. 1006 Tan 76.5 
  9. 1010 ling 96 

本程序也可以將磁盤文件stud.dat先后定義為輸出文件和輸入文件,在結束第一次的輸出之后關閉該文件,然后再按輸入方式打開它,輸入完后再關閉它,然后再按輸出方式打開,再關閉,再按輸入方式打開它,輸入完后再關閉。顯然這是很煩瑣和不方便的。 在程序中把它指定為輸入輸出型的二進制文件。這樣,不僅可以向文件添加新的數據或讀入數據,還可以修改(更新)數據。利用這些功能,可以實現比較復雜的輸入輸出任務。

請注意,不能用ifstream或ofstream類定義輸入輸出的二進制文件流對象,而應當用fstream類。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲电影免费观看高清完整版在线观看| 日韩美女视频在线观看| 97色伦亚洲国产| 一本色道久久88精品综合| 少妇精69xxtheporn| 亚洲视频专区在线| 国产一区私人高清影院| 中文字幕国产亚洲2019| 久久亚洲精品一区| 91精品国产免费久久久久久| 国产精品视频自拍| 国产精品自拍偷拍视频| 精品国内亚洲在观看18黄| 欧美成人性色生活仑片| 久久久久久国产精品三级玉女聊斋| 欧美日韩国产中文精品字幕自在自线| 亚洲精品黄网在线观看| 亚洲欧美日韩国产中文专区| 久久精品视频中文字幕| 久久免费少妇高潮久久精品99| 欧美激情在线观看视频| 久久久久久久久国产精品| 91中文字幕在线| 欧美疯狂做受xxxx高潮| 伊人久久久久久久久久久| 精品亚洲国产成av人片传媒| 亚洲精品丝袜日韩| 亚洲成av人影院在线观看| 国产亚洲a∨片在线观看| 亚洲一区二区三| 欧美俄罗斯乱妇| 欧美在线激情视频| 国产成人一区二区三区| 久久久久久久久久久免费精品| 久久久精品日本| 久久精品国产96久久久香蕉| 欧美乱妇高清无乱码| 国产精品444| 亚洲福利视频免费观看| 欧美成人免费在线视频| 久久免费成人精品视频| 久久九九热免费视频| 欧美日本亚洲视频| 中文字幕亚洲综合| 永久免费看mv网站入口亚洲| 秋霞午夜一区二区| 5252色成人免费视频| 81精品国产乱码久久久久久| 欧美日韩免费看| 亚洲乱码国产乱码精品精天堂| 国产欧美精品va在线观看| 亚洲成人aaa| 91精品在线看| 韩日欧美一区二区| 色婷婷亚洲mv天堂mv在影片| 久国内精品在线| 亚洲精品中文字幕女同| 欧美日韩国产成人高清视频| 日韩在线播放视频| 精品五月天久久| 97免费中文视频在线观看| 宅男66日本亚洲欧美视频| 欧美在线一级va免费观看| 国产精品久久久久影院日本| 亚洲人成电影在线观看天堂色| 欧美在线一区二区三区四| 国产精品美女主播在线观看纯欲| 亚洲自拍偷拍福利| 狠狠色狠色综合曰曰| 激情懂色av一区av二区av| 成人做爰www免费看视频网站| 一区二区三区国产视频| 欧美日韩国产成人在线观看| 成人国产精品久久久| 亚洲国产精品久久久久秋霞蜜臀| 国模私拍一区二区三区| 欧美大全免费观看电视剧大泉洋| 日韩在线免费av| 国外成人在线视频| 91亚洲永久免费精品| 亚洲成人亚洲激情| 日韩免费精品视频| 色狠狠久久aa北条麻妃| 国产成人av网址| 97久久精品人搡人人玩| 亚洲成人免费网站| 国产日韩精品在线观看| 欧美精品激情在线| 91免费人成网站在线观看18| 久久婷婷国产麻豆91天堂| 国产精品丝袜久久久久久高清| 国产精品视频999| 色综合天天综合网国产成人网| 国产精品电影一区| 亚洲石原莉奈一区二区在线观看| www.亚洲一区| 欧美在线性视频| 午夜精品一区二区三区视频免费看| 精品久久久久久中文字幕大豆网| 国产性猛交xxxx免费看久久| 成人精品视频99在线观看免费| 国产日韩欧美在线观看| 亚洲欧美日韩第一区| 中文字幕9999| 最近免费中文字幕视频2019| 成人观看高清在线观看免费| 亚洲免费视频一区二区| 欧美黄色片在线观看| 国产在线视频一区| 一本久久综合亚洲鲁鲁| 欧美成人第一页| 久久99热精品这里久久精品| 成人激情综合网| 国产精品九九久久久久久久| 福利视频第一区| 欧美电影免费观看高清| 国产精品成人久久久久| 国内精品美女av在线播放| www.国产精品一二区| 亚洲欧美在线看| 中文字幕精品国产| 亚洲欧美日韩天堂| 亚洲精品自产拍| 国产亚洲a∨片在线观看| 一级做a爰片久久毛片美女图片| 精品中文字幕乱| 欧美成人精品一区二区| 国产一区二区av| 欧美大尺度激情区在线播放| 亚洲二区中文字幕| 亚洲国产成人精品久久| 久久久视频精品| 欧美成人免费在线视频| 精品偷拍各种wc美女嘘嘘| 午夜精品久久久99热福利| 日本欧美在线视频| 欧美怡春院一区二区三区| 国产日韩精品入口| 色狠狠av一区二区三区香蕉蜜桃| 亚洲激情自拍图| 国产精品久久久久久久久男| 美女福利精品视频| 欧美激情aaaa| 7777精品视频| 66m—66摸成人免费视频| 欧美夫妻性生活xx| 日韩a**站在线观看| 国产一区二区三区高清在线观看| 最近2019年手机中文字幕| 亚洲男人天堂网| 国产日韩欧美自拍| 97热在线精品视频在线观看| 一区二区三区视频免费在线观看| 日韩最新av在线| 久久久久久久久久国产精品| 欧美二区在线播放| 成人免费观看49www在线观看| 日韩中文字幕第一页| 国产精品视频公开费视频| 亚洲已满18点击进入在线看片| 性色av一区二区三区| 91中文字幕在线观看| 欧美日韩国产一区二区三区| 亚洲成人av片|