




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第七章輸入輸出流7.1輸入輸出基本概念7.2標準輸出流7.3標準輸入流7.4對數據文件的操作與文件流*7.5字符串流7.1輸入輸出基本概念7.1.1輸入輸出的邏輯形式7.1.2輸入輸出的分類7.1.3輸入輸出的類庫結構7.1.1輸入輸出的邏輯形式例如:當鍵入字符時,就可認為字符從鍵盤流入程序的數據結構中;當寫入磁盤文件時,也可認為程序流到磁盤上。把接收存放輸出數據的地方叫做目標,把輸入數據來自的地方叫做源,C++將數據從源到目的端的傳送形象地看做一個“流”。設備內部程序數據輸入流輸出流數據設備設備包括:(1)磁盤文件(2)設備文件(如鍵盤、顯示器、打印機等)在輸出輸出過程中會經過內存緩沖區設備內部程序數據輸入流輸出流數據設備內存緩沖區內存緩沖區引入緩沖的目的是解決CPU的運行速度和外設操作速度不匹配的矛盾。如輸出時先寫入緩沖區,再成批輸出。成批寫出數據比一個一個寫出數據節約時間。一般地,緩沖區在內存中。7.1.2輸入輸出的分類(1)標準的輸入輸出從鍵盤輸入數據,輸出到顯示器屏幕。簡稱標準I/O。(2)文件的輸入輸出以外存磁盤文件為對象進行輸入和輸出,即從磁盤文件輸入數據,數據輸出到磁盤文件。簡稱文件I/O。(3)字符串輸入輸出對內存中指定的空間進行輸入和輸出。通常指定一個字符數組作為存儲空間(實際上可以利用該空間存儲任何信息)。這種輸入和輸出稱為字符串輸入輸出,簡稱串I/O。7.1.3輸入輸出的類庫結構C++把與輸入和輸出有關的操作定義為一個類體系,放在一個系統庫里(稱為流庫),供用戶調用。流庫中的類稱為流類(streamclass)。用流類定義的對象稱為流對象。流類具有兩個平行的基類即streambuf類和ios類,所有其它的流類都是從它們直接或間接地派生出來的。7.1.3輸入輸出的類庫結構C++流庫主要由兩個流類層次組成:以streambuf類為父類的類層次主要用于管理流的緩沖區。以ios類為父類的類層次實現了各種格式化的輸入/輸出控制方法。1:標準I/O的流類的體系2:文件I/O的流類的體系標準I/O的流類的體系通用輸出流基類通用輸入輸出流基類cin為istream類的對象cout、cerr、clog為ostream類的對象iosistreamiostreamostreamstreambuf一個指針成員指向該類對象通用輸入流基類抽象緩沖區基類流基類需要包含頭文件:iostream通用輸入輸出流基類文件I/O的流類的體系iosistreamiostreamostreamstreambufifstreamofstreamfstreamfilebuf完成從文件提取數據完成向文件插入數據完成提取插入操作完成文件緩沖區管理一個指針成員指向該類對象通用輸出流基類通用輸入流基類抽象緩沖區基類流基類需要包含頭文件:fstream7.2標準輸出流標準輸出流是流向標準輸出設備(顯示器)的數據。流庫中已經預先定義了cout、cerr和clog三個標準輸出流對象。通過包含頭文件“iostream”就可以使用這三個對象。7.2.1cout,cerr和clog流1.cout流對象2.cerr流對象3.clog流對象1cout流對象作用:可以將不同類型的數據輸出到屏幕上,如:cout<<‘A’<<12.2<<15;cout對象為什么可以這樣使用?因為在ostream中用運算符重載實現了多種數據類型的標準輸入輸出。而cout是ostream的對象。C++對基本的數據類型,均定義了重載運算符<<classostream:virtualpublicios{public:……ostream&operator<<(char*);//字符串輸出重載函數……ostream&operator<<(char&);//字符輸出重載函數……ostream&operator<<(int&);//
整數輸出重載函數……ostream&operator<<(double&);//實型數據輸出重載函數……};//此處代碼僅僅是示意,實際的ostream是類模板,代碼比較復雜2.cerr流對象cerr流對象是標準出錯流。它不經過緩沖區直接向顯示器輸出出錯信息。3.clog流對象
clog流對象也是標準出錯流,clog是帶緩沖版本的標準出錯流。例7.1編寫程序,從鍵盤輸入a,b,c的值求解一元二次方程。如果a=0或判別式的值<0,輸出出錯信息。關于這三者的區別其實相當復雜,書上介紹的三者的區別并不完全正確,有興趣的同學可以參考網上的分析文章:“cout/cerr/clog之異同極其重定向”“clog,cout,cerr輸出機制”。輸入方程的系數a,b,ca=0TF報告輸入系數a的值等于0,出錯!b2-4ac<0TF報告判別式的值小于0,出錯!分別計算一元二次方程的兩個根X1和X2。NS流程圖#include<iostream>usingnamespacestd;intmain(){floata,b,c,disc;cout<<"請輸入a,b,c:";cin>>a>>b>>c;if(a==0)cerr<<"a等于0,錯誤!"<<endl;elseif((disc=b*b-4*a*c)<0)
cerr<<"判別式b*b-4*a*c<0<<endl;else{
cout<<"x1="<<(-b+sqrt(disc))/(2*a)<<endl;
cout<<"x2="<<(-b-sqrt(disc))/(2*a)<<endl;}return0;}7.2.2格式輸出在輸出數據時,如不指定格式,則采用系統給定的默認格式。通過控制符或流的成員函數設置可以輸出格式。1.用控制符設置輸出格式表7.3列出了輸出格式的控制符。這些控制符大部分在頭文件iomanip中聲明,另一部分控制符的聲明包含在頭文件iostream中。控制符是函數。所以也可以稱為格式控制函數。例7.2用控制符控制輸出格式。resetiosflags()#include<iostream>#include<iomanip>usingnamespacestd;intmain(){inta;cout<<"inputa:";cin>>a;cout<<"dec:"<<dec<<a<<endl;cout<<"hex:"<<hex<<a<<endl;cout<<"oct:"<<setbase(8)<<a<<endl;char*pt="China";cout<<setw(10)<<pt<<endl;cout<<setfill('*')<<setw(10)<<pt<<endl;doublepi=22.0/7.0;cout<<setiosflags(ios::scientific)<<setprecision(8);cout<<"pi="<<pi<<endl;cout<<"pi="<<setprecision(4)<<pi<<endl;cout<<resetiosflags(ios::scientific);cout<<"pi="<<setiosflags(ios::fixed)<<pi<<endl;return0;}inputa:34dec:34hex:22oct:42China*****Chinapi=3.14285714e+000pi=3.1429e+000pi=3.1429請按任意鍵繼續...2.用流對象的成員函數控制輸出格式用于控制輸出格式的常用成員函數見表7.4流成員函數setf和控制符setiosflags括號中參數是格式標志,在類ios中定義它是枚舉值。所以在引用這些格式標志時要以ios::開始,格式標志列于表7.5。例7.3用流控制成員函數輸出數據。intmain(){inta=21;cout.setf(ios::showbase);cout<<"dec:"<<a<<endl;cout.unsetf(ios::dec);cout.setf(ios::hex);cout<<"hex:"<<a<<endl;cout.unsetf(ios::hex);cout.setf(ios::oct);cout<<"oct:"<<a<<endl;char*pt="China";cout.width(10);cout<<pt<<endl;cout.width(10);cout.fill('*');注意:用成員函數setf()設置整數的基數,必須用函數unsetf()終止后才能重新設置其他整數基數格式,否則下次設置setf()后,輸出流數據又以默認的十進制基數顯示。注意:用控制符setw()或者成員函數width()設置輸出數據的寬度僅僅對其后的第一個數據有效。cout<<pt<<endl;doublepi=22.0/7.0;cout.setf(ios::scientific);cout<<"pi=";cout.width(14);cout<<pi<<endl;cout.unsetf(ios::scientific);cout.setf(ios::fixed);cout.width(12);cout.setf(ios::showpos);cout.setf(ios::internal);cout.precision(6);cout<<pi<<endl;return0;}7.2.3用流成員函數put輸出字符格式:cout.put(字符/數字)[.put(…)……]如是字符,直接輸出該字符;如是數字,可以用八進制、十進制或十六進制表示整數,用該數字對256取模,輸出對應的ASCII碼字符。如:cout.put('f').put(65).put(321);輸出:fAA例7.4按相反的順序輸出“BASIC”。#include<iostream>usingnamespacestd;intmain(){
char*a="BASIC";for(inti=4;i>=0;i--)cout.put(*(a+i));cout.put('\n');return0;}輸出:CISAB7.3標準輸入流標準輸入流是從標準輸入設備(鍵盤)流向內存的數據。即從鍵盤讀取的數據。流庫中已經預先定義了cin這個標準輸入流對象。通過包含頭文件“iostream”就可以使用這個對象。7.3.1cin流對象7.3.2輸入字符的流成員函數7.3.1cin流對象cin是istream類的對象。istream重載了基本的數據類型的流提取運算符>>,所以可以用cin>>x;這樣的語句輸入數據至變量x中。cin是緩沖流,當輸入一行結束按回車(Enter)時,操作系統將輸入內容放入輸入緩沖區,然后cin從輸入緩沖區提取數據。輸入數據時,在缺省的情況下,數據之間的分隔符為:<Space>鍵(空格鍵)、<Tab>鍵(制表鍵)或<Enter>鍵(回車鍵),這三個鍵通稱為空白字符。如:charc1,c2,c3;cin>>c1>>c2>>c3;程序運行時,可輸入:a<Space>b<Tab>c<Enter>
也可輸入:a<Tab>b<Tab>c<Enter>
或輸入:a<Enter>b<Enter>c<Enter>在上述情況下,三個變量c1、c2和c3獲得值均為‘a’、‘b’和‘c’。應注意,最后輸入的總是回車鍵。當遇到無效字符(文件結束符或者與變量數據類型不一致),cin流的所有操作都被終止,cin的值變為false。可以根據cin的值判斷流對象是否處于正常狀態。例7.5測試cin的值,判斷流對象的狀態。intmain(){floatgrade;cout<<"entergrade:";
while(cin>>grade){if(grade>=85)cout<<grade<<"GOOD!"<<endl;if(grade<60)cout<<grade<<"fail!"<<endl;cout<<"entergrade:";}cout<<"Theend."<<endl;return0;}#include<iostream>usingnamespacestd;intmain(){floatgrade;while(1){cout<<"entergrade:";cin>>grade;if(cin.good()==false)break;if(grade>=85)cout<<grade<<"GOOD!"<<endl;if(grade<60)cout<<grade<<"fail!"<<endl;}cout<<"Theend."<<endl;return0;}7.3.2輸入字符的流成員函數1.不帶參數的get函數格式:cin.get()函數的類型是字符,函數的功能是從輸入流中提取一個字符作為函數值返回。如在流中遇到文件結束符時(在鍵盤中輸入ctrl+z),返回-1。例7.6用get函數讀入字符。intmain(){charc;cout<<"enterasentence:"<<endl;
while((c=cin.get())!=EOF)cout.put(c);return0;}2.帶一個參數的get函數格式:cin.get(字符變量)功能:從輸入流中提取一個字符賦予字符變量。如遇到文件結束符就返回0。例7.6.2把例7.6改寫如下:intmain(){charc;cout<<"enterasentence:"<<endl;
while(cin.get(c)){cout.put(c);}cout<<"end"<<endl;return0;}^Z表示ctrl+Z3.帶三個參數的get函數格式:cin.get(字符指針,n,終止字符)作用:輸入字符串函數從鍵盤緩沖區提取n-1個字符,順序放入字符指針所指的字符數組。如果在提取過程中遇到終止字符,則終止提取。終止字符默認為’\n’在提取的最后一個字符位置后會添加字符串結束標志’\0’。例7.6.3intmain(){charch[20];cout<<"enterasentence:"<<endl;cin.get(ch,10,‘\n’);//與cin.get(ch,10)相同cout<<ch<<endl;return0;}
cin.get()中不帶參數和只帶一個參數的函數,都是以文件結束符作為終止提取的控制符(輸入ctrl+z)。如果提取一個字符結束會把指針移到下一個字符。
cin.get()中帶三個參數的函數,以字符個數或者“終止提取字符”為終止提取的控制符。如遇到終止提取字符而終止提取的,則提取字符結束后指針會指向“終止提取字符”。cin.get()函數族不忽略提取的空白字符。#include<iostream>usingnamespacestd;intmain(){charch[20];chara;
cin.get(ch,10,'/');cin.get(a);cout<<ch<<endl;cout<<a;return0;}輸入情況一:1234567890輸出結果:1234567890輸入情況二:123456/789輸出結果:123456/4.用成員函數getline讀入一行字符格式:cin.getline(字符指針,n,終止字符)函數功能與帶三個參數的get函數類似:相同點:它們都不忽略提取過程中遇到的空白字符,當遇到終止字符時或者達到字符個數上限時就停止提取。終止字符的默認值是’\n’;區別:1:停止提取時,cin.getline會把指針移到終止字符后相鄰的字節,而帶三個參數的cin.get函數不會。2:當在遇到終止字符前已經達到字符個數時,cin.getline會把cin的狀態置為錯誤,而cin.get不會。cin的狀態可以用cin.good()得到,1表示正常,0表示錯誤。intmain(intargc,char*argv[]){ charch[20]; charc1;cout<<"輸入一句話:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;c1=cin.get();cout<<"第二次cin.get()提取的字符串是:"<<c1<<endl;cin.get(c1);cout<<"第三次cin.get(c1)提取的字符串是:"<<c1<<endl;cin.get(ch,20,'/');cout<<"第四次cin.get(ch,20,'/')提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第五次cin.getline(ch,20,'/')提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第六次cin.getline(ch,20,'/')提取的字符串是:"<<ch<<endl;return0;}#include<iostream>usingnamespacestd;intmain(){charch[20];chara;cin.getline(ch,10,'/');cout<<"cinstate:"<<cin.good()<<endl;cin.get(a);cout<<"ch:"<<ch<<endl;cout<<"a:"<<a<<endl;return0;}輸入情況一:1234567890輸出結果:cinstate:0ch:123456789a:請按任意鍵繼續...輸入情況二:123456/789輸出結果:cinstate:1ch:123456a:7請按任意鍵繼續...cin>>與cin.getline的區別
cin>>和cin.getline都具有從鍵盤緩沖區按指針所指提取字符串的功能。它們有以下區別:(1)cin>>忽略起始的空白字符;而cin.getline不忽略起始的空白字符。(2)cin>>當提取到非空白字符后,遇到空白字符時就終止提取,指針就停留在空白字符處;而cin.getline是提取到規定的終止字符或規定的字符個數后終止提取,指針停留在提取的最后一個字符后面相鄰的字節。(3)通過對>>的重載,cin可以提取其他類型的數據;而cin.getline只能輸入字符串。例7.7用成員函數getline讀入一行字符。#include<iostream>usingnamespacestd;voidmain(){charch[20];cout<<"輸入一句話:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;cin.getline(ch,20,'/');cout<<"第二次cin.getline提取的字符串是:"<<ch<<endl;cin.getline(ch,20);cout<<"第三次cin.getline提取的字符串是:"<<ch<<endl;}#include<iostream>usingnamespacestd;voidmain(){charch[20];cout<<"輸入一句話:"<<endl;cin>>ch;cout<<"第一次cin提取的字符串是:"<<ch<<endl;cin.get(ch,20,'/');cout<<"第二次cin.get提取的字符串是:"<<ch<<endl;cin.getline(ch,20);cout<<"第三次cin.getline提取的字符串是:"<<ch<<endl;}7.3.3istream類其他函數
eof()函數當輸入緩沖區的指針遇到文件結束符時函數值為真,否則顯假。從鍵盤用ctrl+z輸入文件結束符。例7.8從鍵盤輸入字符串,以文件結束符作為結束標志,逐個輸出非空格字符。#include<iostream>usingnamespacestd;voidmain(){charc;while(!cin.eof())if((c=cin.get())!='')//cout.put(c);cout<<c;}當(!cin.eof())(c=cin.get())!=''TF輸出C7.4文件操作和文件流7.4.1ASCII文件和二進制文件ASCII文件ASCII文件就是文本文件,每個字節表示一個字符,將內存中的數據按照字符的ascii碼形式存放到磁盤中(以可閱讀的形式將信息保存)。二進制文件二進制文件是把內存中的數據、指令按其在內存的格式存放在磁盤上。異同點:字符信息在內存也是以ASCII碼形式存放,所以字符在ASCII碼文件和在二進制文件中形式是一樣的。對于數值數據,兩者是不一樣的。數值的兩種文件保存方法舉例例如,一個十進制長整數100000,在內存中以四個字節存儲;保存成二進制文件:把這4個字節內容原樣寫到文件中。保存成ASCII文件:保存字符1和5個字符0的ascii碼到文件中7.4.2ASCII文件操作
——寫文件以輸出方式打開文件用流插入符寫文件關閉文件一個例子:ofstreamoutfile(“data.txt",ios::out);outfile<<100<<endl;outfile<<99.01<<endl;outfile<<"helloworld!"<<endl;outfile.close();#include<fstream>usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);outfile<<100<<endl;outfile<<99.01<<endl;outfile<<"helloworld!"<<endl;outfile.close();return0;}以上程序會在程序當前路徑上創建文件data.txt,然后在文件中寫上如下數據:10099.01helloworld!//文件輸出流對象ofstream在//文件fstream中聲明7.4.2ASCII文件操作
——寫文件練習:定義三個變量:英語成績,數學成績,語文成績,由用戶輸入此三個數字,然后將這三個成績保存到文件data.txt中以空格隔開。#include<fstream>//聲明流對象ofsteam的頭文件#include<iostream>//聲明流對象cout和cin的頭文件usingnamespacestd;intmain(){
ofstreamoutfile(“data.txt”,ios::out);//定義并打開一個輸出文件流對象floatscoreEng,scoreMath,scoreChn;cout<<"請輸入英語成績"<<endl;cin>>scoreEng;cout<<"請輸入數學成績"<<endl;cin>>scoreMath;cout<<"請輸入語文成績"<<endl;cin>>scoreChn;outfile<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl; outfile.close();return0;}7.4.2ASCII文件操作
——寫文件注意:用ios::out方式打開一個輸出文件,若沒有該文件,則會先創建一個新的文件。若已有此名字的文件,則會首先清除原有內容。舉例:想將文件data.txt中的內容清空。#include<fstream>//聲明流對象ofsteam的頭文件usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);//定義并打開一個輸出文件流對象 outfile.close();return0;}設想一下這樣一種情景:程序在某一文件中寫入了一些數據。程序關閉后,這時候操作者發覺少錄入了一些數據,需要往文件中再繼續寫入一些數據。這時候不能用ios::
out方式打開文件寫文件。需要用追加寫的方式。7.4.2ASCII文件操作
——追加寫文件以追加輸出的方式打開文件用流插入符寫文件關閉文件一個例子:假設文本文件data.txt中的數據為:10099.01helloworld!ofstreamoutfile(“data.txt",ios::app);outfile<<200<<''<<100.01<<''<<"helloworld!"<<endl;outfile.close();#include<fstream>usingnamespacestd;intmain(){ofstreamoutfile("data.txt",ios::app);//追加輸出方式outfile<<200<<''<<100.01<<''
<<"helloworld!"<<endl;outfile.close();return0;}以上程序會在文件data.txt末尾添加數據,程序運行后文件中的內容如下:10099.01helloworld!200100.01helloworld!//文件輸出流對象ofstream在//文件fstream中聲明用ios::app方式打開一個輸出文件,會將文件指針設置到文件末尾,寫文件的時候從文件末尾開始添加數據。若文件不存在,則會先創建一個新的文件。7.4.2ASCII文件操作
——讀文件以輸入方式打開文件用流提取符讀文件關閉文件一個例子:假設文本文件中的數據為10099.01helloworld!ifstreaminfile("data.txt",ios::in);intnum1;infile>>num1;doublenum2;infile>>num2;chartext[20];infile>>text;infile.close();#include<fstream>#include<iostream>usingnamespacestd;intmain(){
intnum1;doublenum2;chartext[20];
ifstreaminfile("data.txt",ios::in);infile>>num1;infile>>num2;infile>>text;infile.close();cout<<num1<<''<<num2<<''<<text<<endl;return0;}以上會輸出:10099.01helloworld!//文件輸出流對象ifstream在//文件fstream中聲明7.4.2ASCII文件操作
——讀文件練習:假設文本文件“data.txt”中的內容為:858095請定義三個變量:英語成績,數學成績,語文成績,將文件中的數據依次讀到這三個變量中,顯示這三個成績的值。#include<fstream>
//聲明流對象ofsteam的頭文件#include<iostream>
//聲明流對象cout和cin的頭文件usingnamespacestd;intmain(){
floatscoreEng;
floatscoreMath;
floatscoreChn;
ifstreaminfile(“data.txt”,ios::in);//定義并打開一個輸出文件流對象
infile>>scoreEng;
infile>>scoreMath;
infile>>scoreChn;
infile.close();
cout<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl;
return0;}7.4.2ASCII文件操作
——其它一些細節1:文件打開的兩種方式方法一:定義文件流對象的同時指定參數,如:
ifstreaminfile("data.txt",ios::in);方法二:調用文件流對象的成員函數open,如:ifstreaminfile;infile.open("data.txt",ios::in);2:可以調用文件流對象的put,get,getline成員函數進行讀寫。如:chartext[51];ifstreaminfile("data.txt",ios::in);infile.getline(text,50);//將文件data.txt中的第一行讀到text數組中。3:文件流對象的流插入和流提取運算符支持標準類型的數據。對于自定義的類類型數據的文件輸入輸出操作則需要自定義“運算符重載”函數。該重載函數通常以外部函數實現。7.4.2ASCII文件操作
——其它一些細節4:檢測文件打開是否失敗的方法有一些情況會造成文件打開失敗,典型的兩種情況如下:情況一:輸出方式打開一個文件時,若文件是只讀屬性的。判斷方法:若文件打開失敗,則文件流對象的類型轉換函數返回false,否則返回true。情況二:輸入方式打開一個文件時,若文件不存在。#include<fstream>#include<iostream>usingnamespacestd;intmain(){
ofstreamoutfile("data.txt",ios::out);
if(!outfile){cerr<<"Fileopenerror"<<endl;return-1;}outfile<<"helloworld!"<<endl;outfile.close();return0;}系統會自動轉為這種執行方式:!(outfile.operatorbool())當data.txt文件的屬性為只讀時,文件打開失敗,程序會輸出:Fileopenerror7.4.2ASCII文件操作
——綜合舉例例子:成績的輸入與輸出。1:定義一個成績類,包括數據成員:學號(字符串),英語成績,數學成績,語文成績;包括一個帶參數的構造函數和成績顯示函數。2:定義兩個外部函數,分別重載文件流插入和流提取運算符。3:定義一個主函數:其中先定義一個成績對象,將該對象的數據寫入文件中,再定義另外一個成績對象,將文件中的數據讀取到新定義的這個成績對象。顯示這兩個對象的信息。成績類命名為Score,類圖結構如右邊所示。id:學號scoreChn:語文成績scoreEng:英語成績scoreMath:數學成績display:成績顯示成員函數Score:構造函數#include<fstream>#include<iostream>usingnamespacestd;classScore{private:charid[20];floatscoreEng,scoreMath,scoreChn;public:Score(char*id,floateng=0,floatmath=0,floatchn=0):scoreEng(eng),scoreMath(math),scoreChn(chn){strcpy(this->id,id);}voiddisplay(){cout<<"學號:"<<id<<endl<<"英語成績:"<<scoreEng<<endl<<"數學成績:"<<scoreMath<<endl<<"語文成績:"<<scoreChn<<endl;}}
下一步要定義兩個外部運算符重載函數,需要訪問類的私有成員,怎么辦?將外部函數定義為類的友元。
friendofstream&operator<<(ofstream&outfile,Score&score);friendifstream&operator>>(ifstream&infile,Score&score);};ofstream&operator<<(ofstream&outfile,Score&score){outfile<<score.id<<''<<score.scoreEng<<''<<score.scoreMath<<''<<score.scoreChn;//在每個數據之后增加一個空格使得數據有分割returnoutfile;}ifstream&operator>>(ifstream&infile,Score&score){infile>>score.id>>score.scoreEng>>score.scoreMath>>score.scoreChn;returninfile;}1:為什么要返回流對象,可不可以不返回值?復習一下流運算符重載時的一些問題:為了進行連續流插入或者流提取操作,如outfile<<score1<<score2;2:為什么不能定義為類的成員函數。雙目運算符在重載為類的成員函數后,在使用時左操作數必須為類對象。即需要這樣寫score1<<outfile。不符合習慣用法。3:參數為何使用引用類型?若定義為類類型,則會調用拷貝構造函數生成新的對象,增加了程序的開銷。intmain(){Scorescore1(“0”,80,90,70),score2(“1”);//定義兩個成績對象
ofstreamoutfile(“data.txt”,ios::out);//定義一個文件輸出流對象if(!outfile)//若打開失敗則結束程序{cout<<"FileopenError"<<endl;return-1;}outfile<<score1;//成績對象1寫文件outfile.close();ifstreaminfile(“data.txt”,ios::in);//定義一個文件輸入流對象if(!infile)//若打開失敗則結束程序{cout<<"FileopenError"<<endl;return-1;}infile>>score2;//將數據讀到成績對象2中
infile.close();score1.display();score2.display();return0;}程序輸出結果:學號:0英語成績:80數學成績:90語文成績:70學號:0英語成績:80數學成績:90語文成績:707.4.3二進制文件操作read成員函數和write成員函數的原型分別是:istream&read(char*bu,intlen);ostream&write(constchar*bu,intlen);字符指針bu指向內存要讀或寫的數據起始位置。len是一次要讀寫的數據字節個數(數據長度)。調用格式:輸入文件流對象.read(內存首地址,字節數);
輸出文件流對象.write(內存首地址,字節數);二進制文件不用流插入運算符和流提取運算符讀寫文件,而用成員函數read和write讀寫文件。7.4.3二進制文件操作
——寫文件以二進制方式打開文件用成員函數write寫文件關閉文件一個例子:ofstreamoutfile(“data.bin”,ios::binary);intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();#include<fstream>usingnamespacestd;intmain(){intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";
ofstreamoutfile("data.bin",ios::binary);outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();return0;}以上程序會在程序當前路徑上創建文件data.bin,然后在文件中將num1,num2,text在內存中的二進制數據寫入文件。//文件輸出流對象ofstream在//文件fstream中聲明7.4.3二進制文件操作
——寫文件練習:定義三個變量:英語成績,數學成績,語文成績,由用戶輸入此三個數字,然后將這三個成績保存到二進制文件data.bin中。#include<fstream>//聲明流對象ofsteam的頭文件#include<iostream>//聲明流對象cout和cin的頭文件usingnamespacestd;intmain(){
ofstreamoutfile(“data.bin”,ios::binary);//定義并打開一個輸出文件流對象floatscoreEng,scoreMath,scoreChn;cout<<"請輸入英語成績"<<endl;cin>>scoreEng;cout<<"請輸入數學成績"<<endl;cin>>scoreMath;cout<<"請輸入語文成績"<<endl;cin>>scoreChn;outfile.write((char*)&scoreEng,sizeof(float));outfile.write((char*)&scoreMath,sizeof(float));outfile.write((char*)&scoreChn,sizeof(float));outfile.close();return0;}7.4.3二進制文件操作
——寫文件注意:用ios::binary方式打開一個輸出文件,若沒有該文件,則會先創建一個新的文件。若已有此名字的文件,則會首先清除原有內容。舉例:想將文件data.bin中的內容清空。#include<fstream>//聲明流對象ofsteam的頭文件usingnamespacestd;intmain(){ofstreamoutfile("data.bin",ios::binary);//定義并打開一個輸出文件流對象outfile.close();return0;}設想一下這樣一種情景:程序在某一文件中寫入了一些數據。程序關閉后,這時候操作者發覺少錄入了一些數據,需要往文件中再繼續寫入一些數據。這時候不能用ios::
binary方式打開文件寫文件。需要用追加二進制寫的方式。7.4.3二進制文件操作
——追加寫文件以追加輸出和二進制方式打開文件用成員函數write寫文件關閉文件一個例子:ofstreamoutfile(“data.bin”,ios::binary|ios::app);intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();#include<fstream>usingnamespacestd;intmain(){intnum1=100;doublenum2=99.01;chartext[20]="helloworld!";
ofstreamoutfile("data.bin",ios::app|ios::binary);outfile.write((char*)&num1,sizeof(int));outfile.write((char*)&num2,sizeof(double));outfile.write((char*)text,sizeof(text));outfile.close();return0;}//文件輸出流對象ofstream在//文件fstream中聲明以上程序會在文件data.bin末尾添加數據。原有的數據不會刪除。7.4.3二進制文件操作
——讀文件以二進制方式打開文件用成員函數read讀文件關閉文件一個例子:假設二進制文件中的保存有一個整數100一個雙精度數99.01和一個20個元素的字符數組helloworld!ifstreaminfile("data.txt",ios::binary);intnum1;infile.read((char*)&num1,sizeof(int));doublenum2;infile.read((char*)&num2,sizeof(double));chartext[20];infile.read((char*)text,sizeof(text));infile.close();#include<fstream>#include<iostream>usingnamespacestd;intmain(){intnum1;doublenum2;chartext[20];ifstreaminfile("data.bin",ios::binary);infile.read((char*)&num1,sizeof(int));infile.read((char*)&num2,sizeof(double));infile.read((char*)text,sizeof(text));infile.close();cout<<num1<<''<<num2<<''<<text;return0;}以上會輸出:10099.01helloworld!7.4.3二進制文件操作
——讀文件練習:假設二進制文件“data.bin”中的內容為:三個單精度浮點數的二進制形式,兩個數字之間以空格隔開,三個數分別為85,80,95請定義三個變量:英語成績,數學成績,語文成績,將文件中的數據依次讀到這三個變量中,顯示這三個成績的值。#include<fstream>//聲明流對象ofsteam的頭文件#include<iostream>//聲明流對象cout和cin的頭文件usingnamespacestd;intmain(){floatscoreEng;floatscoreMath;floatscoreChn;ifstreaminfile("data.bin",ios::binary);//定義并打開一個輸出文件流對象infile.read((char*)&scoreEng,sizeof(float));infile.read((char*)&scoreMath,sizeof(float));infile.read((char*)&scoreChn,sizeof(float));infile.close();cout<<scoreEng<<''<<scoreMath<<''<<scoreChn<<endl;return0;}7.4.3二進制文件操作
——其它一些細節1:文件打開的兩種方式方法一:定義文件流對象的同時指定參數,如:
ifstreaminfile("data.bin",ios::binary);方法二:調用文件流對象的成員函數open,如:ifstreaminfile;infile.open("data.bin",ios::binary);2:檢測文件打開是否失敗的方法判斷方法:若文件打開失敗,則文件流對象的類型轉換函數返回false,否則返回true。1和2的規則同ASCII文件的操作規則3:以可讀可寫的方式打開需要用類fstream的對象進行操作,打開方式要寫ios::binary|ios::in|ios::out。如:fstreamiofile("data.txt",ios::binary|ios::in|ios::out);7.4.4二進制文件操作
——隨機訪問文件二進制文件讀寫的時候用戶可以設置讀寫的位置,在指定位置執行讀寫操作。什么是隨機訪問?二進制文件的讀寫位置如何指定?g:get(輸入操作)p:put(輸出操作)以字節數計量位置,有以下成員函數提供位置設置與查詢功能7.4.4二進制文件操作
——隨機訪問文件參照位置表示以什么作為移動起點。
ios::beg以文件開始為起點,這是默認值。
ios::cur以指針當前位置為起點。
ios::end
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 一季度GDP大超預期怎么看、怎么辦
- PHP程序設計項目化教程電子教案9 文本內容過濾器-數據處理
- 2025年電動釣魚船項目可行性研究報告
- 2025年球類推車項目可行性研究報告
- 山東旅游職業學院《地質與文化遺產概況》2023-2024學年第一學期期末試卷
- 昆明市重點中學2025年高三畢業班3月份摸底調研考試生物試題含解析
- 上海交大南洋中學2025屆高三第二次診斷考試生物試題含解析
- 華北理工大學冀唐學院《品牌傳播龐鐵明》2023-2024學年第二學期期末試卷
- 2025春新版【一年級下冊語文】 全冊1-8單元成語解釋
- 長春建筑學院《工科大學化學-無機與結構化學基礎B》2023-2024學年第二學期期末試卷
- 新疆地方教材五年級可愛的中國計劃、教案
- 小白兔拔蘿卜課件
- 2023年河南推拿職業學院單招考試面試模擬試題及答案解析
- 警械的正確使用以及法律適用課件
- 高頻變壓器外觀檢驗標準課件
- 火災調查 學習指南
- 2021年新湘教版九年級數學中考總復習教案
- EGS002:EG8010+IR2110m正弦波逆變器AD16電路圖印制板圖
- 試析水穩填充大粒徑碎石基層的全過程施工工藝
- 廣東省行政執法資格考試題庫(共80頁)
- 英語科技論文寫作ppt課件(PPT 65頁)
評論
0/150
提交評論