![C第10章流類庫和輸入輸出課件_第1頁](http://file4.renrendoc.com/view/00760c16138bf86be4227ea558c2f0f6/00760c16138bf86be4227ea558c2f0f61.gif)
![C第10章流類庫和輸入輸出課件_第2頁](http://file4.renrendoc.com/view/00760c16138bf86be4227ea558c2f0f6/00760c16138bf86be4227ea558c2f0f62.gif)
![C第10章流類庫和輸入輸出課件_第3頁](http://file4.renrendoc.com/view/00760c16138bf86be4227ea558c2f0f6/00760c16138bf86be4227ea558c2f0f63.gif)
![C第10章流類庫和輸入輸出課件_第4頁](http://file4.renrendoc.com/view/00760c16138bf86be4227ea558c2f0f6/00760c16138bf86be4227ea558c2f0f64.gif)
![C第10章流類庫和輸入輸出課件_第5頁](http://file4.renrendoc.com/view/00760c16138bf86be4227ea558c2f0f6/00760c16138bf86be4227ea558c2f0f65.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第10章流類庫和輸入輸出
本章要點本章要點10.1C++的基本流類體系basic_iosbasic_streambufbasic_istreambasic_ostreambasic_ifstreambasic_iostreambasic_ofstreambasic_fstream指針10.1C++的基本流類體系basic_iosbasicC++的基本流類體系說明(*)basic_streambuf不是basic_ios的派生類,而是一個獨立的類,只是basic_ios有一個保護訪問限制的指針指向它,其作用是管理一個流的緩沖區(qū)。basic_ios類模板提供了對流進行格式化輸入輸出和錯誤處理的成員函數(shù)。basic_istream類模板提供完成提取(輸入)操作的成員函數(shù),basic_ostream類模板提供完成插入(輸出)操作的成員函數(shù)。basic_iostream類是前兩者的聚合,并沒有增加成員。*從技術(shù)上講,模板并不能派生。但是這些模板只是預先定義了數(shù)據(jù)類型(如char或wchar_t等等)的模板實例,所以可以繼承。C++的基本流類體系說明(*)basic_streambuf標準輸入/輸出流對象在C++的流類庫中定義了四個全局流對象:cin,cout,cerr和clog。cin標準輸入流對象,鍵盤為其對應的標準設(shè)備。cout、cerr和clog都是標準輸出流對象,顯示器為標準輸出設(shè)備。標準輸入/輸出流對象在C++的流類庫中定義了四個全局流對象:標準輸出流對象的區(qū)別對象名是否使用緩沖區(qū)是否可以重定向cout是是clog是否cerr否否注:這里的區(qū)別與頭文件、編譯環(huán)境和運行環(huán)境都有較大影響,具體細節(jié)非常復雜。標準輸出流對象的區(qū)別對象名是否使用緩沖區(qū)是否可以重定向coucerr對象的不緩沖特性(*) #include<iostream.h>//傳統(tǒng)頭文件 intmain() { inti=0,j; cerr<<“SEU”;//更換cout和clog對比 j=5/i; return0; }cerr對象的不緩沖特性(*) #include<iostcout的重定向(*) #include<iostream> usingnamespacestd; intmain() { cout<<"SEU\n"; cerr<<"NJU\n"; clog<<"PKU\n"; return0;}//命令行方式下運行**.exe>>**.txtcout的重定向(*) #include<iostream提取運算符和插入運算符提取運算符“>>”(stream_extractionoperator)和插入運算符“<<”(stream_insertionoperator),執(zhí)行輸入/輸出操作。
“提取”的含義是指輸入操作,可看作從流中提取一個字符序列。
“插入”的含義是指輸出操作,可看作向流中插入一個字符序列。提取運算符和插入運算符提取運算符“>>”(stream_ex重載插入和提取運算符插入和提取運算符只能重載為類的友元函數(shù)提取運算符重載格式:friendistream&operator>>(istream&,className&);插入運算符重載格式:friendostream&operator<<(ostream&,className&);流對象作為返回值和參數(shù)必須是引用?。?!重載插入和提取運算符插入和提取運算符只能重載為類的友元函數(shù)插入運算符重載:mystring類重載插入運算符“<<”聲明為mystring的友元: friendostream&operator<<(ostream&,constmystring&);
定義為: ostream&operator<<(ostream&s,constmystring&cstr) {returns<<cstr.str<<'\t';}插入運算符重載:mystring類重載插入運算符“<<”聲明插入運算符重載:Orderedlist類 template<typename
T,intsize>void<T,size>::print(){inti; for(i=0;i<=last;i++) { cout<<slist[i].key;//這句是關(guān)鍵 if(i%5==4)cout<<endl;} cout<<endl; }插入運算符重載:Orderedlist類 template插入運算符重載:復數(shù)類 ostream&operator<<(ostream&s,constComplex&z) {
returns<<'('<<z.Real<<','<<z.Image<<')';}插入運算符重載:復數(shù)類 ostream&operator<<提取運算符重載:復數(shù)類 istream&operator>>(istream&s,Complex&a){
//格式為d,(d),(d,d)
doublere=0,im=0;charc=0;s>>c;
if(c=='('){//是否由括號開始
s>>re>>c;//實部
if(c==',')s>>im>>c;//虛部
if(c!=')')s.clear(ios::failbit);}
//漏了括號給一個操作失敗標志
else{s.putback(c);//無括號,返回一個字符到輸入緩沖區(qū)
s>>re;}//實數(shù)
if(s)a=Complex(re,im);returns;}提取運算符重載:復數(shù)類 istream&operator>>提取運算符重載:復數(shù)類分析課本上的這個例子,覺得有什么優(yōu)點和不足?優(yōu)點:考慮了多種的實際情況,有一定的健壯性缺點:在輸入之前沒有提示,程序不夠友好在實驗當中給出自己的修改意見提取運算符重載:復數(shù)類分析課本上的這個例子,覺得有什么優(yōu)點和提高標準輸入/輸出的穩(wěn)健性cin為緩沖流。如果輸入錯了,回車鍵按下就無法挽回了。只有把數(shù)據(jù)取完后,才能重來。輸入的數(shù)據(jù)類型必須與要提取的數(shù)據(jù)類型一致,否則出錯。出錯只是在流的狀態(tài)字state中對應位置位,要重來必須重置狀態(tài)??崭?、回車和制表符可以用來分隔數(shù)值數(shù)據(jù),但無法分隔字符和字符串。特別需要注意在輸入字符和字符串之前的操作。提高標準輸入/輸出的穩(wěn)健性cin為緩沖流。如果輸入錯了,回車程序健壯性的示例:輸入成績 intscore; do { cout<<"請輸入您的分數(shù):"; cin>>score; }while(score<0||score>100);
猜測:如果輸入一個字符a,后果是?程序健壯性的示例:輸入成績提高程序健壯性:掌控流狀態(tài)
狀態(tài)字state為整型
enumios_state{goodbit=0x00, //流正常
eofbit=0x01,
//輸入流結(jié)束或文件結(jié)束已無數(shù)據(jù)可取
failbit=0x02, //最近的I/O操作失敗,流可恢復
badbit=0x04, //最近的I/O操作非法,流可恢復
hardfail=0x08//I/O出現(xiàn)致命錯誤,流不可恢復}提高程序健壯性:掌控流狀態(tài) 狀態(tài)字state為整型提高程序健壯性:掌控流狀態(tài)
讀取狀態(tài)的有關(guān)操作如下:inlineintios::rdstate()const{returnstate;}
//讀取狀態(tài)字inlineintios:operator!()const{returnstate&(badbit|failbit);}
//可用操作符!()代替fail()inlineintios::bad(){returnstate&badbit;}
//返回非法操作位提高程序健壯性:掌控流狀態(tài) 讀取狀態(tài)的有關(guān)操作如下:提高程序健壯性:掌控流狀態(tài)inlinevoidios::clear(int_i){lock();state=_i;unlock();}
//人工設(shè)置狀態(tài),可用來清狀態(tài)inlineintios::eof()const{returnstate&eofbit;}
//返回流(文件)結(jié)束位inlineintios::fail()const{returnstate&(badbit|failbit);}
//返回操作非法和操作失敗這兩位inlineintios::good()const{returnstate==0;}
//正常返回1,否則返回0提高程序健壯性:掌控流狀態(tài)inlinevoidios::程序健壯性的示例:輸入成績 intscore; do { cin.clear(); cout<<"請輸入您的分數(shù):"; cin>>score; }while(score<0||score>100);
猜測:這樣的改進有用嗎?程序健壯性的示例:輸入成績提高程序健壯性:清空緩沖區(qū)方法一、用cin.getline()等方式提走緩沖區(qū)內(nèi)容 do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.getline(s,100);//chars[100]; }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法一、用cin.getline(提高程序健壯性:清空緩沖區(qū)方法二、使用函數(shù)cin.ignore()提取緩沖區(qū)內(nèi)容 do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.ignore(255,'\n'); }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法二、使用函數(shù)cin.ignor提高程序健壯性:清空緩沖區(qū)方法三、使用函數(shù)cin.sync()清空輸入緩沖區(qū) do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.sync(); }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法三、使用函數(shù)cin.sync(標準輸入/輸出成員函數(shù)intistream::get();istream&istream::get(char&);istream&istream::get(char*,int,char=’\n’);//不提取終止符istream&istream::getline(char*,int,char=’\n’);
//提取終止符并丟棄
提示:如果是超出數(shù)量而結(jié)束字符串輸入,需要重置流狀態(tài)。標準輸入/輸出成員函數(shù)intistream::get();標準輸入/輸出成員函數(shù) chars[100]; intnum; cin.getline(s,2,‘#’);//如輸入abcd# cout<<s<<endl;
cin.clear(0);cin.sync();//必須寫這兩句 cin>>num; cout<<num<<endl;標準輸入/輸出成員函數(shù) chars[100];10.2文件的輸入與輸出C++根據(jù)文件(file)內(nèi)容的數(shù)據(jù)格式,可分為兩類:二進制文件和文本文件。文本文件由字符序列組成,也稱ASCII碼文件,在文本文件中存取的最小信息單位為字符(character),而二進制文件中存取的最小信息單位為字節(jié)(Byte)。文本文件的讀寫容易理解,二進制文件讀寫效率較高。讀寫文件需包含頭文件fstream10.2文件的輸入與輸出C++根據(jù)文件(file)內(nèi)容的數(shù)讀寫文件四部曲1、定義文件對象,根據(jù)讀寫方式區(qū)分 ifstreamifile;//只輸入用 ofstreamofile;//只輸出用 fstreamiofile;//既輸入又輸出用
讀寫文件四部曲1、定義文件對象,根據(jù)讀寫方式區(qū)分讀寫文件四部曲2、使用文件流對象的成員函數(shù)打開一個磁盤文件。這樣在文件流對象和磁盤文件名之間建立聯(lián)系。以ifstream類為例: void
ifstream::open(const
char*,int=ios::in,int=);
其中參數(shù)一是字符串形式的文件名,參數(shù)二是打開方式,參數(shù)三一般使用默認值。
注意:如果文件名中包含路徑,\符號必須連續(xù)使用,如d:\\my.txt 讀寫文件四部曲2、使用文件流對象的成員函數(shù)打開一個磁盤文件。讀寫文件的打開方式打開方式讀/寫說明ios::in只讀方式文件不存在報錯ios::out只寫方式文件存在覆蓋ios::ate定位到尾部等待后續(xù)操作ios::app只寫追加方式文件存在繼續(xù)寫ios::trunc覆蓋方式ios::binary二進制必須讀寫文件的打開方式打開方式讀/寫說明ios::in只讀方式文讀寫文件的四部曲三個文件流類都重載了一個帶默認參數(shù)的構(gòu)造函數(shù),功能與open函數(shù)一樣:ifstream::ifstream(const
char*,int=ios::in,
int=);ofstream::ofstream(const
char*,int=ios::out,
int=);fstream::fstream(constchar*,int,
int=);讀寫文件的四部曲三個文件流類都重載了一個帶默認參數(shù)的構(gòu)造函數(shù)讀寫文件的四部曲打開文件也應該判斷是否成功,若成功,文件流對象值為非零值,不成功為0(NULL)。因此打開一個文件完整的程序為: fstreamiofile(”my”,ios::in|ios::out); if(!iofile){//“!”為重載的運算符,見9.3.1節(jié) cout<<”不能打開文件:”<<”my”<<endl; return-1;
}//失敗退回讀寫文件的四部曲打開文件也應該判斷是否成功,若成功,文件流對文本文件的讀寫如果將鍵盤和顯示器看成特殊的文件,那么我們熟練的輸入輸出和文件讀寫就可以統(tǒng)一概念了。輸入和讀文件本質(zhì)上是一致的;輸出和寫文件本質(zhì)上是一致的。因此之前熟悉的運算符和函數(shù)都幾乎可以直接用于文本文件的讀寫。文本文件的讀寫如果將鍵盤和顯示器看成特殊的文件,那么我們熟練文本讀寫——按字符復制文件
intmain(){
charch;ifstreamsfile("d:\\1.txt"); ofstreamdfile("d:\\2.txt"); if(!sfile){cout<<"不能打開源文件:"<<endl; return-1;}文本讀寫——按字符復制文件 intmain(){文本讀寫——按字符復制文件 if(!dfile){ cout<<"不能打開目標文件:"<<endl;
return-1;}s(ios::skipws);
//關(guān)鍵!把跳過空白控制位置0,即不跳過空白格
while(sfile>>ch)dfile<<ch;s();//如沒有這兩個關(guān)閉函數(shù),析構(gòu)函數(shù)也可關(guān)閉
d();return0;}文本讀寫——按字符復制文件 if(!dfile){文本讀寫——按字符復制文件1、使用默認的>>獲取字符時,會跳過空白符號。除了選擇關(guān)閉設(shè)置之外,可以用s(ch)來代替即可。2、當讀到文件尾部之后,流對象sfile進入eof狀態(tài),在循環(huán)判斷中會被判斷為NULL,因此循環(huán)停止。3、本算法可以復制所有文件,但效率較低。文本讀寫——按字符復制文件1、使用默認的>>獲取字符時,會跳文本讀寫——按行復制文件chars[2];//極端測試
do {
i(s,2); if(i()==0) ofile<<s<<endl; elseif(i()==4){ i();ofile<<s; } else{ ofile<<s; break;} }while(1);文本讀寫——按行復制文件chars[2];//極端測試 文本讀寫——按行復制文件1、通過默認符號\n終止讀取的,則流狀態(tài)正常,但因為getline不提取回車符,在復制時需要手工補上。2、通過字符上限終止讀取的,流狀態(tài)變成fail,需要將其置為正常才能繼續(xù)。3、該算法效率較高,但不適合二進制文件,因為二進制文件根本沒有行。文本讀寫——按行復制文件1、通過默認符號\n終止讀取的,則流文本文件讀寫總結(jié)基本上,文本文件的讀寫和輸入輸出的使用是很相近的,大部分函數(shù)和符號可以直接通用。提取和插入運算符的重載也可以用于文件對象,用于將類的內(nèi)容從文件輸入或?qū)懭胛募Wx文件的時候,需要注意判斷文件流的狀態(tài)。文本文件讀寫總結(jié)基本上,文本文件的讀寫和輸入輸出的使用是很相文本文件讀寫和運算符
classMoney {
intyuan,jiao,fen;
public: Money(inty=0,intj=0,intf=0) {yuan=y;jiao=j;fen=f;}
friendistream&operator>>(istream&is,Money&m);
friendostream&operator<<(ostream&os,Money&m); };文本文件讀寫和運算符 classMoney文本文件讀寫和運算符istream&operator>>(istream&is,Money&m) { is>>m.yuan>>m.jiao>>m.fen; returnis; }ostream&operator<<(ostream&os,Money&m) { os<<m.yuan<<‘\t’<<m.jiao<<‘\t’<<m.fen;//輸出的時候要分割 returnos; }文本文件讀寫和運算符istream&operator>>(文本文件讀寫和運算符 intmain(){ Moneym1;cin>>m1;cout<<m1<<endl;//重載輸入輸出 ofstreamofile("my.txt",ios::out); ofile<<m1;o();//輸出到文件 ifstreamifile("my.txt",ios::out); ifile>>m1;i();//從文件讀入數(shù)據(jù) cout<<m1;}文本文件讀寫和運算符 intmain(){文本文件讀寫和運算符重載 istream&operator>>(istream&is,Money&m) { if(&is==&cin)//如果是默認的cin對象 cout<<"請依次輸入元、角和分的值,用空格分割,回車符確認:"; is>>m.yuan>>m.jiao>>m.fen; returnis; }文本文件讀寫和運算符重載 istream&operator二進制文件讀寫istream&istream::read(char*,int); //從二進制流提取個若干個字節(jié),送入第一個參數(shù)地址開始的單元ostream&ostream::write(const
char*,int);//從第一個參數(shù)地址讀取若干個字節(jié),寫入文件流當中二進制文件讀寫istream&istream::read(c二進制文件讀寫 voidWriteTo&ofile); voidReadFrom&ifile); voidshow()//原始的show函數(shù) { cout<<yuan<<'\t'<<jiao<<'\t'<<fen<<endl; }二進制文件讀寫 voidWriteTo&ofile);二進制文件讀寫 voidMoney::WriteTo&ofile) { o((char*)&yuan,sizeof(yuan)); o((char*)&jiao,sizeof(jiao)); o((char*)&fen,sizeof(fen)); o(); }二進制文件讀寫 voidMoney::WriteTo&o二進制文件讀寫 voidMoney::ReadFrom&ifile) { i((char*)&yuan,sizeof(yuan)); i((char*)&jiao,sizeof(jiao)); i((char*)&fen,sizeof(fen)); i(); }二進制文件讀寫二進制文件讀寫 intmain() {Moneym1(1,2,3),m2; ofstreamofile("my.dat",ios::binary); ifstreamifile("my.dat",ios::binary); m1.WriteTo); m2.ReadFrom); m2.show(); return0;}二進制文件讀寫 intmain()二進制文件和文本文件讀寫二進制文件可以控制字節(jié)長度,讀寫數(shù)據(jù)時不會出現(xiàn)二義性,可靠性高。對于復雜數(shù)據(jù),如數(shù)組、結(jié)構(gòu)體、對象等,讀寫方便。二進制文件保密性好,必須知道寫文件的過程才能知道如何讀取。二進制文件體積也較小,因此在實際過程中往往首選二進制文件。二進制文件和文本文件讀寫二進制文件可以控制字節(jié)長度,讀寫數(shù)據(jù)讀文件時的順序問題 ofstreamofile("d:\\1.dat",ios::binary); inti; for(i=1;i<=10;i++) o((char*)&i,sizeof(i)); o();讀文件時的順序問題 ofstreamofile("d:\\讀文件時的順序問題 ifstreamifile("d:\\1.dat",ios::binary); intx; while(ifile)//或者while(i()==0) { i((char*)&x,sizeof(x)); cout<<x<<endl; } i();//這個代碼的結(jié)果是??讀文件時的順序問題 ifstreamifile("d:\\讀文件時的順序問題上述代碼會多讀出一個10出來!正確寫法之一: while(i((char*)&x,sizeof(x))) cout<<x<<endl;正確寫法之二: do{ i((char*)&x,sizeof(x)); if(!i; cout<<x<<endl; }while(1);讀文件時的順序問題上述代碼會多讀出一個10出來!讀文件的順序問題當讀到文件尾部的時候,數(shù)據(jù)應該是結(jié)束了。但此時eof并不為真,除非再做一次讀操作才會。第一個錯誤代碼當中,多做了一次循環(huán),在循環(huán)中沒有讀到任何內(nèi)容,x保留上一次的值,因此10重復出現(xiàn)了。合理的方案是:先做讀操作,馬上緊跟判斷。讀文件的順序問題當讀到文件尾部的時候,數(shù)據(jù)應該是結(jié)束了。但此文件的隨機讀寫(*)之前對文件的讀寫,都是從文件頭順序操作到文件尾,但有時我們需要靈活的對讀寫位置定位。讀寫位置的定位通過兩組共6個函數(shù)完成。istream&istream::seekg(streampos); istream&istream::seekg(streamoff,ios::seek_dir); longistream::tellg();
對于ostream中的函數(shù)只需要將g改p即可。
文件的隨機讀寫(*)之前對文件的讀寫,都是從文件頭順序操作到指針相對定位ios::seek_dir枚舉參數(shù)意義注明ios::cur當前位置可用tell獲取ios::beg文件起點位移只能為正ios::end文件中點位移只能為負指針相對定位ios::seek_dir枚舉參數(shù)意義注明ios例:獲得任一文件的大小 ifstreamifile("d:\\1.dat",ios::binary); i(0,ios::end);//定位到最后 cout<<i();//讀出位置的偏移值例:獲得任一文件的大小 ifstreamifile("d:例:數(shù)組的隨機讀寫 //文件讀寫一般對二進制文件適合 ofstreamofile("d:\\1.dat",ios::binary); inta[10]={1,2,3,4,5,6,7,8,9,10},i,x; o((char*)a,sizeof(a)); o();例:數(shù)組的隨機讀寫 //文件讀寫一般對二進制文件適合例:數(shù)組的隨機讀寫 //只讀取偶數(shù)下標的數(shù)據(jù),即1,3,5,7,9 ifstreamifile("d:\\1.dat",ios::binary); for(i=0;i<5;i++) {i(i*2*sizeof(a[0]),ios::beg); i((char*)&x,sizeof(x)); cout<<x<<endl;} i();例:數(shù)組的隨機讀寫 //只讀取偶數(shù)下標的數(shù)據(jù),即1,3,5,寫在最后成功的基礎(chǔ)在于好的學習習慣Thefoundationofsuccessliesingoodhabits59寫在最后成功的基礎(chǔ)在于好的學習習慣59結(jié)束語當你盡了自己的最大努力時,失敗也是偉大的,所以不要放棄,堅持就是正確的。WhenYouDoYourBest,FailureIsGreat,SoDon'TGiveUp,StickToTheEnd演講人:XXXXXX時間:XX年XX月XX日
結(jié)束語60第10章流類庫和輸入輸出
本章要點本章要點10.1C++的基本流類體系basic_iosbasic_streambufbasic_istreambasic_ostreambasic_ifstreambasic_iostreambasic_ofstreambasic_fstream指針10.1C++的基本流類體系basic_iosbasicC++的基本流類體系說明(*)basic_streambuf不是basic_ios的派生類,而是一個獨立的類,只是basic_ios有一個保護訪問限制的指針指向它,其作用是管理一個流的緩沖區(qū)。basic_ios類模板提供了對流進行格式化輸入輸出和錯誤處理的成員函數(shù)。basic_istream類模板提供完成提取(輸入)操作的成員函數(shù),basic_ostream類模板提供完成插入(輸出)操作的成員函數(shù)。basic_iostream類是前兩者的聚合,并沒有增加成員。*從技術(shù)上講,模板并不能派生。但是這些模板只是預先定義了數(shù)據(jù)類型(如char或wchar_t等等)的模板實例,所以可以繼承。C++的基本流類體系說明(*)basic_streambuf標準輸入/輸出流對象在C++的流類庫中定義了四個全局流對象:cin,cout,cerr和clog。cin標準輸入流對象,鍵盤為其對應的標準設(shè)備。cout、cerr和clog都是標準輸出流對象,顯示器為標準輸出設(shè)備。標準輸入/輸出流對象在C++的流類庫中定義了四個全局流對象:標準輸出流對象的區(qū)別對象名是否使用緩沖區(qū)是否可以重定向cout是是clog是否cerr否否注:這里的區(qū)別與頭文件、編譯環(huán)境和運行環(huán)境都有較大影響,具體細節(jié)非常復雜。標準輸出流對象的區(qū)別對象名是否使用緩沖區(qū)是否可以重定向coucerr對象的不緩沖特性(*) #include<iostream.h>//傳統(tǒng)頭文件 intmain() { inti=0,j; cerr<<“SEU”;//更換cout和clog對比 j=5/i; return0; }cerr對象的不緩沖特性(*) #include<iostcout的重定向(*) #include<iostream> usingnamespacestd; intmain() { cout<<"SEU\n"; cerr<<"NJU\n"; clog<<"PKU\n"; return0;}//命令行方式下運行**.exe>>**.txtcout的重定向(*) #include<iostream提取運算符和插入運算符提取運算符“>>”(stream_extractionoperator)和插入運算符“<<”(stream_insertionoperator),執(zhí)行輸入/輸出操作。
“提取”的含義是指輸入操作,可看作從流中提取一個字符序列。
“插入”的含義是指輸出操作,可看作向流中插入一個字符序列。提取運算符和插入運算符提取運算符“>>”(stream_ex重載插入和提取運算符插入和提取運算符只能重載為類的友元函數(shù)提取運算符重載格式:friendistream&operator>>(istream&,className&);插入運算符重載格式:friendostream&operator<<(ostream&,className&);流對象作為返回值和參數(shù)必須是引用?。?!重載插入和提取運算符插入和提取運算符只能重載為類的友元函數(shù)插入運算符重載:mystring類重載插入運算符“<<”聲明為mystring的友元: friendostream&operator<<(ostream&,constmystring&);
定義為: ostream&operator<<(ostream&s,constmystring&cstr) {returns<<cstr.str<<'\t';}插入運算符重載:mystring類重載插入運算符“<<”聲明插入運算符重載:Orderedlist類 template<typename
T,intsize>void<T,size>::print(){inti; for(i=0;i<=last;i++) { cout<<slist[i].key;//這句是關(guān)鍵 if(i%5==4)cout<<endl;} cout<<endl; }插入運算符重載:Orderedlist類 template插入運算符重載:復數(shù)類 ostream&operator<<(ostream&s,constComplex&z) {
returns<<'('<<z.Real<<','<<z.Image<<')';}插入運算符重載:復數(shù)類 ostream&operator<<提取運算符重載:復數(shù)類 istream&operator>>(istream&s,Complex&a){
//格式為d,(d),(d,d)
doublere=0,im=0;charc=0;s>>c;
if(c=='('){//是否由括號開始
s>>re>>c;//實部
if(c==',')s>>im>>c;//虛部
if(c!=')')s.clear(ios::failbit);}
//漏了括號給一個操作失敗標志
else{s.putback(c);//無括號,返回一個字符到輸入緩沖區(qū)
s>>re;}//實數(shù)
if(s)a=Complex(re,im);returns;}提取運算符重載:復數(shù)類 istream&operator>>提取運算符重載:復數(shù)類分析課本上的這個例子,覺得有什么優(yōu)點和不足?優(yōu)點:考慮了多種的實際情況,有一定的健壯性缺點:在輸入之前沒有提示,程序不夠友好在實驗當中給出自己的修改意見提取運算符重載:復數(shù)類分析課本上的這個例子,覺得有什么優(yōu)點和提高標準輸入/輸出的穩(wěn)健性cin為緩沖流。如果輸入錯了,回車鍵按下就無法挽回了。只有把數(shù)據(jù)取完后,才能重來。輸入的數(shù)據(jù)類型必須與要提取的數(shù)據(jù)類型一致,否則出錯。出錯只是在流的狀態(tài)字state中對應位置位,要重來必須重置狀態(tài)??崭瘛⒒剀嚭椭票矸梢杂脕矸指魯?shù)值數(shù)據(jù),但無法分隔字符和字符串。特別需要注意在輸入字符和字符串之前的操作。提高標準輸入/輸出的穩(wěn)健性cin為緩沖流。如果輸入錯了,回車程序健壯性的示例:輸入成績 intscore; do { cout<<"請輸入您的分數(shù):"; cin>>score; }while(score<0||score>100);
猜測:如果輸入一個字符a,后果是?程序健壯性的示例:輸入成績提高程序健壯性:掌控流狀態(tài)
狀態(tài)字state為整型
enumios_state{goodbit=0x00, //流正常
eofbit=0x01,
//輸入流結(jié)束或文件結(jié)束已無數(shù)據(jù)可取
failbit=0x02, //最近的I/O操作失敗,流可恢復
badbit=0x04, //最近的I/O操作非法,流可恢復
hardfail=0x08//I/O出現(xiàn)致命錯誤,流不可恢復}提高程序健壯性:掌控流狀態(tài) 狀態(tài)字state為整型提高程序健壯性:掌控流狀態(tài)
讀取狀態(tài)的有關(guān)操作如下:inlineintios::rdstate()const{returnstate;}
//讀取狀態(tài)字inlineintios:operator!()const{returnstate&(badbit|failbit);}
//可用操作符!()代替fail()inlineintios::bad(){returnstate&badbit;}
//返回非法操作位提高程序健壯性:掌控流狀態(tài) 讀取狀態(tài)的有關(guān)操作如下:提高程序健壯性:掌控流狀態(tài)inlinevoidios::clear(int_i){lock();state=_i;unlock();}
//人工設(shè)置狀態(tài),可用來清狀態(tài)inlineintios::eof()const{returnstate&eofbit;}
//返回流(文件)結(jié)束位inlineintios::fail()const{returnstate&(badbit|failbit);}
//返回操作非法和操作失敗這兩位inlineintios::good()const{returnstate==0;}
//正常返回1,否則返回0提高程序健壯性:掌控流狀態(tài)inlinevoidios::程序健壯性的示例:輸入成績 intscore; do { cin.clear(); cout<<"請輸入您的分數(shù):"; cin>>score; }while(score<0||score>100);
猜測:這樣的改進有用嗎?程序健壯性的示例:輸入成績提高程序健壯性:清空緩沖區(qū)方法一、用cin.getline()等方式提走緩沖區(qū)內(nèi)容 do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.getline(s,100);//chars[100]; }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法一、用cin.getline(提高程序健壯性:清空緩沖區(qū)方法二、使用函數(shù)cin.ignore()提取緩沖區(qū)內(nèi)容 do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.ignore(255,'\n'); }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法二、使用函數(shù)cin.ignor提高程序健壯性:清空緩沖區(qū)方法三、使用函數(shù)cin.sync()清空輸入緩沖區(qū) do { cout<<"請輸入您的分數(shù):"; cin>>score; cin.clear(ios::goodbit); cin.sync(); }while(score<0||score>100);提高程序健壯性:清空緩沖區(qū)方法三、使用函數(shù)cin.sync(標準輸入/輸出成員函數(shù)intistream::get();istream&istream::get(char&);istream&istream::get(char*,int,char=’\n’);//不提取終止符istream&istream::getline(char*,int,char=’\n’);
//提取終止符并丟棄
提示:如果是超出數(shù)量而結(jié)束字符串輸入,需要重置流狀態(tài)。標準輸入/輸出成員函數(shù)intistream::get();標準輸入/輸出成員函數(shù) chars[100]; intnum; cin.getline(s,2,‘#’);//如輸入abcd# cout<<s<<endl;
cin.clear(0);cin.sync();//必須寫這兩句 cin>>num; cout<<num<<endl;標準輸入/輸出成員函數(shù) chars[100];10.2文件的輸入與輸出C++根據(jù)文件(file)內(nèi)容的數(shù)據(jù)格式,可分為兩類:二進制文件和文本文件。文本文件由字符序列組成,也稱ASCII碼文件,在文本文件中存取的最小信息單位為字符(character),而二進制文件中存取的最小信息單位為字節(jié)(Byte)。文本文件的讀寫容易理解,二進制文件讀寫效率較高。讀寫文件需包含頭文件fstream10.2文件的輸入與輸出C++根據(jù)文件(file)內(nèi)容的數(shù)讀寫文件四部曲1、定義文件對象,根據(jù)讀寫方式區(qū)分 ifstreamifile;//只輸入用 ofstreamofile;//只輸出用 fstreamiofile;//既輸入又輸出用
讀寫文件四部曲1、定義文件對象,根據(jù)讀寫方式區(qū)分讀寫文件四部曲2、使用文件流對象的成員函數(shù)打開一個磁盤文件。這樣在文件流對象和磁盤文件名之間建立聯(lián)系。以ifstream類為例: void
ifstream::open(const
char*,int=ios::in,int=);
其中參數(shù)一是字符串形式的文件名,參數(shù)二是打開方式,參數(shù)三一般使用默認值。
注意:如果文件名中包含路徑,\符號必須連續(xù)使用,如d:\\my.txt 讀寫文件四部曲2、使用文件流對象的成員函數(shù)打開一個磁盤文件。讀寫文件的打開方式打開方式讀/寫說明ios::in只讀方式文件不存在報錯ios::out只寫方式文件存在覆蓋ios::ate定位到尾部等待后續(xù)操作ios::app只寫追加方式文件存在繼續(xù)寫ios::trunc覆蓋方式ios::binary二進制必須讀寫文件的打開方式打開方式讀/寫說明ios::in只讀方式文讀寫文件的四部曲三個文件流類都重載了一個帶默認參數(shù)的構(gòu)造函數(shù),功能與open函數(shù)一樣:ifstream::ifstream(const
char*,int=ios::in,
int=);ofstream::ofstream(const
char*,int=ios::out,
int=);fstream::fstream(constchar*,int,
int=);讀寫文件的四部曲三個文件流類都重載了一個帶默認參數(shù)的構(gòu)造函數(shù)讀寫文件的四部曲打開文件也應該判斷是否成功,若成功,文件流對象值為非零值,不成功為0(NULL)。因此打開一個文件完整的程序為: fstreamiofile(”my”,ios::in|ios::out); if(!iofile){//“!”為重載的運算符,見9.3.1節(jié) cout<<”不能打開文件:”<<”my”<<endl; return-1;
}//失敗退回讀寫文件的四部曲打開文件也應該判斷是否成功,若成功,文件流對文本文件的讀寫如果將鍵盤和顯示器看成特殊的文件,那么我們熟練的輸入輸出和文件讀寫就可以統(tǒng)一概念了。輸入和讀文件本質(zhì)上是一致的;輸出和寫文件本質(zhì)上是一致的。因此之前熟悉的運算符和函數(shù)都幾乎可以直接用于文本文件的讀寫。文本文件的讀寫如果將鍵盤和顯示器看成特殊的文件,那么我們熟練文本讀寫——按字符復制文件
intmain(){
charch;ifstreamsfile("d:\\1.txt"); ofstreamdfile("d:\\2.txt"); if(!sfile){cout<<"不能打開源文件:"<<endl; return-1;}文本讀寫——按字符復制文件 intmain(){文本讀寫——按字符復制文件 if(!dfile){ cout<<"不能打開目標文件:"<<endl;
return-1;}s(ios::skipws);
//關(guān)鍵!把跳過空白控制位置0,即不跳過空白格
while(sfile>>ch)dfile<<ch;s();//如沒有這兩個關(guān)閉函數(shù),析構(gòu)函數(shù)也可關(guān)閉
d();return0;}文本讀寫——按字符復制文件 if(!dfile){文本讀寫——按字符復制文件1、使用默認的>>獲取字符時,會跳過空白符號。除了選擇關(guān)閉設(shè)置之外,可以用s(ch)來代替即可。2、當讀到文件尾部之后,流對象sfile進入eof狀態(tài),在循環(huán)判斷中會被判斷為NULL,因此循環(huán)停止。3、本算法可以復制所有文件,但效率較低。文本讀寫——按字符復制文件1、使用默認的>>獲取字符時,會跳文本讀寫——按行復制文件chars[2];//極端測試
do {
i(s,2); if(i()==0) ofile<<s<<endl; elseif(i()==4){ i();ofile<<s; } else{ ofile<<s; break;} }while(1);文本讀寫——按行復制文件chars[2];//極端測試 文本讀寫——按行復制文件1、通過默認符號\n終止讀取的,則流狀態(tài)正常,但因為getline不提取回車符,在復制時需要手工補上。2、通過字符上限終止讀取的,流狀態(tài)變成fail,需要將其置為正常才能繼續(xù)。3、該算法效率較高,但不適合二進制文件,因為二進制文件根本沒有行。文本讀寫——按行復制文件1、通過默認符號\n終止讀取的,則流文本文件讀寫總結(jié)基本上,文本文件的讀寫和輸入輸出的使用是很相近的,大部分函數(shù)和符號可以直接通用。提取和插入運算符的重載也可以用于文件對象,用于將類的內(nèi)容從文件輸入或?qū)懭胛募Wx文件的時候,需要注意判斷文件流的狀態(tài)。文本文件讀寫總結(jié)基本上,文本文件的讀寫和輸入輸出的使用是很相文本文件讀寫和運算符
classMoney {
intyuan,jiao,fen;
public: Money(inty=0,intj=0,intf=0) {yuan=y;jiao=j;fen=f;}
friendistream&operator>>(istream&is,Money&m);
friendostream&operator<<(ostream&os,Money&m); };文本文件讀寫和運算符 classMoney文本文件讀寫和運算符istream&operator>>(istream&is,Money&m) { is>>m.yuan>>m.jiao>>m.fen; returnis; }ostream&operator<<(ostream&os,Money&m) { os<<m.yuan<<‘\t’<<m.jiao<<‘\t’<<m.fen;//輸出的時候要分割 returnos; }文本文件讀寫和運算符istream&operator>>(文本文件讀寫和運算符 intmain(){ Moneym1;cin>>m1;cout<<m1<<endl;//重載輸入輸出 ofstreamofile("my.txt",ios::out); ofile<<m1;o();//輸出到文件 ifstreamifile("my.txt",ios::out); ifile>>m1;i();//從文件讀入數(shù)據(jù) cout<<m1;}文本文件讀寫和運算符 intmain(){文本文件讀寫和運算符重載 istream&operator>>(istream&is,Money&m) { if(&is==&cin)//如果是默認的cin對象 cout<<"請依次輸入元、角和分的值,用空格分割,回車符確認:"; is>>m.yuan>>m.jiao>>m.fen; returnis; }文本文件讀寫和運算符重載 istream&operator二進制文件讀寫istream&istream::read(char*,int); //從二進制流提取個若干個字節(jié),送入第一個參數(shù)地址開始的單元ostream&ostream::write(const
char*,int);//從第一個參數(shù)地址讀取若干個字節(jié),寫入文件流當中二進制文件讀寫istream&istream::read(c二進制文件讀寫 voidWriteTo&ofile); voidReadFrom&ifile); voidshow()//原始的show函數(shù) { cout<<yuan<<'\t'<<jiao<<'\t'<<fen<<endl; }二進制文件讀寫 voidWriteTo&ofile);二進制文件讀寫 voidMoney::WriteTo&ofile) { o((char*)&yuan,sizeof(yuan)); o((char*)&jiao,sizeof(jiao)); o((char*)&fen,sizeof(fen)); o(); }二進制文件讀寫 voidMoney::WriteTo&o二進制文件讀寫 voidMoney::
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年前列腺射頻治療儀系統(tǒng)行業(yè)深度研究分析報告
- 2025年船用裝飾材料項目投資可行性研究分析報告-20241226-205913
- 以租代買房合同范本
- 個人銷售欠款合同范本
- 關(guān)于公司承包合同范本
- 2025年度道路劃線施工與交通信號優(yōu)化合同范本
- 一汽解放車銷售合同范本
- 代理電商合同范本
- 代建房合同范本
- 《如何做一名好教師》課件
- 2016-2023年婁底職業(yè)技術(shù)學院高職單招(英語/數(shù)學/語文)筆試歷年參考題庫含答案解析
- 貴陽市2024年高三年級適應性考試(一)一模英語試卷(含答案)
- 地理標志專題通用課件
- 魚類和淡水生態(tài)系統(tǒng)
- 全國大學高考百科匯編之《哈爾濱工業(yè)大學》簡介
- 學校安全教育教你如何遠離危險
- 【人教版】九年級化學上冊全冊單元測試卷【1-7單元合集】
- 中國傳統(tǒng)文化課件6八卦五行
- 《胃癌課件:病理和分子機制解析》
- 口腔科導診分診技巧(PPT課件)
評論
0/150
提交評論