《C++程序設(shè)計(jì)教程》課件第8章_第1頁
《C++程序設(shè)計(jì)教程》課件第8章_第2頁
《C++程序設(shè)計(jì)教程》課件第8章_第3頁
《C++程序設(shè)計(jì)教程》課件第8章_第4頁
《C++程序設(shè)計(jì)教程》課件第8章_第5頁
已閱讀5頁,還剩161頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論