版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第8章C++輸入輸出類層次ffh目錄8.1概述8.2格式化輸入/輸出8.3重載流的插入符和提取符8.4常用成員函數(shù)I/O8.5流的錯誤處理8.6文件流操作8.7字符串流8.1概述輸入輸出操作在C++語言中沒有定義,但提供了一個I/O流庫C++輸入輸出類核心是:流!一個流就是一個字節(jié)序列,如果流向程序,這個流就稱為輸入流:如果流出程序,則稱為輸出流。如果輸入流來源于鍵盤,表明你的程序要從鍵盤獲取輸入;如果輸入流來源于一個文件,表明程序要從那個文件獲取輸入。類似地,輸出流可以發(fā)送給屏幕或文件。主要包括:標(biāo)準(zhǔn)流類:處理與標(biāo)準(zhǔn)輸入設(shè)備(鍵盤)和輸出設(shè)備(顯示器)關(guān)聯(lián)的數(shù)據(jù)流8.1概述文件流類:處理與磁盤文件關(guān)聯(lián)的數(shù)據(jù)流字符串流類:利用內(nèi)存中的字符數(shù)組處理數(shù)據(jù)的輸入輸出異常類等:處理異常錯誤其他:網(wǎng)絡(luò)流等文件文件是指存儲在外部介質(zhì)上具有名稱的數(shù)據(jù)集合8.1.1標(biāo)準(zhǔn)輸入輸出層次體系Ios_basebasic_iosbasic_istreambasic_ostreambasic_ifstreambasic_istringstreambasic_iostreambasic_ostringstreambasic_ofstreambasic_stringstreambasic_fstream8.1.1標(biāo)準(zhǔn)輸入輸出層次體系Ios_base:流的抽象基類,描述了流的基本性質(zhì),不考慮流的字符集basic_ios:流的抽象基類,描述了流的基本性質(zhì),考慮流的字符集basic_istream:描述流中讀寫和移動數(shù)據(jù)的方法;重載<<,>>basic_ostreambasic_ifstream:對文件進(jìn)行讀取basic_ofstreambasic_fstream:從fstreambase類和iostream類中派生,可對文件進(jìn)行插入和提取操作basic_istringstreambasic_iostreambasic_ostringstreambasic_stringstream8.1.2輸入輸出庫中的緩沖類層次C++輸入輸出類結(jié)構(gòu),如圖Inputbuff鍵盤顯示器處理Outputbuffabcduvwxyz驅(qū)動程序驅(qū)動程序系統(tǒng)預(yù)定義4個流類的對象:在使用下述類時,總要包含iostream.h文件:cin:它是istream類的對象,用來處理標(biāo)準(zhǔn)輸入,即鍵盤輸入cout:它是ostream類的對象,用來處理標(biāo)準(zhǔn)輸出,即屏幕輸出cerr:它是ostream類的對象,用來處理標(biāo)準(zhǔn)出錯信息,它提供不帶緩沖區(qū)的輸出clog:它是ostream類的對象,用來處理標(biāo)準(zhǔn)出錯信息,它提供帶緩沖區(qū)的輸出支持文件的流類8.2格式化輸入/輸出8.2.1使用ios類的成員函數(shù)進(jìn)行格式控制8.2.2使用控制符進(jìn)行格式控制8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制用ios類的成員函數(shù)來對輸入/輸出的格式進(jìn)行控制,如格式標(biāo)志字、域?qū)?、充填字符及輸出精度等?.使用ios類的成員函數(shù)設(shè)置標(biāo)志字ios類中聲明了一個數(shù)據(jù)成員,用于記錄當(dāng)前流的格式化狀態(tài),這個數(shù)據(jù)成員稱為標(biāo)志字。標(biāo)志字的每一位用于記錄一種格式。使用標(biāo)志常量或直接用對應(yīng)的十六進(jìn)制值設(shè)置輸入輸出流的格式。下表列出了主要標(biāo)志常量名及其意義。8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制Ios的幾個直接操作標(biāo)志字的公有成員函數(shù):(1)longflags():該函數(shù)用來返回標(biāo)志字。(2)longflags(long):該函數(shù)使用參數(shù)值來更新標(biāo)志字,并返回更新前的標(biāo)志字。(3)longsetf(longsetbits,longfield):該函數(shù)用來將field所指定的標(biāo)志位清零,將setbits為1的標(biāo)志位置為1,并返回設(shè)置前的標(biāo)志字。(4)longsetf(long):該函數(shù)用來設(shè)置參數(shù)所指定的那些標(biāo)志位,并返回更新前的標(biāo)志字。(5)longunsetf(long):該函數(shù)用來清除參數(shù)所指定的那些標(biāo)志位,并返回更新前的標(biāo)志字。8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制例8.1:以幾種不同的格式輸出同一浮點數(shù),示例如何使用成員函數(shù)來操作標(biāo)志字。#include<iostream>usingnamespacestd;intmain(){ doublea=12.34; cout<<"a="<<a<<endl; cout.setf(ios::showpos);cout.setf(0x0100);cout<<"a="<<a<<endl; cout.setf(0x1000);cout<<"a="<<a<<endl; return0;}結(jié)果:a=12.34a=+12.34a=+1.234000e+0018.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制例8.2:以幾種不同的進(jìn)制輸出同一整數(shù)。示例ios定義的公有靜態(tài)符號常量的作用。#include<iostream>usingnamespacestd;intmain(){ doublea=12; cout.setf(ios::showbase);
cout<<"以十進(jìn)制輸出12為:"; cout.setf(ios::dec,ios::basefield);
cout<<12<<endl; cout<<“以八進(jìn)制輸出12為:“;
cout.setf(ios::oct,ios::basefield);cout<<12<<endl; cout<<"以十六進(jìn)制輸出12為:"; cout.setf(ios::hex,ios::basefield);cout<<12<<endl; return0;}輸出結(jié)果以十進(jìn)制輸出12為:12以八進(jìn)制輸出12為:014以十六進(jìn)制輸出12為:0xc8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制2.使用ios類的成員函數(shù)設(shè)置域?qū)?、充填字符及輸出精度在ios類定義了一些設(shè)置域?qū)?、充填字符及輸出精度等成員函數(shù):(1)設(shè)置輸出數(shù)據(jù)所占寬度的函數(shù): intwidth()該函數(shù)用來返回當(dāng)前輸出的數(shù)據(jù)寬度。 intwidth(int)該函數(shù)用來設(shè)置當(dāng)前輸出的數(shù)據(jù)寬度,并返回更新之前的寬度值。(2)填充當(dāng)前寬度內(nèi)的填充字符函數(shù) charfill()該函數(shù)用來返回當(dāng)前所使用的填充字符。 charfill(char)該函數(shù)用來設(shè)置當(dāng)前填充字符為參數(shù)所表示的字符,并返回更新前的填充字符。8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制(3)設(shè)置浮點數(shù)輸出精度函數(shù) intprecision()該函數(shù)用來返回當(dāng)前浮點數(shù)的有效數(shù)字的個數(shù)。 intprecision(int)該函數(shù)用來設(shè)置當(dāng)前浮點數(shù)輸出時的有效數(shù)字個數(shù)為該函數(shù)的參數(shù)值,并返回更新前的值。
8.2.1
使用ios類的成員函數(shù)進(jìn)行格式控制例8.3:示例如何使用ios類的成員函數(shù)設(shè)置域?qū)?、充填字符及輸出精度?include<iostream>#include<string>usingnamespacestd;intmain(){doublevalues[]={1.23,35.36,653.7,4358.24};char*names[]={"aaaaaaa","bbbb","ccccc","dddddd"};
for(inti=0;i<4;i++) {
cout.setf(ios::left);//設(shè)置左對齊
cout.fill('*');//充填字符為*
cout.width(10);//設(shè)置域?qū)挒?0 cout.precision(5);//輸出精度為5cout<<names[i]<<",”<<values[i]<<endl;} return0;
}運行結(jié)果:aaaaaaa***,1.23bbbb******,35.36ccccc*****,653.7dddddd****,43使用控制符進(jìn)行格式控制8.2.2使用控制符進(jìn)行格式控制8.2.2使用控制符進(jìn)行格式控制例8.4
使用控制符進(jìn)行格式控制,完成例8.3同樣的功能。#include<iostream>#include<iomanip>usingnamespacestd;intmain(){doublevalues[]={1.23,35.36,653.7,4358.24};char*names[]={"aaaaaaa","bbbb","ccccc","dddddd"};for(inti=0;i<4;i++){cout<<setiosflags(ios::left)<<setfill('*')<<setw(10)<<names[i]<<",";cout<<setprecision(5)<<values[i]<<endl;
}return0;}8.3重載流的插入符和提取符運算符重載有兩種形式:重載為成員函數(shù)或者是重載為友元函數(shù)。由于重載插入符和提取符時,其左邊的參數(shù)是流,而右邊的參數(shù)是類的對象,因此,插入符和提取符只能重載為友元函數(shù)。插入符重載的一般格式如下:ostream&operator<<(ostream&s,classa&a){<函數(shù)體>returns;}8.3重載流的插入符和提取符例8.5:重載流的插入符和提取符,完成復(fù)數(shù)類的功能。#include<iostream>usingnamespacestd;classComplex{public:Complex(doubler=0,doublei=0);friendComplexoperator+(Complexc1,Complexc2);//重載加
friendComplexoperator-(Complexc1,Complexc2);//二元減
friendistream&operator>>(istream&s,Complex&c); friendostream&operator<<(ostream&s,Complex&c);private:doublereal,imag;};8.3重載流的插入符和提取符Complex::Complex(doubler,doublei) {real=r;imag=i;}Complexoperator+(Complexc1,Complexc2){Complextemp;temp.real=c1.real+c2.real;temp.imag=c1.imag+c2.imag;returntemp;}Complexoperator-(Complexc1,Complexc2){Complextemp;temp.real=c1.real-c2.real;temp.imag=c1.imag-c2.imag;returntemp;}8.3重載流的插入符和提取符istream&operator>>(istream&s,Complex&c){ s>>c.real>>c.imag; returns;
}ostream&operator<<(ostream&s,Complex&c){ s<<'('<<c.real<<','<<c.imag<<')'<<endl; returns;
}intmain(){Complexc1,c2; cin>>c1>>c2;Complex
c;cout<<“c1=”<<c1;
cout<<"c2="<<c2;c=c1+c2;
//c=operator+(c1,c2);cout<<"c1+c2="<<c;c=c1-c2;
//c=operator-(c1,c2);cout<<"c1-c2="<<c;return0;}8.4常用成員函數(shù)I/O8.4.1輸入流的常用成員函數(shù)8.4.2輸出流的常用成員函數(shù)8.4.1
輸入流的常用成員函數(shù)1.read()函數(shù) istream&read(char*pch,intnCount);將指定的nCount個字符輸入到內(nèi)存中的字符數(shù)組pch。如果讀取的字符數(shù)量少于指定的數(shù)量,就會設(shè)置failbit錯誤位。voidmain(){
constintS=80;
charbuf[S]="";
cout<<"Input…\n";
cin.read(buf,S);
cout<<endl;
cout<<buf<<endl;}Ans:執(zhí)行該程序顯示如下信息:Input…abcd<ctrl+z>輸出如下:abcd8.4.1
輸入流的常用成員函數(shù)2.get()函數(shù)該函數(shù)有3種主要形式: istream&int
get()從指定的輸入流中輸入一個字符(包括空白字符),并返回該字符作為函數(shù)調(diào)用的值;遇到輸入流中的文件結(jié)束符時,此get函數(shù)返回EOF。 istream&int
get(char&rch)從輸入流讀取一個字符(包括空白字符),并將其存儲rch。當(dāng)遇到文件結(jié)束符時,此get函數(shù)返回0,否則返回對istream對象的引用,并用該引用再次調(diào)用get成員函數(shù)。
istream&intget(char&pch,intnCount,chardelim=’\n’)
從輸入流中讀取字符。函數(shù)要么在讀取到nCount-1個字符后終止,要么在讀取到指定的分隔符delim時終止。例:
從鍵盤輸入abcxyz123voidmain(){
charch;
cout<<"Input:";
while((ch=cin.get())!=EOF)//EOF=-1,包含在iostream
cout.put(ch);
cout<<"ok!";}Ans:Input:abcxyz123^zOk!8.4.1
輸入流的常用成員函數(shù)3.getline()與帶3個參數(shù)的get成員函數(shù)類似,它讀取一行字符串后在字符數(shù)組末尾加入’\0’。不同的是,getline要從輸入流中刪除分隔符(即讀取并刪除它),而不是把它存放在數(shù)組中。4.gcount()函數(shù)無參函數(shù),統(tǒng)計最后一次輸入操作讀取的字符數(shù)。例:求每行字符個數(shù),最長行字符個數(shù),多少行constintSIZE=80;voidmain(){
intlcnt=0,lmax=-1;//行數(shù),最長行的輸入字符個數(shù)
charbuf[SIZE];
cout<<"Input…\n";
while(cin.getline(buf,SIZE))
{
intcount=cin.gcount();//輸入字符的個數(shù)
lcnt++;
if(count>lmax)lmax=count;
cout<<"Line#"<<lcnt<<"\t" <<"charsread:"<<count<<endl;
cout.write(buf,count).put('\n').put('\n');
}
cout<<endl;
cout<<"Totalline:"<<lcnt<<endl;
cout<<"Longestline:"<<lmax<<endl;}Ans:Input…thisisastring.Line#1charsread:18thisisastring.youareastudent.Line#2charsread:19youareastudent.thefourseaconsoftheyear.Line#3charsread:30thefourseasonsoftheyear.changetoaN.332bus.Line#4charsread:25changetoaN.332bus.輸入<ctrl+z>后,輸出:Totalline:4Longestline:308.4.1
輸入流的常用成員函數(shù)5.ignore()函數(shù)該函數(shù)原型為:istream&ignore(intn=1,intt=EOF);遇到指定的終止字符t時提前結(jié)束或跳過輸入流中n個字符結(jié)束(此時跳過包括終止字符內(nèi)的若干個字符)。終止字符仍停留在輸入流中。8.4.1
輸入流的常用成員函數(shù)
6.putback()函數(shù)該函數(shù)原型為:istream&putback(charch);把上一次從輸入流中通過get(或getline)取得的字符再放回該輸入流中。對于應(yīng)用程序需要掃描輸入流以查找以特定字符開頭的字段來說,這是非常有用的。當(dāng)輸入一個字符時,應(yīng)用程序把該字符放回輸入流,以保證輸入的數(shù)據(jù)中包含該字符。7.peek()函數(shù)無參函數(shù),返回輸入流的下一個字符,但并不將其從輸入流中刪除。其作用是觀測該字符,字符指針仍停留在原來位置上。例peek()查找ab連續(xù)組合#include<iostream.h>voidmain(){
intch,cnt=0;
cout<<"Input…\n";
while((ch=cin.get())!=EOF) {
if(ch=='a'&&cin.peek()=='b‘)cnt++;
}
cout<<endl;
cout<<cnt<<endl;}當(dāng)輸入流如下所示:mabyababcabcdab<ctrl+z>68.4.2輸出流的常用成員函數(shù)1.write()函數(shù)ostream&write(const*str,intn);將字符串送到輸出流。例如: cout.write("string",strlen("string"));#include<string>voidPrintString(char*s){
cout.write(s,strlen(s)).put('\n');
cout.write(s,6)<<"\n“;}例:函數(shù)write()voidmain(){
charstr[]="IloveC++“;
cout<<"Thestringis:"<<str<<endl;
PrintString(str);
PrintString("thisisastring");}Ans:Thestringis:IloveC++IloveC++Ilovethisisastrthisi8.4.2輸出流的常用成員函數(shù)2.put()函數(shù)ostream&put(char
ch);輸出一個字符。voidmain(){
cout<<'a'<<','<<'b'<<'\n';
cout.put('a').put(',').put('b').put('\n');
charc1='A',c2='B';
cout.put(c1).put(c2).put(‘\n’);
}Ans:a,ba,bAB8.4.2輸出流的常用成員函數(shù)例8.6:從輸入的串中分離數(shù)字串,示例常用成員函數(shù)I/O#include<iostream>usingnamespacestd;intmain(){ charstr[10]; inti=0; cout<<"輸入一個字符串(最多9個字符)"; cin.get(str,10,'!');//輸入一個字符串
charc=str[i]; cout<<"數(shù)字串為:"<<endl;8.4.2輸出流的常用成員函數(shù) while(i<cin.gcount()) {
if(isdigit(c))//輸出數(shù)字串
cout.put(c);
if(isdigit(c)&&!isdigit(str[i+1])) cout<<endl;
i=i+1;
c=str[i]; } cout<<endl; return0;} 8.5流錯誤的處理8.5.1I/0流的錯誤狀態(tài)字8.5.2I/0流的狀態(tài)函數(shù)在對流進(jìn)行操作時,可能會發(fā)生錯誤必須有一種能夠檢測到錯誤狀態(tài)的機制和清除錯誤的方法通過幾種方法都可以檢測出錯誤,并查明其錯誤性質(zhì),然后調(diào)用clear()函數(shù)清除錯誤狀態(tài),可以使得流能夠恢復(fù)處理。8.5.1I/0流的錯誤狀態(tài)字ios類定義了一個數(shù)據(jù)成員,用它來記錄各種錯誤的性質(zhì),稱為狀態(tài)字:goodbit=0x00表示狀態(tài)正常,沒有位設(shè)置。fofbit=0x01表示到達(dá)文件末尾。failbit=0x02表示I/O操作失敗。流沒有受到破壞,可以恢復(fù)。badbit=0x04表示試圖進(jìn)行非法操作。設(shè)備硬件故障,不可恢復(fù)。hardbit=0x80表示致命錯誤使用clear()函數(shù)可以清除除hardbit以外的其他錯所設(shè)置的位。返回本節(jié)8.5.2I/0流的狀態(tài)函數(shù)1.檢查一個流對象當(dāng)前狀態(tài)的成員函數(shù)有幾個函數(shù)可用來檢查一個流對象的當(dāng)前狀態(tài),它們都是ios類的成員函數(shù):intrdstate()//返回當(dāng)前的流狀態(tài)字inteof()//如果提取操作已到達(dá)文件尾,則返回非零值intfail()//若failbit位置位,返回非零值intbad()//若badbit位置位,返回非零值intgood()//若狀態(tài)字沒有置位,則返回非零值可以使用這些函數(shù)檢查當(dāng)前流的狀態(tài)。利用函數(shù)來檢測流是否出錯例如: fstreamistrm("f1.dat"); if(istrm.good()) …
//文件打開成功,進(jìn)行某些操作例如:ofstreamostrm("f2.dat"); if(!ostrm.good()) …//文件沒有被打開,退出該程序例如:if(!cin.eof()) …//文件沒有結(jié)束,可進(jìn)行讀操作成員函數(shù):intios::operator!()可判斷流狀態(tài)是否正常
ifstreamistrm("f1.dat");if(!istrm)cout<<"f1.datcan'topen.\n";8.5.2I/0流的狀態(tài)函數(shù)2.檢查一個流對象當(dāng)前狀態(tài)的運算符函數(shù)如果不關(guān)心具體是哪一位置位(具體的錯誤性質(zhì)),則可以使用ios類中重載的兩個運算符函數(shù): intios::operator!();在設(shè)置了failbit、badbit或hardbit位的情況下返回非零,而成員函數(shù): ios::operatorvoid*();在上述這些位沒有設(shè)置的情況下(正常狀態(tài))返回非零。這兩個函數(shù)提供了從兩個方面測試流狀態(tài)是否為正常情況的手段。8.5.2I/0流的狀態(tài)函數(shù)3.清除/設(shè)置流狀態(tài)位函數(shù)ios類的成員函數(shù): voidios::clear(int=0);用于清除/設(shè)置流的狀態(tài)位(它不能設(shè)置/清除hardfail位)。函數(shù)clear()更多地是用于在己知流發(fā)生錯誤的情況下清除流的錯誤狀態(tài),也可以用于設(shè)置流的錯誤狀態(tài)。例如:8.6文件流操作8.6.1文件流8.6.2文件的打開與關(guān)閉8.6.3文件的讀寫8.6.1
文件流
在C++中,文件被看作是元素的序列,即文件是由一個個的元素數(shù)據(jù)順序組成的。不考慮記錄的界限,因此這種文件稱為流式文件。按數(shù)據(jù)的存儲形式來分類,文件可分為文本文件和二進(jìn)制文件。在文本文件中,每個字節(jié)存放一個ASCII代碼表示一個字符,文本文件的優(yōu)點是可直接按字符形式輸出,供人們閱讀。二進(jìn)制文件則是把數(shù)據(jù)的內(nèi)部存儲形式原樣存放到文件中,這種文件的優(yōu)點是與數(shù)據(jù)在內(nèi)存中的存儲形式保持一致,因此存儲效率高,無須進(jìn)行存儲形式的轉(zhuǎn)換,但不能直接按字符形式輸出。
8.6.1
文件流按數(shù)據(jù)的存取方式來分類,文件可分為順序文件和隨機讀寫文件。在C++中,文件既可以進(jìn)行順序訪問,也可以進(jìn)行隨機訪問。在C++中,文件定義為文件流類的一個對象。要進(jìn)行文件的輸入/輸出,必須先創(chuàng)建—個文件流對象,并與指定的文件相關(guān)聯(lián),即打開文件;然后才能進(jìn)行讀寫操作;完成后再關(guān)閉這個文件。文件流是以外存文件為輸入/輸出對象的數(shù)據(jù)流。輸出文件流是從內(nèi)存流向外存文件的數(shù)據(jù),輸入文件流是從外存文件流向內(nèi)存的數(shù)據(jù)。每一個文件流都有一個內(nèi)存緩沖區(qū)與之對應(yīng)。C++有三種文件流:輸入文件流、輸出文件流和輸入/輸出文件流。8.6.2文件的打開與關(guān)閉1.打開文件有兩種方法:先建立流對象,然后調(diào)用函數(shù)open連接外部文件流類對象名;
對象名.open(文件名,方式);調(diào)用流類帶參數(shù)的構(gòu)造函數(shù),建立流對象的同時連接外部文件流類對象名(文件名,方式);其中,“流類”是C++流類庫定義的文件流類,為ifstream、ofstream或fstream。8.6.2文件的打開與關(guān)閉如: ofstreamostrm; ostrm.open("f1.txt");或
fstreamoutfile(“f1.txt”,ios::out);\\寫 ifstreamistrm; istrm.open("f2.txt");或
ifstreamistrm(“f2.txt”);\\讀ios文件訪問方式常量方式名用途in以輸入(讀)方式打開文件out以輸出(寫)方式打開文件app以輸出追加方式打開文件ate文件打開時,文件指針位于文件尾trune如果文件存在,將其長度截斷為0,并清除原有內(nèi)容;如果文件不存在,則創(chuàng)建新文件binary以二進(jìn)制方式打開文件,缺省時為文本方式nocreate打開一個已有文件,如該文件不存在,打開失敗noreplace如果文件存在,除非設(shè)置ios::ate或ios::app,否則打開操作失敗ios::in|ios::out以讀和寫的方式打開文件ios::out|ios::binary以二進(jìn)制寫方式打開文件ios::in|ios::binary以二進(jìn)制讀方式打開文件說明:缺省文件的讀寫位置指針位于文件頭用ios::app方式打開文件時文件讀寫位置指針位于文件尾在以ios::out方式打開文件,而未指定ios::in,ios::ate,ios::app方式時,則隱含為ios::trunc方式通過"位或"操作結(jié)合起來,表示具有幾種方式的操作。例如:
ios::in|ios::out|ios::binary//二進(jìn)制的讀寫未指定binary方式時,文件都以文本方式打開。若指定了binary方式,則文件以二進(jìn)制方式打開8.6.2文件的打開與關(guān)閉8.6.2文件的打開與關(guān)閉2.關(guān)閉文件當(dāng)結(jié)束一個文件的操作后,要及時將該文件關(guān)閉使用close()成員函數(shù)進(jìn)行關(guān)閉:<流對象名>.close()其中,<流對象名>是待關(guān)閉的文件流的對象名。例如,關(guān)閉文件標(biāo)識符為outfile的文件,使用下面格式:outfile.close();例:文件流被打開、關(guān)閉#include<fstream>voidmain(){
ofstreamostrm;
ostrm.open("f1.dat");
ostrm<<12<<endl;
ostrm<<310.85<<endl;
ostrm.close();
ifstreamistrm("f1.dat");
intn;
doubled;
istrm>>n>>d;
cout<<n<<","<<d<<endl;
istrm.close();}Ans:12,310.858.6.3文件的讀寫1.文本文件的讀寫文本文件用默認(rèn)方式打開。例8.7:從輸入的串中分離數(shù)字串,先將其存入磁盤文件,然后將其讀出并在屏幕上顯示出來。#include<iostream>#include<fstream>usingnamespacestd;intmain(){ charstr[10]; inti=0; cout<<"輸入一個字符串(最多9個字符)“; cin.get(str,10,'!');//輸入一個字符串
ofstreamoutfile(“f1.txt”);
//以輸出方式打開文件f1.txt if(!outfile)
{
cout<<“Filecannotbeopened.”<<endl;
return0;} charc=str[i];
while(i<cin.gcount()) { if(isdigit(c))
outfile<<c;
//將數(shù)字串存入文件outfile if(isdigit(c)
&&
!isdigit(str[i+1]))
outfile<<endl; i=i+1; c=str[i]; } outfile<<'\0';outfile.close(); ifstreaminfile(“f1.txt”);
//以輸入方式打開文件f1.txtif(!infile)
{
cout<<“Filecannotbeopened.”<<endl;
return0;} cout<<"存入f1.txt文件中的數(shù)字串為:"<<endl; while(!infile.eof())
//從文件中讀出數(shù)據(jù),并輸出到屏幕上。
{
infile.getline(str,sizeof(str));//從文件中讀出一行數(shù)據(jù)
cout<<str<<endl; }infile.close(); return0;} 例
單字符讀寫函數(shù)get()和put()#include<iostream>usingnamespacestd;#include<fstream>#include<stdlib.h>#include<string>voidmain(){ fstreamoutfile,infile;outfile.open("f3.dat",ios::out);if(!outfile){cout<<"f3.datcan'topen.\n";abort();}charstr[]="thisisaC++program."; for(inti=0;i<=strlen(str);i++)outfile.put(str[i]);outfile.close();例
單字符讀寫函數(shù)get()和put() infile.open("f3.dat",ios::in);if(!infile){cout<<"f3.datcan'topen.\n";abort();}charch;while(infile.get(ch))cout<<ch;cout<<endl;infile.close();}Ans:thisisaC++program.例:
文件拷貝#include<iostream>usingnamespacestd;#include<fstream>#include<stdlib.h>voidmain(){ fstreaminfile,outfile; infile.open("f2.dat",ios::in); if(!infile){cout<<"f2.datcan‘?topen.\n";abort();} outfile.open("f4.dat",ios::out); if(!outfile){cout<<"f4.datcan'topen.\n";abort();} charch; while(infile.get(ch))
outfile.put(ch); infile.close(); outfile.close();}8.6.3文件的讀寫2.二進(jìn)制文件的讀寫打開二進(jìn)制文件時,在open()函數(shù)中要加上ios::binary寫入信息時,使用write()函數(shù)讀信息,使用read()函數(shù)例8.8:用二進(jìn)制文件處理學(xué)生信息#include<iostream>#include<fstream>//文件流頭文件#include<string>usingnamespacestd;classstudent{ private: longnum; stringname; floatscore;public: voidsetnum() //輸入學(xué)號num
{
cout<<“請輸入學(xué)生的學(xué)號:“;cin>>num;
}voidsetname()//輸入姓名name
{
cout<<"請輸入學(xué)生的姓名:“;cin>>name;}voidsetscore()
//輸入學(xué)號成績
{
cout<<“請輸入學(xué)生的成績:“;cin>>score;
}
longgetnum()
{returnnum;
}
//得到學(xué)號stringgetname()
{
returnname;
}
//得到姓名
floatgetscore()
{returnscore;
}
//得到成績};intmain(){ofstreamoutfile("student.dat",ios::binary); if(!outfile)
{
cout<<"Filecannotbeopened."<<endl; return0;}studentstud[100];charch; inti=0;
while(1){cout<<"\n你想輸入更多記錄嗎(y/n)?“;cin>>ch;if(ch==‘n’||ch==‘N‘)
break; i=i+1;
stud[i].setnum();//輸入學(xué)號
stud[i].setname();//輸入姓名
stud[i].setscore();//輸入成績
outfile.write((char*)&stud[i],sizeof(student)); }outfile.close();//關(guān)閉文件
cout<<"********輸入結(jié)束********"<<endl; cout<<"\n你想看文件內(nèi)容嗎(y/n)?“;cin>>ch; if(ch=='Y'||ch=='y') {ifstreaminfile("student.dat",ios::binary);if(!infile){cout<<"Filecannotbeopened."<<endl;return0;} cout<<"學(xué)號"<<"\t姓名"<<"\t成績"<<endl; infile.read((char*)&stud[i],sizeof(student));
i=1;while(infile) {cout<<stud[i].getnum()<<"\t“<<stud[i].getname()<<"\t“;cout<<stud[i].getscore()<<endl; i=i+1; infile.read((char*)&stud[i],sizeof(student)); }infile.close();//關(guān)閉文件 } return0;}8.6.3文件的讀寫3.文件的隨機讀寫文件打開以后,系統(tǒng)自動生成兩個隱含的流指針:讀指針和寫指針。在輸入文件流類中,有關(guān)讀指針的函數(shù)如下:(1)移動讀指針函數(shù)istream&istream::seekg(streampospos);該函數(shù)的功能是將輸入文件的指針移動到pos指定的位置中。istream&istream::seekg(streamoffoffset,seek_dirorigin);其中,origin的類型seek_dir是一個枚舉類型,可有以下三種取值:ios::beg表示指針的起始位置為文件頭ios::cur表示指針的起始位置為當(dāng)前位置ios::end表示指針的起始位置為文件尾該函數(shù)的功能是從origin指定的開始位置起,將文件指針移動offset個字節(jié)數(shù)。例,假設(shè)input是一個istream類型的流:input.seekg(-100,ios::cur);以當(dāng)前位置為基準(zhǔn)向前(流的開始位置方向)移動100各字節(jié)處
input.seekg(100,ios::beg);從流開始的位置后移100個字節(jié)處 input.seekg(-100,ios::end);相對于流結(jié)尾處前移100個字節(jié)處8.6.3文件的讀寫(2)返回讀指針當(dāng)前指向的位置值streamposistream::tellg();該函數(shù)的功能是確定文件指針的當(dāng)前位置。相應(yīng)地,ostream類提供有關(guān)寫指針的函數(shù)如下:(1)移動寫指針函數(shù)ostream&ostream::seekp(streampospos);ostream&ostream::seekp(streamoffoffset,seek_dirorigin);(2)返回寫指針當(dāng)前指向的位置值streamposostream::tellp();函數(shù)參數(shù)的意義與讀指針函數(shù)一樣。例
讀、寫指針操作#include<iostream.h>#include<fstream.h>#include<stdlib.h>voidmain(){
fstreamfile("f6.dat",ios::in|ios::out|ios::binary);
if(!file){cout<<"f6.datcan'topen.\n“;
abort();} for(inti=0;i<15;i++)//每個int,占4個byte
file.write((char*)&i,sizeof(int));
streampospos=file.tellp();cout<<"Currentbytenumber:"<<pos<<endl;
for(i=15;i<45;i++)
file.write((char*)&i,sizeof(int));
file.seekg(pos);//輸入文件,讀
file.read((char*)&i,sizeof(int));
cout<<"Thedatastoredis"<<i<<endl;
file.seekp(0,ios::beg);//輸出文件,寫
for(i=80;i<100;i++)
file.write((char*)&i,sizeof(int));
file.seekg(pos);
file.read((char*)&i,sizeof(int);
cout<<"Thedatastoredis"<<i<<endl;
cout<<"Currentbytenumber:"<<file.tellp()<<endl;}Ans:Currentbytenumber:60Thedatastoredis15Thedatastoredis95Thedatastoredis21Currentbytenumber:88例:
數(shù)組#include<iostream.h>#include<fstream.h>#include<stdlib.h>voidmain(){
structstudent
{
charname[20];
longnumber;
doubletotalscord;
}
stu[5]={"Ma",97001,85.72,"Li",97002,92.62,
"Hu",97003,89.25,"Yan",97004,90.84,"Lu",97005,80.92};
fstreamfile;
studentone;
file.open("f7.dat",ios::out|ios::in|ios::binary);
if
(!file1)
{
cout<<“f7.datcan‘topen.\n‘;
abort();}
for(inti=0;i<5;i++)
file1.write((char*)&stu[i],sizeof(student));
file1.seekp(sizeof(student)*4);
file1.read((char*)&one,sizeof(stu[i]));
cout<<<<"\t"<<one.number<<"\t" <<one.totalscord<<endl;
file1.seekp(sizeof(student)&1);
file1.read((char8)&one,sizeof(stu[i]));
cout<<<<"\t"<<one.number<<"\t"<<one.totalscord<<endl;
file1.close();}Ans:Lu9700580.92Li9700292.628.6.3文件的讀寫例8.9:用二進(jìn)制文件隨機處理學(xué)生信息#include<iostream>#include<fstream>//文件流頭文件#include<string>usingnamespacestd;classstudent{
private: longnum; stringname; floatscore;8.6.3文件的讀寫public: voidsetnum()
{
cin>>num;
}
//輸入學(xué)號voidsetname(){
cin>>name;
}//輸入姓名
voidsetscore(){
cin>>score;
}
//輸入成績longgetnum()
{returnnum;}
//得到學(xué)號stringgetname()
{returnname;
}
//得到姓名floatgetscore()
{
returnscore;
}
//得到成績};intmain(){ fstreamfile;file.open("student.dat",ios::in|ios::out|ios::binary); if(!file)
{
cout<<“Filecannotbeopened.”<<endl;
return0;} studentstud[100],s;8.6.3文件的讀寫cout<<"首先輸入3個學(xué)生的信息:"<<endl;cout<<"學(xué)號\t姓名\t成績"<<endl;for(inti=0;i<3;i++) {
stud[i].setnum();//輸入學(xué)號
stud[i].setname();//輸入姓名
stud[i].setscore();//輸入成績
file.write((char*)&stud[i],sizeof(student)); }cout<<"再在第2個學(xué)生后插入兩個學(xué)生的信息:"<<endl;cout<<"學(xué)號\t姓名\t成績"<<endl; file.seekp(sizeof(student)*2);for(i=3;i<5;i++) {
stud[i].setnum();
stud[i].setname();stud[i].setscore();
file.write((char*)&stud[i],sizeof(student)); }
8.6.3文件的讀寫cout<<"輸出第2,4個學(xué)生的信息:"<<endl;cout<<"學(xué)號\t姓名\t成績"<<endl;file.seekg(sizeof(student)*1);//讀指針移到第2條記錄file.read((char*)&s,sizeof(student));cout<<s.getnum()<<"\t”<<s.getname()<<"\t”<<s.getscore()<<endl;file.seekg(sizeof(student)*3);
//讀指針移到第4條記錄file.read((char*)&s,sizeof(student));cout<<s.getnum()<<"\t”<<s.getname()<<"\t”<<s.getscore()<<endl;file.close();//關(guān)閉文件return0;}8.6.4其它有關(guān)文件操作的函數(shù)1.跳過輸入流中指定數(shù)量的字符的函數(shù)該函數(shù)原型如下:istream&istream::ignore(intn=1,intt=EOF);功能是從流中跳過n個字符,或者直到發(fā)現(xiàn)終止符t為止一般的使用ctrl+z鍵結(jié)束從鍵盤上鍵入的輸入流例:輸入整數(shù),發(fā)現(xiàn)錯誤,則跳過當(dāng)前輸入,等待下一次輸入voidmain(){
inta;
cout<<"Inputaninteger:“;
cin>>a;
while(!cin)//判斷輸入流cin是否有錯,有錯時cin為0
{
cin.clear();//清楚錯誤標(biāo)志位,等待下次輸入
//最多跳過80字符或遇\n為止,等待下次輸入
cin.ignore(80,'\n');
cout<<"Tryagain!"<<endl<<"Inputaninteger:";
cin>>a;
}
cout<<"Theintegerenteredis"<<a<<endl;}Ans:Inputaninteger:a789yTryagain!678aTheintegeryouenteredis6782.退回一個字符到輸入流的函數(shù)函數(shù)原型如下:
istream&istream::putback(charch)功能是將讀出的指定的字符退回到輸出流中ch是指出要退回輸入流的字符例:
從輸入流中分析出數(shù)字串#include<iostream>#include<ctype.h>//內(nèi)含isdigit(),非0為真intgetnum(char*s);voidmain(){
charbuf[80];
cout<<"Enterstream:\n";
while(getnum(buf))
cout<<"Digitstringis:"<<buf<<endl;}intgetnum(char*s)//每次處理一個數(shù)字串{
intflag(0);//標(biāo)志量,沒有數(shù)字串返回為0
charch;
while(cin.get(ch)&&!isdigit(ch)
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年大理護(hù)理職業(yè)學(xué)院單招職業(yè)技能測試題庫及答案詳解1套
- 2026年廈門軟件職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性考試題庫及參考答案詳解
- 2026年榆林能源科技職業(yè)學(xué)院單招綜合素質(zhì)考試題庫及參考答案詳解1套
- 2026年西安歐亞學(xué)院單招職業(yè)傾向性測試題庫及答案詳解1套
- 2026年山西林業(yè)職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性考試題庫帶答案詳解
- 鐵路職工考試面試題及答案
- (一調(diào))樂山市高中2023級高三第一次調(diào)查研究考試化學(xué)試卷
- 【歷 史】2025-2026學(xué)年八年級歷史上冊手繪筆記課件
- 2025年西安外國語大學(xué)第二批專任教師崗位公開招聘34人的備考題庫及答案詳解參考
- 2025年心血管內(nèi)科科研助理招聘備考題庫帶答案詳解
- 液壓升降平臺技術(shù)協(xié)議模板
- 統(tǒng)編版語文三年級上冊期末作文專項復(fù)習(xí) 課件
- 2024年高考英語 (全國甲卷)真題詳細(xì)解讀及評析
- DB36-T 1865-2023 濕地碳匯監(jiān)測技術(shù)規(guī)程
- 福建省部分地市2025屆高中畢業(yè)班第一次質(zhì)量檢測 化學(xué)試卷(含答案)
- JJF(陜) 036-2020 單相機攝影測量系統(tǒng)校準(zhǔn)規(guī)范
- 藥物化學(xué)-001-國開機考復(fù)習(xí)資料
- 電力工程施工方案1
- 運營助理述職報告
- 保安臨時用工合同范例
- 期中測試(試題)-2024-2025學(xué)年四年級上冊數(shù)學(xué)人教版
評論
0/150
提交評論