《C++面向对象程序设计》教学内容第1章C++概述第2章类和对象第3章面向对象程序设计概述第4章进一步学习类和对象第5章堆与复制构造函数第6章继承性:派生类第7章运算符重载第8章虚函数和多态性第9章模板第10章类库和C++的标准模板库STL第11章输入输出流第12章异常处理第11章C++的输入输出系统:I/O流库11.1C++的输入输出流(I/OStreams)11.2重载输入输出运算符11.3输入输出格式控制11.4文件的输入输出操作11.1C++的输入输出流•I/O流的概念•输出流•输入流•输入/输出流为什么要有C++流类库•C语言的输入输出系统不支持拥护自定义的对象或数据类型,如一定义:structsample{inti;floatf;char*ch;}s1;•不能用输出函数来输出以上结构变量:printf(“%sample”,s1);为什么要有C++流类库•C++中,用户自定义的对象很多。C++的类机制允许它可以建立一个可控制的输入输出系统。可以通过重载“”和“”算符来解决以上的问题。•流stream–在数据从一个对象流动到另一个对象的过程中,无论是否对数据进行缓冲或对数据进行格式变换,这种流动都被抽象为流。流类库•流类库是提供一组类,程序利用它们可以方便的与外部世界交换数据.–C++的流类库是用继承的方法建立起来的一个输入输出类库。•流类库有两个基类,即streambuf类和ios类。•streambuf类提供对缓冲区的低级操作,如缓冲区的设置、缓冲区的读写等。•ios类用来完成检查错误的格式化输入、输出。流类库的结构流类的继承层次iosostreamistreamclogfstreamiostreamcerrcinifstreamofstreamcoutiostream.hI/O流类继承层次•ios–istream•istrstream•istream_withassign•ifstream–ostream•ostrstream•ostream_withassign•ofstreamIostreamfstreamstrstreamstdiostreamI/O流类继承层次Classios;classistream:virtualpublicios;classostream:virtualpublicios;classiostream:publicistream,publicostream;•又如:classistream_withassign:publicistream;classostream_withassign:publicostream;输出流和输出流对象•输出流对象是信息流动的目标.ostream,ofstream和ostrstream是三个最重要的输出流.•ostream类通过派生类ostream_withassign支持预先定义的流对象–cout标准输出–cerr标准错误输出,没有缓冲,发给它的内容立即输出–clog类似于cerr,但有缓冲,缓冲区满时被输出.•ofstream类支持磁盘文件输出.•ostrstream类支持输出字符串。流类库和流•C++中预定义了流类对象:–标准输入流cin–标准输出流cout–非缓冲的出错流cerr–和缓冲的出错流clog•每个流都和一种与设备相联系:–与输入设备(如键盘)联系的流为输入流;–与输出设备(如屏幕)联系的流为输出流。流类对象的操作•流类对象在使用前要被建立,在使用后要被删除;•使用特定的操作能够从流中获取数据–称为提取操作•或向流中添加数据–称为插入操作带空格space的字符串的输入方法#includeiostream.hvoidmain(){//读入一串字符到line数组,以‘t’终止charline[100];cout“Typealineterminatedby‘t’”endl;cin.getline(line,100,’t’);coutline;}注意:在使用读入字符串时,在遇到第一个空格字符后输入将停止。11.2重载I/O运算符•对于“”运算符的重载istream&operator(inti);istream&operator(longI);istream&operator(doubled);istream&operator(charc);istream&operator(constchar*s);11.2.1重载输出算符“”•定义输出运算符重载函数的一般格式如下:ostream&operator(ostream&stream,class_name,obj){函数体}函数中第一个参数是对ostream对象的引用。includeiostream.hclassDate{intmo,da,yr;public:Date(intm,intd,inty){mo=m;da=d;yr=y;}friendostream&operator(ostream&os,Datedt);};ostream&operator(ostream&os,Datedt){osdt.mo'/'dt.da'/'dt.yr;returnos;}voidmain(){Datedt(5,6,92);coutdt;}11.2.2重载输入运算符“”classuser_type{...friendistream&operator(istream&stream,user_type&obj){streamobj.member1;streamobj.member2;streamobj.member3;...returnstream;//返回流对象}}【例11.3】在Date类中重载了输入运算符“”istream&operator(istream&in,Date&dt){coutInputmonth,day,year:\n;indt.monthdt.daydt.year;returnin;}intmain(){Datedt;coutdt;cindt;//输入一个日期型对象coutdt;return0;}11.2.3综合应用举例#includeiostream.hclasscomplex//定义complex类{floatreal,image;public:complex(floatr,floati){real=r;image=i;}complex(){real=0;image=0;}friendcomplexoperator+(complex,complex);friendostream&operator(ostream&,complex&);friendistream&operator(istream&,complex&);};用和输出/入复数用和输出/入复数//定义重载运算符+complexoperator+(complexa,complexb){complextemp;temp.real=a.real+b.real;temp.image=a.image+b.image;returntemp;}用和输出/入复数//定义重载运算符ostream&operator(ostream&output,complex&obj){outputobj.real;if(obj.image0)output“+”;if(obj.image!=0)outputobj.imagei;returnoutput;}用和输出/入复数//定义重载运算符istream&operator(istream&input,complex&obj){cout“Inputtherealandimageofacomplex:\n”;inputobj.real;inputobj.image;returninput;}用和输出/入复数//主函数main(){complexc1(2.4,4.6),c2,c3;cout“Thevalueofc1is:”c1endl;cinc2;cout“Thevalueofc2is:”c2endl;c3=c1+c2;cout“Thevalueofc3is:”c3endl;return0;}用和输出/入复数//运行结果:Thevalueofc1is:2.4+4.6iInputtherealandimageofacomplex:3.72.5Thevalueofc2is:2.4+4.6iThevalueofc3is:2.4+4.6i11.3输入输出格式控制•插入运算符与预先定义的操纵符一起工作,用来控制输出格式。•通过已定义的操纵符可以控制输出宽度、输出格式、输出精度等。11.3.1使用ios的成员函数来控制输入输出数据的格式•在流类库中的基类ios类中定义了表示和控制输入输出数据格式状态(formatstate)的格式标志位(fmtflags),•表11.2中列出了所有的格式标志位。•例如left标志位表示输出数据左对齐,scientific标志位表示输出的浮点数据将以科学记数法格式输出。•通过修改流对象的格式标志位(fmtflags)就能够精确控制输入和输出数据的格式。设置格式标志位我们可以使用ios类的成员函数setf()来设置标志位。该函数的原型如下:fmtflagssetf(fmtflaqsflags);在ios类中的还有其他几个与输入输出数据格式有关的成员函数,这些函数可以设置输出数据的精度和宽度以及填充字符。【例11.6】使用函数setf()来设置标志位#includeiostreamusingnamespacestd;intmain(){cout.setf(ios::showpos);cout.setf(ios::scientific);cout19993.1415926endl;cout.setf(ios::uppercase);cout19993.1415926endl;cout.setf(ios::fixed);cout19993.1415926endl;return0;}【例11.6】输出结果•该程序运行后的输出结果为:+1999+3.141593e+000+1999+3.141593E+000+1999+3.14159控制输出数据的宽度•可使用setw操纵符或width成员函数来控制每个输出项的输出宽度:#includeiostream.hvoidmain(){doublevalues[]={1.23,35,36,653.7,4358.24};for(inti=0;i4;i++){cout.width(10);coutvalues[I]'\n';}}11.3.2使用操纵符来控制输入输出数据的格式•在C++输入输出系统中还可以通过C++流类库中预定义的操纵符来控制输出宽度、输出格式、输出精度等。•操纵符是一种特殊的函数,它们可以包含在输入输出表达式中。•请参见表11.3标准C++输入输出操纵符【例11.8】用setw操纵符来控制输出宽#includeiostream#includeiomanip//必须包含iomanip头文件usingnamespacestd;intmain(){doublevalues[]={1.23,35.36,653.7,4358.24};char*name[]={Bill,David,Frank,John};for(inti=0;i4;i++)coutsetw(6)name[i]setw(10)values[i]'\n';return0;}【例11.8】输出结果•该程序运行后的输出结果为:Bill1.23David35.36Frank653.7John4358.24