版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
8.1I/O標(biāo)準(zhǔn)流類 8.2格式化操作
8.3ios類的成員函數(shù)
8.4流操作算子
8.5文件流類
8.6串流類
8.7異常處理
本章要點(diǎn)
練習(xí)
8.1.1標(biāo)準(zhǔn)設(shè)備流
在C/C++中將設(shè)備看做對象,并分別給出了不同的關(guān)鍵字來標(biāo)識(shí)設(shè)備,如表8-1所示。標(biāo)準(zhǔn)流的設(shè)備名是C++中預(yù)先定義的全局對象名。用I/O流的標(biāo)準(zhǔn)頭文件iostream就可將其包含進(jìn)來。8.1I/O標(biāo)準(zhǔn)流類表8-1標(biāo)準(zhǔn)設(shè)備
C++的輸入/輸出以流的形式實(shí)現(xiàn)。在輸入操作中,流的傳遞方向是設(shè)備→內(nèi)存;在輸出操作中,流的傳遞方向是內(nèi)存→設(shè)備。輸入操作的運(yùn)算符是>>,輸出操作的運(yùn)算符是<<。
在C++中將左移(<<)和右移(>>)重載為輸出和輸入運(yùn)算符,并對“<<”和“>>”賦予了新的含義,分別稱為流插入與流提取。
在C++中為輸入/輸出流各建立了一個(gè)隊(duì)列結(jié)構(gòu)緩沖區(qū)。每次的輸出操作都是將數(shù)據(jù)插入到隊(duì)尾,每次的輸入操作都是從隊(duì)首取數(shù)據(jù)。輸出數(shù)據(jù)先插入到輸出流隊(duì)列的尾部,稱為插入,用“<<”運(yùn)算符表示。輸入數(shù)據(jù)就是從輸入流隊(duì)列中提取,用“>>”運(yùn)算符表示。8.1.2I/O流類
I/O相關(guān)的類及繼承關(guān)系參見圖8-1。圖8-1流類的繼承關(guān)系基類ios類是一個(gè)虛基類,它提供了對流進(jìn)行格式化輸入/輸出操作以及錯(cuò)誤處理的函數(shù)。ios類的派生類istream和ostream分別提供對流進(jìn)行輸入/輸出操作的成員函數(shù)。iostream復(fù)合繼承了istream和ostream類,它具有這兩個(gè)類的行為,因此在大多數(shù)C++程序中都包含iostream這個(gè)頭文件,其中包含了大量的輸入與輸出所需的信息。
istream類的派生類ifstream包含了對文件執(zhí)行輸入操作的成員函數(shù),ostream類的派生類ofstream包含了對文件執(zhí)行輸出操作的成員函數(shù)。fstream繼承iostream類,它同時(shí)具有輸入與輸出行為。在C++中,若要對文件進(jìn)行操作,都要包含fstream這個(gè)頭文件。8.1.3流對象及操作過程
cout是ostream流類的對象。它在iostream頭文件中定義為:
ostreamcout(stdout);
它是以標(biāo)準(zhǔn)輸出設(shè)備名作為其構(gòu)造函數(shù)的參數(shù),這樣就將cout與顯示器關(guān)聯(lián)。若有cout<<x;,則將x單元內(nèi)的值插入到名為cout的輸出流中,即送給顯示器。
ostream流類對應(yīng)的每個(gè)基本數(shù)據(jù)類型都有重載函數(shù),它們在ostream中這樣聲明:
ostream&operator<<(ostream&dest,char*pSource);
ostream&operator<<(ostream&dest,intsource);
ostream&operator<<(ostream&dest,charsource);
ostream&operator<<(constvoid*); //等等
同理,cin是istream流類的全局對象,istream流類也有若干個(gè)重載函數(shù):
istream&operator>>(istream&dest,char*pSource);
istream&operator>>(istream&dest,intsource);
istream&operator>>(istream&dest,charsource); //等等在標(biāo)準(zhǔn)類庫中提供了許多這樣的重載流插入或流提取運(yùn)算符的函數(shù),在此僅列出幾個(gè)。讀者要想進(jìn)一步了解,可參考C++系統(tǒng)的類庫指南。
在C++中對于一些cout<<的操作都通過匹配重載函數(shù)來實(shí)現(xiàn)。若有:cout<<"IlearnC++";,由于“<<”是操作符,它的左邊是ostream類的對象cout,右邊是char*類型,即字符串,因此自動(dòng)匹配ostream&operator<<(ostream&dest,char*pSource)重載函數(shù)。若有cout<<"thisis"<<8;,因運(yùn)算符“<<”具有左結(jié)合性,所以可以看做為:(cout<<"thisis")<<8;。由于cout<<"thisis"返回對象的引用,因此得出cout<<"thisis"的類型與cout的相同,即都是ostream。那么該引用再與后面的8又自動(dòng)匹配了另一個(gè)ostream&operator<<(ostream&dest,intsource);操作符,結(jié)果構(gòu)成了可連續(xù)(輸出)插入。在C++中對每一種內(nèi)部類型數(shù)據(jù)的輸出都有重載函數(shù),因此用cout<<輸出內(nèi)部類型數(shù)據(jù)時(shí),無論內(nèi)部類型是什么,它都能自動(dòng)尋求匹配重載函數(shù)。在需要時(shí),用戶還可以通過重載流插入與流提取運(yùn)算符設(shè)計(jì)自己的輸入/輸出操作。
【例8-1】通過重載使流插入運(yùn)算符作用于自定義對象。
#include<iostream>
#include<string>
usingnamespacestd;
classStudent
{public: Student(inta,strings,doubleb)
{name=s;num=a;score=b;}
staticinti;
stringname;
intnum;
doublescore;
};
intStudent::i=0;ostream&operator<<(ostream&str,StudentObj)
{Student::i++;
str<<Student::i<<“:\t”<<Obj.num<<‘\t’<<O<<‘\t’<<Obj.score<<endl;
returnstr;
//返回已插入數(shù)據(jù)的流對象
}
voidmain()
{Studenta(11,"Ally",3),b(22,"Halevy",4),c(33,"Jonas",5);
cout<<"\tNo"<<'\t'<<"Name"<<'\t'<<"Score"<<endl;
cout<<a<<b<<c<<endl;//該句的輸出格式由重載函數(shù)決定
}運(yùn)行結(jié)果:
No Name Score
1: 11 Ally 3
2: 22 Halevy 4
3: 33 Jonas 5
從結(jié)果來看,通過重載指定了用戶要求的格式。有了這些重載函數(shù),可以將標(biāo)準(zhǔn)設(shè)備流對象cout、cerr和clog以及用戶自定義的流對象一起使用。8.2.1格式控制
在此前的程序中已使用了輸入與輸出,但都用的是默認(rèn)方式,沒有對輸入與輸出實(shí)現(xiàn)有效的控制。默認(rèn)的輸出格式是:十進(jìn)制數(shù),右對齊,6位有效位(不包括小數(shù)點(diǎn))。在輸出浮點(diǎn)數(shù)時(shí),若整數(shù)部分位數(shù)超過6位,則用科學(xué)記數(shù)法輸出;若整數(shù)部分位數(shù)小于或等于6位,則用浮點(diǎn)數(shù)法輸出;當(dāng)輸出數(shù)據(jù)的冪小于-4時(shí),用科學(xué)記數(shù)法輸出。而實(shí)際應(yīng)用中僅靠這些默認(rèn)格式是不夠的,往往對輸入與輸出格式有新的要求。8.2格?式?化?操?作將輸入與輸出中對數(shù)據(jù)格式的要求用一個(gè)長整型數(shù)表示,稱為格式狀態(tài)志或格式標(biāo)志。在C++中對輸入和輸出的格式控制提供了兩種方法,即用ios類的成員函數(shù)和用流操作算子,將方法與格式狀態(tài)志結(jié)合起來,可實(shí)現(xiàn)對輸入和輸出的有效控制。8.2.2格式狀態(tài)志
在ios類中有l(wèi)ongx_flags;,它是受保護(hù)的成員,要用成員函數(shù)才可訪問。x_flags低16位中的每一位的狀態(tài)都表示著一種控制方式,因此將它稱為格式狀態(tài)志。由于直接記憶標(biāo)志中的某一位對應(yīng)某一狀態(tài)不方便,因此用枚舉符號(hào)常量定義了x_flags的每一位狀態(tài)標(biāo)志。x_flags中的某位為1,則相應(yīng)的特性有效;某位為0,則相應(yīng)的特性無效。在ios中定義的數(shù)據(jù)格式化標(biāo)志如下:
enum //定義了一個(gè)無名枚舉類型
{skipws=0x0001,
//忽略輸入流中的空白(如空格、制表符、回車、換行等)
left=0x0002, //左對齊
right=0x0004, //右對齊
internal=0x0008, //符號(hào)左,數(shù)值右對齊oct=0x0020, //置基數(shù)為八進(jìn)制,以八進(jìn)制形式輸入/輸出
hex=0x0040,
//十六進(jìn)制,只對整數(shù)有用,以十六進(jìn)制形式輸入/輸出
showbase=0x0080,
//輸出數(shù)制的基數(shù),如輸出2A時(shí)將輸出0x2A
showpoint=0x0100, //輸出小數(shù)點(diǎn)和尾數(shù)中的0
uppercase=0x0200, //十六進(jìn)制數(shù)大寫輸出
showpos=0x0400, //強(qiáng)制打印+(正)號(hào),只對十進(jìn)制起作用
scientific=0x0800,
//科學(xué)記數(shù)法,浮點(diǎn)數(shù)用科學(xué)記數(shù)(指數(shù))法表示
fixed=0x1000, //定點(diǎn)浮點(diǎn)數(shù)輸出,小數(shù)點(diǎn)后占六位
unitbuf=0x2000, //每次插入后刷新所有流
};8.3.1ios類和ostream類的成員函數(shù)
ios類中提供了一些公有成員函數(shù)。因?yàn)閏out是ostream類的對象,所以它可調(diào)用ostream類和ios類的成員函數(shù)。8.3ios類的成員函數(shù)
1.主要函數(shù)的功能
1)?ios::setf
setf用于設(shè)置格式標(biāo)志。它的功能是設(shè)置新格式標(biāo)志,返回原格式標(biāo)志。它的函數(shù)原型:
longsetf(longlFlags);
longsetf(longlFlags,longlMask);
當(dāng)格式標(biāo)志是表8-2中的第一個(gè)參數(shù)時(shí),需要提供第二個(gè)參數(shù)。而且,第一個(gè)參數(shù)是否設(shè)置成功依賴于第二個(gè)參數(shù)。表8-2參數(shù)表
2)?ios::unsetf
unseft用于取消格式標(biāo)志。它的功能是取消格式標(biāo)志,并返回被取消的格式標(biāo)志。它的函數(shù)原型:
longunsetf(longlFlags);
3)?ios::flags
flags用于設(shè)置格式標(biāo)志或獲取當(dāng)前格式標(biāo)志的狀態(tài)。它的函數(shù)原型:
longflags()const;
longflags(longlFlags);若flags函數(shù)參數(shù)為空,則該函數(shù)用于獲取當(dāng)前格式標(biāo)志的狀態(tài)。若flags函數(shù)給出參數(shù),則該函數(shù)用于設(shè)置格式標(biāo)志。在設(shè)置格式標(biāo)志時(shí),該函數(shù)能設(shè)置新標(biāo)記,清除舊標(biāo)記,并返回舊標(biāo)記。
4)?ios::precision
precision用于設(shè)置輸出精度,即總有效位數(shù)。它的函數(shù)原型:
intprecision()const;
intprecision(intnp);默認(rèn)精度為6位,不含小數(shù)點(diǎn)。該函數(shù)的功能是獲得原輸出精度和設(shè)置新輸出精度。精度設(shè)置后可以保留,直到下次重新設(shè)定。若已指定為scientific或fixed格式,然后設(shè)置精度,那么該精度值就是小數(shù)點(diǎn)后的位數(shù)。
5)?ios::fill
fill用于設(shè)置填充字符。它的函數(shù)原型:
charfill()const;
charfill(charcFill);該函數(shù)的功能是獲得原填充字符和設(shè)置新填充字符。默認(rèn)的填充字符是空格。填充字符設(shè)置后可以保留,直到下次重新設(shè)定。
6)?ios::width
width用于設(shè)置域?qū)挕K暮瘮?shù)原型:
intwidth(intnw);
intwidth()const;
該函數(shù)的功能是設(shè)置新的最小域?qū)挘祷卦驅(qū)挕W钚∮驅(qū)捠侵府?dāng)實(shí)際值大于設(shè)定值時(shí)能自動(dòng)突破。域?qū)捲O(shè)置后不能保留,僅一次性有效。默認(rèn)域?qū)捰蓪?shí)際數(shù)據(jù)位數(shù)決定。
7)?ostream::put
put用于輸出一個(gè)字符。它的函數(shù)原型:
ostream&put(charch);
該函數(shù)的功能是將字符輸出到ostream流類對象(顯示器)上。
8)?ostream::write
write用于無格式輸出。它的函數(shù)原型:
ostream&write(constchar*pch,intnCount);
該函數(shù)的功能是將給出的字符串以及指定字符個(gè)數(shù)送給顯示器。
2.應(yīng)用舉例
因?yàn)閏out就是ostream流類對象之一,所以在此我們以它為例來了解一些ostream流類成員函數(shù)的使用方法。
【例8-2】演示格式控制。
#include<iostream>
#include<iomanip>
usingnamespacestd;
voidmain(){cout<<“|”<<123<<“|\n”; //以默認(rèn)方式輸出|123|
cout<<“|”<<123.456<<“|\n”; //輸出|123.456|
cout.setf(ios::fixed,ios::floatfield); //設(shè)置fixed方式
cout<<“|”<<123.456<<“|\n”; //輸出|123.456000|
cout.setf(ios::showpos); //設(shè)置showpos方式
cout.setf(ios::scientific,ios::floatfield);
//設(shè)置scientific方式cout<<“|”<<123<<“|\n”; //以showpos與scientific方式輸出|+123|
cout<<“|”<<123.456<<“|\n”; //輸出|+1.234560e+002|
cout.unsetf(ios::showpos|ios::scientific);
//同時(shí)取消showpos和scientific方式
cout.setf(ios::showbase|ios::uppercase); //設(shè)置基數(shù)標(biāo)記,如0X
cout.setf(ios::hex,ios::basefield); //設(shè)置十六進(jìn)制數(shù)
cout<<“|”<<123<<“|\n”;
//以hex|showbase|uppercase方式輸出|0X7B|
cout<<“|”<<123.456<<“|\n”;
//輸出|123.456|。非十進(jìn)制數(shù)只對整數(shù)有效
cout.unsetf(ios::hex);
//取消hex。注:showbase|uppercase未取消
cout<<"|";cout.width(15); //域?qū)捲O(shè)置后僅一次性有效
cout<<123<<“|\n”;
//默認(rèn)方式,輸出|123|
cout<<"|"<<123.456<<"|\n"; //默認(rèn)方式,輸出|123.456|
cout.fill('#'); //設(shè)置填充,可保留
cout.setf(ios::left,ios::adjustfield); //設(shè)置左對齊
cout<<"|";cout.width(15);
//對于填充要給出寬度,否則無法填充
cout<<123<<“|\n”; //輸出|123############|
cout.unsetf(ios::left); //取消左對齊,默認(rèn)為右對齊
longformat=cout.flags(ios::hex|ios::showbase|ios::scientific);
//設(shè)置新標(biāo)志,保存原標(biāo)志
cout<<“|”<<123<<“|\n”;
//輸出|0x7b|
cout<<“|”<<123.456<<“|\n”;
//輸出|1.2346e+002|scientific方式,精度為4
cout.flags(format);//恢復(fù)原保存在format中的格式
}當(dāng)scientific與fixed均不設(shè)置時(shí),編譯器自動(dòng)選擇一種合適的方式輸出數(shù)據(jù),即當(dāng)冪小于-4或大于默認(rèn)precision精度時(shí),采用scientific科學(xué)記數(shù)法,否則采用fixed普通法。
【例8-3】演示precision與scientific或fixed的配合使用。
#include<iostream>
usingnamespacestd;
voidmain()
{cout.precision(4);cout<<123<<endl; //以默認(rèn)方式輸出123
cout<<123.456<<endl; //輸出123.5
cout<<1234.56<<endl; //輸出1235
cout.setf(ios::scientific,ios::floatfield); //設(shè)置scientific方式
cout<<123<<endl; //輸出123
cout<<"["<<123.456<<"]\n"; //輸出[+1.2346e+002]
cout.unsetf(ios::scientific); //取消scientific方式cout<<123.456<<endl; //輸出123.5
cout.setf(ios::fixed,ios::floatfield); //設(shè)置fixed方式
cout<<“[”<<123<<“]\n”; //輸出123
cout<<“[”<<123.456<<“]\n”; //輸出123.4560
}
當(dāng)precision與scientific或fixed合用時(shí),該精度指小數(shù)點(diǎn)后的總位數(shù)。對于precision,若未設(shè)定scientific或fixed,則精度是不含小數(shù)點(diǎn)的總位數(shù),若整數(shù)位數(shù)大于給出的精度,則按實(shí)際輸出。8.3.2ios類和istream類的成員函數(shù)
ios類中提供了一些公有成員函數(shù)。因?yàn)閏in是istream類的對象,所以它可調(diào)用istream類和ios類的成員函數(shù)。
1.主要函數(shù)的功能
1)?istream::read
read用于無格式輸入。它的函數(shù)原型:
istream&read(char*pch,intnCount);該函數(shù)的功能是從輸入流中讀入nCount個(gè)字符放在pch所指向的單元中,尾部不加\0。它是不能保留的,即設(shè)置后一次有效。
2)?ios::width
width用于設(shè)置域?qū)?。該函?shù)的功能是設(shè)置允許輸入流一次可讀入的字符個(gè)數(shù)。它是不能保留的,即設(shè)置后一次有效。
3)?istream::get
get用于輸入字符。它的函數(shù)原型主要有三個(gè):
intistream::get();從(輸入流)鍵盤中讀取一個(gè)字符,并返回該字符值,若已到達(dá)文件的末尾,則返回EOF。
istream&get(char&ch);
從輸入流中讀取一個(gè)字符存儲(chǔ)在ch中,它返回被引用的istream對象。
istream&get(char*pch,intnCount,chardelim=‘\n’);。
從(輸入流)鍵盤中讀取nCount-1個(gè)字符,放入pch指向的單元中,若其中發(fā)現(xiàn)了'\n'或到達(dá)了文件的末尾,則提前結(jié)束。
4)?istream::getline
getline用于輸入字符。它的函數(shù)原型:
istream&getline(char*pch,intnCount,chardelim=‘\n’);
該函數(shù)的功能是從(輸入流)鍵盤中讀取nCount-1個(gè)字符,放入pch指向的單元中,若其中發(fā)現(xiàn)了‘\n’或到達(dá)了文件的末尾,則提前結(jié)束。
5)?istream::gcount
gcount用于統(tǒng)計(jì)輸入字符的個(gè)數(shù)。它的函數(shù)原型:
intgcount()const;
2.應(yīng)用舉例
因?yàn)閏in就是istream流類對象之一,所以我們以它為例來說明istream流類成員函數(shù)的使用方法?!纠?-4】演示read、gcount、width的使用。
#include<iostream>
usingnamespacestd;
constintN=80;
voidmain()
{inti=0;chara[N];
cout<<"Enterthefirstsentence:\n";
cin.read(a,9); //僅在以后的一次輸入流中能讀入9個(gè)字符
cout<<"Thesentenceenteredwas:"<<endl;cout.write(a,cin.gcount());
//輸出a數(shù)組中的cin.gcount()個(gè)字符
cout<<endl;
cout<<"Enterthesecondsentence:"<<endl;
while(i<3) //控制讀入3次
{cin.width(3); //一次讀2個(gè)字符,即兩字符后加\0結(jié)尾
cin>>a; //將讀入的兩個(gè)字符串放入a中
cout<<"a:"<<a<<'\n'; //輸出
i++;
cout<<"i:"<<i<<endl;
}
}運(yùn)行結(jié)果:
Enterthefirstsentence:
12345abcdefghijk↙
Thesentenceenteredwas:
12345abcd
Enterthesecondsentence:
a:ef
i:1
a:gh
i:2
a:ij
i:3程序中的cin.gcount()用來統(tǒng)計(jì)輸入流中的字符數(shù)。由于前面有cin.read(a,9);,所以,cin.gcount()的結(jié)果為9,于是運(yùn)行結(jié)果就輸出a數(shù)組中的9個(gè)字符。
【例8-5】演示用get輸入一系列字符串,用默認(rèn)終止符終止輸入。
#include<iostream>
usingnamespacestd;
constintSIZE=80;
main()
{charbuffer1[SIZE],buffer2[SIZE];
cout<<"Enterasentence:\n";
cin.get(buffer1,SIZE);
//從當(dāng)前位置起,讀入SIZE-1個(gè)字符給buffer1數(shù)組
cin.get();
//消除該終止符
cin.get(buffer2,SIZE); //讀入\n即終止
cout<<"\nThestringinbuffer1was:"<<buffer1<<"\n";
cout<<"Thestringinbuffer2was:"<<buffer2<<endl;
return0;
}運(yùn)行結(jié)果:
Enterasentence:
IlearnC++↙
program↙
Thestringinbuffer1was:IlearnC++
Thestringinbuffer2was:program從運(yùn)行結(jié)果分析,在第一個(gè)get讀入時(shí),就將終止符之前的字符讀入數(shù)組buffer1中。當(dāng)?shù)诙€(gè)get讀入時(shí),首先遇到的是終止符\n,這樣讀取操作剛開始就結(jié)束了。數(shù)組buffer2中是由\0組成的空串。改進(jìn)方法是加入cin.get();,以消除終止符,這樣第二個(gè)get的讀入才可起作用。
【例8-6】演示用get輸入一系列字符串,通過自己指定終止符X來結(jié)束輸入。
#include<iostream>
usingnamespacestd;
voidmain()
{charstr[128];cout<<“inputalineoftextandpressEnter”<<endl;
cin.get(str,sizeof(str),‘X’);
//讀入后放在str中。指定X為終止符
cout<<“Firstline:”<<str<<endl;
cin.get(str,sizeof(str));
cout<<“Secondline:”<<str<<endl;
}
運(yùn)行結(jié)果:
顯示 inputalineoftextandpressEnter
輸入 YouarestudentXYoulearnC++↙
輸出 Firstline:Youarestudent
Secondline:XYoulearnC++;//注意,前面有一個(gè)X【例8-7】演示函數(shù)getline的使用。
#include<iostream>
usingnamespacestd;
voidmain()
{charstr[128];
cout<<“inputalineoftextandpressEnter”<<endl;
cin.getline(str,sizeof(str),‘X’);
//首次讀入,在遇到X時(shí)結(jié)束操作
cout<<“Firstline:”<<str<<endl;
cin.getline(str,sizeof(str));
//再次讀入,默認(rèn)為遇到回車時(shí)結(jié)束操作
cout<<"Secondline:"<<str;
}運(yùn)行結(jié)果:
顯示 inputalineoftextandpressEnter
輸入 YouarestudentXYoulearnC++↙
輸出 Firstline:Youarestudent
Secondline:YoulearnC++; //注意,不再有X
比較例8-6和例8-7的運(yùn)行結(jié)果可知,在例8-6中的“Secondline:”后多了一個(gè)X,這就是get和getline的區(qū)別。前者不從輸入流中清除輸入時(shí)指定的結(jié)束標(biāo)記,后者從輸入流中輸入時(shí)清除指定的結(jié)束標(biāo)記。8.3.3讀取標(biāo)準(zhǔn)串
cin.getline或cin.get都是讀取C格式串,即以\0結(jié)尾的串。在<string>文件中也有g(shù)etline函數(shù),它用于讀取標(biāo)準(zhǔn)串。string類的字符串稱為標(biāo)準(zhǔn)串,以\0結(jié)尾的字符串稱為C格式串。
【例8-8】演示讀取標(biāo)準(zhǔn)串。
#include<iostream>
usingnamespacestd;
#include<string>
voidmain(){stringa;cin>>a; //用cin讀標(biāo)準(zhǔn)串,讀入時(shí)遇空格等結(jié)束
cout<<a<<endl;
getline(cin,a); //從鍵盤中讀取標(biāo)準(zhǔn)串
cout<<a<<endl;
}
運(yùn)行結(jié)果:
IlearnC++↙
I //讀入一個(gè)單詞
learnC++
//learnC++前有空恪
在本例中直接用cin讀取標(biāo)準(zhǔn)串,由于用cin輸入時(shí)遇空格或回車便結(jié)束,于是cin>>a;只能讀入一個(gè)單詞,即I。8.4.1概念與應(yīng)用
在C++中除了類成員函數(shù)之外,C++的流類庫還提供了更方便的輸入/輸出格式化方法,該方法是使用一種稱為流操作算子(或操作符)的特殊函數(shù)。流操作算子的特點(diǎn)是能直接包含在輸入/輸出表達(dá)式中,所以使用更方便。
所有流操作算子均在頭文件iomanip中作了定義,使用時(shí)要包含該頭文件。一些常用的流操作算子如表8-3所示。8.4流?操?作?算?子表8-3流操作算子表
【例8-9】演示用流操作算子來控制在輸入/輸出中的數(shù)制。數(shù)制設(shè)定后能保留。
#include<iostream>
#include<iomanip>
usingnamespacestd;
voidmain()
{intm,n;
cin>>oct>>m; //輸入數(shù)據(jù)為八進(jìn)制
cin>>n; //仍為八進(jìn)制
cout<<"m(DEC)is"<<m<<ends; //輸出十進(jìn)制數(shù)
cout<<",n(DEC)is"<<n<<endl;cout<<m<<“Octalis”<<oct<<m<<endl;
//第一個(gè)m為十進(jìn)制,第二個(gè)m為八進(jìn)制
cout<<n<<“DECis”<<dec<<n<<endl;
//第一個(gè)n為八進(jìn)制,第二個(gè)n為十進(jìn)制
}
運(yùn)行結(jié)果:
1215↙
m(DEC)is10,n(DEC)is13
10Octalis12
15DECis13【例8-10】演示域?qū)捄途鹊奶幚矸椒ā?/p>
#include<iostream>
#include<iomanip>
#include<cmath>
usingnamespacestd;
voidmain()
{intm=20,n=12345;cout<<n<<'['<<setw(4)<<m<<']'<<'['<<m<<']'<<endl; //域?qū)捲O(shè)置僅一次有效
cout<<setw(4)<<n<<endl; //n域?qū)捥?,按?shí)際輸出
cout<<m<<"Hexadcimalis"<<hex<<m<<endl; //設(shè)置為十六進(jìn)制,并能保留
cout<<'['<<setw(8)<<n<<']'<<m<<endl; //設(shè)置域?qū)?/p>
cout<<m<<“Decimalis”<<dec<<m<<endl; //改為十進(jìn)制方式
doubleroot=sqrt(2);
cout<<root<<endl;
//輸出浮點(diǎn)數(shù),默認(rèn)為六位,不含小數(shù)點(diǎn)
cout<<setprecision(8)<<root<<endl;
//不含小數(shù)點(diǎn)總共八位,并可保留
cout<<root<<endl;//仍舊保留為八位,直到下一次改變?yōu)橹?/p>
}運(yùn)行結(jié)果:
12345[20][20] //系統(tǒng)默認(rèn)右對齊
12345
20Hexadcimalis14
[ 3039]14
14Decimalis20
1.41421 //系統(tǒng)默認(rèn)六位,不包含小數(shù)點(diǎn)
1.4142136 //共八位不包含小數(shù)點(diǎn)
1.41421368.4.2自編流操作算子
我們可以自己編寫流操作算子,方法為編寫一個(gè)帶有ostream&參數(shù)的函數(shù),并返回該參數(shù)。若我們希望使用新的流操作算子HEX,則實(shí)現(xiàn)如下:
#include<iostream>
usingnamespacestd;
ostream&HEX(ostream&s)
{s.setf(ios::hex,ios::basefield);
returns;
}
voidmain()
{cout<<HEX<<315<<endl;} //輸出13b8.4.3流操作算子與狀態(tài)標(biāo)記合用
并不是說有了流操作算子狀態(tài)標(biāo)記就可取消,對于有些情況,需要流操作算子與狀態(tài)標(biāo)記合用。我們可以在使用流操作算子時(shí)提供狀態(tài)標(biāo)記作為參數(shù)。
【例8-11】通過狀態(tài)標(biāo)記和流操作算子兩者合用,輸出浮點(diǎn)數(shù)。
#include<iostream>
#include<iomanip>
usingnamespacestd;
voidmain()
{doublenum=22.0/7;cout<<num<<endl; //默認(rèn)輸出3.14286,總共六位
cout<<setiosflags(ios::hex)<<setprecision(4)<<num<<endl;
cout<<1.90<<endl; //精度還是4,不輸出無效的0
cout<<setiosflags(ios::showpoint)<<1.90<<endl;
//強(qiáng)制輸出小數(shù)點(diǎn)后無效的0
cout<<setiosflags(ios::fixed)<<setprecision(4)<<num<<endl;
cout<<1.90<<endl;
//小數(shù)仍保留4位cout<<resetiosflags(ios::fixed); //取消浮點(diǎn)顯示
cout<<setiosflags(ios::scientific)<<num<<endl;
//用指數(shù)形式輸出
cout<<resetiosflags(ios::scientific)<<num<<endl;
//取消指數(shù)法顯示
cout<<setiosflags(ios::fixed)<<num<<endl;
//改用浮點(diǎn)數(shù)輸出
cout<<setiosflags(ios::showpos)<<num<<endl;
//在正數(shù)前輸出+號(hào),輸出+3.1429
}運(yùn)行結(jié)果:
3.14286 //精度默認(rèn)為6
3.143 //hex不起作用
1.9 //不輸出無效的0
1.900 //精度為4
3.1429 //小數(shù)后有4位數(shù)1.9000 //小數(shù)后仍舊保留4位數(shù)
3.1429e+000
3.143 //取消指數(shù)形式后的顯示。此時(shí)的精度是4
3.1429 //又設(shè)定浮點(diǎn)數(shù),所以4是小數(shù)后的位數(shù)
+3.1429 //正數(shù)前強(qiáng)制輸出+號(hào)8.5.1概念
ofstream、ifstream和fstream是文件流類,分別是輸入、輸出和輸入/輸出文件流,它們在fstream中定義。使用這三個(gè)類時(shí)必須用#include命令將fstream頭文件包含進(jìn)來。
文件流類不是標(biāo)準(zhǔn)設(shè)備,所以沒有像cout那樣預(yù)先定義為全局對象。文件流類定義的操作應(yīng)用于外部設(shè)備,最典型的是磁盤文件。若要定義一個(gè)文件流類對象,就會(huì)自動(dòng)調(diào)用該類的構(gòu)造函數(shù)。8.5文件流類定義文件流類對象的方法:
類名對象名(文件名,打開方式和保護(hù)方式);
其中,文件的打開方式和保護(hù)方式參見表8-4。表8-4文件使用模式在文件流類的處理中還有幾個(gè)重載構(gòu)造函數(shù),其中常用的是下面幾種。
(1)用于創(chuàng)建ofstream類對象的構(gòu)造函數(shù):
ofstream::ofstream();
ofstream::ofstream(constchar*,int=ios::out,
int=filebuf::openprot); //打開指定文件
(2)用于創(chuàng)建ifstream類對象的構(gòu)造函數(shù):
ifstream::ifstream();
ifstream::ifstream(char*,int=ios::in,int=filebuf::openprot);其中,第1個(gè)參數(shù)是文件名,ios::in是打開方式,filebuf::openprot是保護(hù)方式。
(3)用于創(chuàng)建fstream類對象的構(gòu)造函數(shù):
fstream();
fstream(constchar*,int=ios::in|ios::out,int=filebuf::openprot);
其中,第1個(gè)參數(shù)是文件名,第2個(gè)參數(shù)是打開方式,第3個(gè)參數(shù)是文件保護(hù)方式。第2、3個(gè)參數(shù)都可以取默認(rèn)值。8.5.2使用方法
1.通過構(gòu)造函數(shù)打開文件
ofstream和fstream都具有重載的構(gòu)造函數(shù),在定義流對象時(shí)也可以給出0~3個(gè)指定參數(shù)。例如:
ofstreamout_file(“filename.txt”);
在定義文件流對象時(shí),通過構(gòu)造函數(shù)打開文件,于是就在文件流對象與文件之間建立了聯(lián)系。
2.通過成員函數(shù)打開文件
可以在定義了流對象之后,使用流類對象的成員函數(shù)open()打開文件,用close()關(guān)閉文件。打開文件之后就在文件流對象和文件之間建立了一個(gè)連接關(guān)系,關(guān)閉文件之后就斷絕了文件流對象和文件之間的連接關(guān)系。
打開文件函數(shù)open()的原型有幾種表現(xiàn)形式。在ifstream類中為:
voidopen(constchar*,int=ios::in,int=filebuf::openprot);
在ofstream類中為:
voidopen(constchar*,int=ios::out|ios::trunc,int=filebuf::openprot);
在fstream類中為:
voidopen(constchar*,int=ios::in|ios::out,int=filebuf::openprot);以上三個(gè)open函數(shù),都至少提供一個(gè)參數(shù)文件名。
一般情況下,都是用構(gòu)造函數(shù)打開文件。ifstream、ofstream和fstream都有自己的構(gòu)造函數(shù),它們具有與open函數(shù)相同的參數(shù)和默認(rèn)值。用構(gòu)造函數(shù)打開文件的同時(shí),流對象和文件之間就建立了聯(lián)系。
為了能對文件進(jìn)行操作,必須先定義文件流類的對象。例如:
ofstream out_file; out_file.open("filename.txt");先定義了一個(gè)輸出流對象,自動(dòng)調(diào)用無參構(gòu)造函數(shù),然后通過out_file.open(“filename.txt”);就建立了文件流類對象和文件的聯(lián)系,在此我們稱為打開文件。同理:
ifstreamin_file.open(“filename.txt”);
//定義了一個(gè)輸入流對象,并指定輸入文件
fstreamio_file.open(“filename.txt”);
//定義了一個(gè)輸入/輸出流、文件流對象,并指定操作文件8.5.3應(yīng)用舉例
通過文件流類的使用可以把一個(gè)文件連接到程序上,以便輸入和輸出。使用文件流類,首先要包含fstream頭文件。
1.ifstream和ofstream的應(yīng)用
【例8-12】演示簡單的文件讀/寫操作。
#include<fstream>
#include<iostream>
usingnamespacestd;
voidWrite()
{doublex;ofstreamoutfile(“score.txt”);
//打開或新建名為score.txt的文件
outfile<<"數(shù)學(xué)"<<'\t'<<"C++"<<endl; //寫入表頭
cin>>x;outfile<<x<<'\t'; //寫入成績
cin>>x;outfile<<x<<'\t';
}
voidRead(){doublex;chars[20];
ifstreamInfile(“score.txt”);
//打開或新建名為score.txt的文件
Infile>>s;cout<<s<<‘\t’; //讀入表頭,輸出時(shí)加入跳格
Infile>>s;cout<<s<<‘\t’<<endl;
//讀入表頭,輸出時(shí)加入跳格和回車
Infile>>x;cout<<x<<‘\t’; //讀入成績,輸出時(shí)加入跳格
Infile>>x;cout<<x<<‘\t’<<endl;
//讀入成績,輸出時(shí)加入跳格和回車
}
voidmain()
{Write()
Read();
}
【例8-13】在當(dāng)前目錄下建立一個(gè)名為sea的文件,內(nèi)容為:
Whatdoyouknowaboutthesea?Weknowthatitlooksveryprettywhenthesunisshinningonit.Wealsoknowthatitcanbeveryroughwhenthereisastrongwind.Whatotherthingsdoweknowaboutit?
建立sea文件的代碼為:
#include<iostream>
#include<fstream>
usingnamespacestd;
voidInput()
{charch;cout<<"Inputtexty/n?"<<endl;
cin>>ch;
if(ch=='n'||ch=='N')return;
cout<<"Inputtext.Endupas#"<<endl;
ofstreamoutfile("sea.txt"); //打開或新建名為sea.txt的文件
cin.get(ch); //先輸入的第一個(gè)字符
while(ch!='#') //輸入以上內(nèi)容并以#結(jié)束
{outfile.put(ch);cin.get(ch);}//存入文件sea中
outfile.close(); //關(guān)閉文件
}接上例,若在當(dāng)前目錄中有名為sea.txt的文件,則下面的程序用于打開該文件,并將它輸出顯示。
voidOutput()
{charfile[20],ch;cout<<“Pleaseinputfilename”<<endl;
cin>>file;
//輸入要打開的文件名和后綴
ifstreaminfile(file); //打開文件
if(!infile) //判斷打開是否有效
{cout<<“Sorryunabletoopen”<<file<<endl;exit(-1);}
while(infile.get(ch)) //從打開的文件中讀入字符賦給ch
cout.put(ch);
//將ch中的字符輸出到顯示器
cout<<endl;
infile.close();
}接上例,若在當(dāng)前目錄中有名為sea.txt的文件,則下面的程序用open函數(shù)打開該文件,將其改名后另存到c盤根目錄下,并且使文件為未知類型。
voidSave_as()
{charfile[20];cout<<“pleaseinputfilename”<<endl;
cin>>file;
//輸入一個(gè)要打開的文件名
ifstreamopenfile;
openfile.open(file); //打開文件
ofstreamnewfile("c:\\dahai");//在c盤建立一個(gè)dahai的文件
if(!openfile)
{cout<<"Sorryunabletoopen"<<file<<endl;exit(-1);}charch;
while(openfile.get(ch))
//從被打開的文件中讀字符存于ch中
newfile.put(ch);
//將ch中的字符存于新建立的文件中
openfile.close();
newfile.close();
}
voidmain()
{Input();
Output();
Save_as();
}
2.fstream的應(yīng)用
用ifstream或ofstream可以建立輸入或輸出文件,用fstream既可以建立輸入文件,又可以建立輸出文件。
【例8-14】演示fstream的使用和文件的輸入與輸出。
#include<iostream>
#include<fstream>
usingnamespacestd;
voidRebuild() //輸入
{charch;cout<<“Inputtexty/n?”<<endl;
cin>>ch;
if(ch==‘n’||ch==‘N’)return;
fstreamiofile(“sea.txt”);
//以讀/寫方式打開名為sea的文本文件
while(ch!=‘#’) //約定輸入字符以#結(jié)束
{cin.get(ch);iofile.put(ch);}
//從鍵盤中讀入后,存入文件sea中
iofile.close();
}voidOutfile() //輸出
{charch;
fstreamoutfile("sea.txt");
//以讀/寫方式打開名為sea的文本文件
while(outfile.get(ch)) //先將字符讀入到ch中
cout.put(ch); //再送給顯示器
outfile.close();
}
voidmain()
{Rebuild();
Outfile();
}
fstream與ofstream的區(qū)別是:雖然用fstream或ofstream以默認(rèn)方式打開的文件都具有寫入功能,但用ofstream打開時(shí)若該文件不存在,則它具有新建一個(gè)文件的能力,而fstream卻沒有這個(gè)能力。在本例中sea.txt是文本文件,即Windows窗口中記事本文件,若用sea.doc就是Word文件。在C++中提供了一些處理字符的類——串流類,它們的繼承關(guān)系可以由圖8-2來描述。
ostringstream、istringstream、stringstream是串流類,在sstream頭文件中定義,使用時(shí)要包含相關(guān)頭文件。8.6串流類圖8-2串流類的繼承關(guān)系8.6.1串流類處理字符串
在C++中引入sstream的主要作用是可以使用字符串類,在sstream頭文件中已包含了string頭文件。
【例8-15】演示串流類istringstream的使用。
#include<iostream>
#include<sstream>
usingnamespacestd;
voidmain(){charstr[100]="Youareastudent.\n";
chara[10],b;
istringstreamai(str); //把str看做提取設(shè)備
ai>>a; //從ai中提取一串字符
cout<<a<<endl; //插入一個(gè)字符
ai>>b; //從ai中提取一個(gè)字符
cout<<b<<endl;
}
【例8-16】演示串流類istringstream結(jié)合string類的使用。
#include<iostream>
#include<sstream>
usingnamespacestd;
voidmain()
{stringstr="Youareastudent.\n"; //定義串流類對象
chara[10],b;
istringstreamai(str);
ai>>a;
cout<<a<<endl;
ai>>b;
cout<<b<<endl;
}
【例8-17】演示串流類ostringstream結(jié)合string類的使用。
#include<iostream>
#include<sstream>
usingnamespacestd;
stringparseString(char*pString)
{istringstreaminp(pString);
intNumber;floatbalance; //帳號(hào)和余額
inp>>Number>>balance; //自動(dòng)以空格等分隔ostringstreamoutp;
outp<<"aNumber="<<Number<<",balance="<<balance<<'\0';
returnoutp.str(); //將ostringstream對象轉(zhuǎn)換為string對象
}
voidmain()
{char*str="1234100.35";
stringpBuf=parseString(str); //定義串流類對象
cout<<pBuf<<endl;
}
該例中串流類的成員函數(shù)str()返回與ostringstream類對象相關(guān)連的string類對象。在ostringstreamoutp中并沒有指出outp的大小,它由提取字符的長度決定。8.6.2串流類處理文件
【例8-18】若在當(dāng)前目錄中已經(jīng)有文件sea,我們在Input函數(shù)中將它打開,并將文件內(nèi)容讀入buf中,然后在主函數(shù)中將它輸出。
#include<iostream>
#include<fstream>
#include<sstream>
usingnamespacestd;stringInput()
{charch,name[40];
cin>>name;
fstreamfile_in(name); //打開文件備讀
ostringstreambuf;
while(file_in.get(ch))
buf.put(ch);returnbuf.str(); //將buf轉(zhuǎn)換成string對象再返回
}
voidmain()
{stringtext=Input();
cout<<text<<endl;
}
要了解更多的操作,請查看類庫手冊。8.7.1異常處理的概念
程序可能按我們的意愿終止,如用return語句或exit函數(shù),也可能因?yàn)槌绦蛑械哪撤N不當(dāng)而異常終止。異常是由系統(tǒng)運(yùn)行造成的可以預(yù)料、但不可避免的事件。例如,內(nèi)存空間不足、在硬盤上的文件被挪離、軟盤沒有放好、在運(yùn)算時(shí)除數(shù)為0或數(shù)組下標(biāo)越界等,這些都是運(yùn)行中的異常。異常處理(exceptionhandling)就是提供對可以預(yù)料的情況進(jìn)行必要處理的方法。它是處理程序運(yùn)行期間錯(cuò)誤的一種結(jié)構(gòu)化方法。8.7異常處理8.7.2異常處理的方法
在C++中異常處理由拋出異常、捕獲異常和處理異常三部分組成。拋出異常即根據(jù)設(shè)置條件決定是否拋出異常;捕獲異常就是尋找最佳匹配;處理異常即完成善后工作。C++通過三個(gè)保留關(guān)鍵字try、throw和catch來實(shí)現(xiàn)異常處理。
1.語法結(jié)構(gòu)
實(shí)現(xiàn)異常處理的基本結(jié)構(gòu)由try塊和catch塊組成。其中try塊的作用是檢測和拋出異常,catch塊的作用是捕獲和處理異常。
1)?try塊
關(guān)鍵字try和它后面由“{”、“}”所包圍的語句塊組成try塊。在該語句塊中包含用戶要求監(jiān)測的異常語句和拋出異常語句。拋出異??赏ㄟ^throw表達(dá)式來實(shí)現(xiàn),它由關(guān)鍵字throw后跟一個(gè)表達(dá)式構(gòu)成,該表達(dá)式的類型是被拋出異常的類型。
2)?catch塊
在try塊之后緊接著是catch與“{”、“}”所包圍的語句,我們稱為catch子句。這些catch子句組成的子句集合稱為catch塊或稱異常處理器。該語句塊的主要任務(wù)是捕獲異常,并通過catch子句來完成處理工作。程序員就在該語句塊中添加一些語句來實(shí)現(xiàn)善后處理工作。例如:
try{ //try塊開始
… //正常要求完成的功能語句
throwexception //發(fā)生異常時(shí)拋出exception
… //正常要求完成的功能語句
} //try塊結(jié)束catch(參數(shù)類型1){…異常發(fā)生后的處理語句塊…} //catch子句
catch(參數(shù)類型2){…異常發(fā)生后的處理語句塊…} //catch子句
catch(參數(shù)類型n){…異常發(fā)生后的處理語句塊…} //catch子句
以上各catch子句的集合稱為catch塊。要注意C++語法規(guī)定,try塊和catch塊之間不能有其他語句。
2.執(zhí)行過程
在C++中將由try和catch塊組成的結(jié)構(gòu)稱為異常機(jī)制,它使用的是將錯(cuò)誤報(bào)告和錯(cuò)誤處理相分離的方法。其中,try和監(jiān)測異常的語句塊稱為錯(cuò)誤報(bào)告;catch和處理語句塊稱為錯(cuò)誤處理。
C++的異常處理機(jī)制被稱為是不可恢復(fù)的,也就是說,一旦拋出異常,程序的執(zhí)行就不能夠在異常被拋出的地方繼續(xù)。它的執(zhí)行步驟可以簡單地描述如下:
(1)檢測。檢測結(jié)束后,如果不發(fā)生異常,則只執(zhí)行檢測和其他正常功能的語句。
(2)拋出。如果在try塊內(nèi)處理某程序時(shí)發(fā)生異常,則通過throw拋出一個(gè)exception信息,并以拋出異常的語句作為出口,在拋出異常的同時(shí)跳出try塊。在該try塊中,從拋出點(diǎn)開始到try塊結(jié)束之間的語句不再執(zhí)行。
(3)捕獲與處理。被拋出的異常就在各catch子句聲明的參數(shù)中尋找一種嚴(yán)格匹配,當(dāng)尋找到某一catch匹配時(shí),就執(zhí)行該catch子句。除了被匹配的catch子句外,其他的catch子句就不再執(zhí)行了。然后程序執(zhí)行catch塊后面的語句。
【例8-19】引入異常機(jī)制,實(shí)現(xiàn)兩數(shù)相除。
#include<iostream>
usingnamespacestd;
voidDivide(doublex,doubley)
{doublez;
try
{if(y==0) //檢測異常
throwy;
//拋出異常
z=x/y;
cout<<z;
}
catch(double){cout<<"exceptofdividingzero"<<endl;}
catch(...){}
}
voidmain()
{doublex,y;cin>>x>>y;
Divide(x,y);
}該例的執(zhí)行過程是:若y為0,則在try塊中拋出y,z=x/y;將不再執(zhí)行,繼而在catch塊中找到匹配后輸出提示信息,并結(jié)束函數(shù)Divide的調(diào)用;若y不為0,則輸出x/y的值。
在try后的throw可以是任何類型的數(shù)據(jù)。當(dāng)發(fā)生異常由throw拋出一個(gè)數(shù)據(jù)時(shí),根據(jù)該數(shù)據(jù)的類型,在catch的括號(hào)中尋找一個(gè)嚴(yán)格的匹配,找到后就執(zhí)行該子句,否則執(zhí)行默認(rèn)的catch子句。從throw拋出口開始,到try塊結(jié)束的語句不再執(zhí)行。
3.異常處理的規(guī)則
(1)?try和catch必須成對出現(xiàn)。try至少要有一個(gè)catch語句與之對應(yīng)。任意數(shù)量的catch塊只能緊跟在try塊之后,即catch塊和try塊之間不能有其他語句。
(2)可以有單獨(dú)的throw。有單獨(dú)的throw而不提供默認(rèn)的catch子句,不是好方法。當(dāng)有拋出而沒有被匹配時(shí),就調(diào)用unexpected()函數(shù),unexpected()又調(diào)用terminate()函數(shù),terminate()又調(diào)用abort()函數(shù),使程序緊急終止,這是一種不受歡迎的終止方式。
(3)引發(fā)異常的throw應(yīng)該放在try塊內(nèi),或者放在由try塊中直接或間接調(diào)用的函數(shù)體內(nèi)。
(4)?catch的參數(shù)表中最多只能有一個(gè)參數(shù)。catch的參數(shù)表中可以不給或只給出一個(gè)參數(shù)。若在catch語句塊中要使用被拋出的對象,那么在catch子句的參數(shù)表中就要給出對象名。這樣一來,當(dāng)拋出異常后就要發(fā)生拷貝,為了減少時(shí)間開銷,可以用指針或引用作為參數(shù)。
(5)建議提供一個(gè)默認(rèn)的catch子句。默認(rèn)的catch子句的參數(shù)用(…)表示,并將它放在catch子句的最后。catch(...)稱為默認(rèn)異常,它能捕獲任何異常。不要將此默認(rèn)異常放在其他catch語句塊之前,因?yàn)樗鼘θ魏蝨hrow的拋出都能接收。
4.實(shí)現(xiàn)異常處理的步驟
首先定義異常try語句塊,將所有可能產(chǎn)生錯(cuò)誤的語句框定在try塊內(nèi)。然后完成拋出異常throw語句,判斷是否發(fā)生異常,若是則拋出異常信息。最后定義異常處理的catch語句塊,將異常處理的語句放在catch塊內(nèi),完成異常處理。8.7.3異常處理的結(jié)構(gòu)與要求
1.異常處理的結(jié)構(gòu)
異常處理按結(jié)構(gòu)來分,有兩種處理方法:方法一,異常派生層次結(jié)構(gòu);方法二,異常枚舉族系。下面通過兩個(gè)例子來介紹。
【例8-20】演示拋出多種類型的數(shù)據(jù)及捕捉的方法,說明異常派生層次結(jié)構(gòu)。
#include<iostream>
#include<cmath>usingnamespacestd;
classCode
{public:
Code(inta,floatb){u=a;v=b;}
private:
intu;floatv;
};
voidTest(intx)
{inty=8,a[10];doublez;
try{ if(x==0)throwx;elsey=y/x; //拋出int
if(x>10&&x<50)throw‘A’;elsea[0]=y; //拋出char
if(x<0)throw3.1;elsez=sqrt(x); //拋出double
if(x==8)throwCode(3,3.4f); //拋出class
if(x>50)throw“program”; //拋出char*
cout<<“normal”<<endl;
//若不發(fā)生異常能執(zhí)行到該句
}catch(int){cout<<“exceptofdividingzero”<<endl;}
catch(char){cout<<“erroroverbounder”<<endl;}
catch(double){cout<<“errorx<0”<<endl;}
//聲明時(shí)只給出類型
catch(char*p){cout<<p<<endl;}
//語句塊中使用p,參數(shù)中就要給出
catch(Code){cout<<“throwCode”<<endl;}
catch(...){cout<<“default...”<<endl;}
//默認(rèn)必需(...),即三小點(diǎn)不可少
cout<<"Testprogramreturn"<<endl;//總要執(zhí)行該句
return;
}voidmain()
{intx;cout<<"inputanumber"<<endl;cin>>x;
Test(x);
cout<<"mainend"<<endl; //總要執(zhí)行該句
}當(dāng)throw拋出某類型的數(shù)據(jù)或?qū)ο笾?,就在catch塊中按從上到下的順序,根據(jù)類型來尋找匹配。其中的匹配都是嚴(yán)格匹配,不存在轉(zhuǎn)換匹配。在catch塊中,只執(zhí)行匹配的catch子句,其余的catch子句不執(zhí)行。但catch語句塊之后的其他語句仍要執(zhí)行,如上例中的cout<<"Testprogramreturn"<<endl;。
【例8-21】演示用枚舉族系進(jìn)行異常處理。
#include<iostream>
usingnamespacestd;
enumException{noPrep,wrongFormat,noExit,zero};
i
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度廠房電氣系統(tǒng)升級(jí)改造合同范本4篇
- 2024新版二手房定金支付合同樣本版
- 二零二五年度新材料研發(fā)承包生產(chǎn)合同3篇
- 二零二四屬公積金貸款合同簽訂后的貸后審計(jì)與合規(guī)性檢查3篇
- 2024預(yù)定房屋買賣協(xié)議書
- 個(gè)人農(nóng)田租賃承包協(xié)議:2024年標(biāo)準(zhǔn)范本一
- 2024年04月江西九江銀行萍鄉(xiāng)分行社會(huì)招考筆試歷年參考題庫附帶答案詳解
- 2024年04月四川興業(yè)銀行瀘州分行招考筆試歷年參考題庫附帶答案詳解
- 2024版有限責(zé)任公司發(fā)起人協(xié)議書
- 2024年03月浙江中國工商銀行浙江平湖工銀村鎮(zhèn)銀行春季校園招考筆試歷年參考題庫附帶答案詳解
- 2024-2030年中國通航飛行服務(wù)站(FSS)行業(yè)發(fā)展模式規(guī)劃分析報(bào)告
- 機(jī)械制造企業(yè)風(fēng)險(xiǎn)分級(jí)管控手冊
- 地系梁工程施工方案
- 藏文基礎(chǔ)-教你輕輕松松學(xué)藏語(西藏大學(xué))知到智慧樹章節(jié)答案
- 2024電子商務(wù)平臺(tái)用戶隱私保護(hù)協(xié)議3篇
- 安徽省蕪湖市2023-2024學(xué)年高一上學(xué)期期末考試 英語 含答案
- 電力工程施工安全風(fēng)險(xiǎn)評(píng)估與防控
- 醫(yī)學(xué)教程 常見體表腫瘤與腫塊課件
- 內(nèi)分泌系統(tǒng)異常與虛勞病關(guān)系
- 智聯(lián)招聘在線測評(píng)題
- DB3418T 008-2019 宣紙潤墨性感官評(píng)判方法
評(píng)論
0/150
提交評(píng)論