第七章C++的流类库与输入输出本章介绍C++流概述、文件的输入输出、命名空间等内容。本章主要内容:C++流的概述预定义类型的输入输出用户自定义类型的输入输出文件的输入输出命名空间和头文件命名规则2019/12/21《面向对象的程序设计》-武大资环院2/457.1C++为何建立自己的输入输出系统因为在C++中用户需要定义众多的自定义类型,但是C语言的输入输出系统不支持用户自定义的类型。请看下面的类:classmy_class{inti;floatf;char*str;}obj;对此类类型,在C语言中下面的语句是不能接受的:printf("%my_class",obj);C++的流类比C的输入输出函数具有更大的优越性。7.2C++的流库及其基本结构7.2.1C++的流在C++中,流类是为输入输出提供的一组类,它们都放在流库中。流总是与某一设备相联系的(例如键盘、屏幕或硬盘等),通过使用流类中定义的方法,就可以完成对这些设备的输入输出操作。流具有方向性:与输入设备(如键盘)相联系的流称为输入流;与输出设备(如屏幕)相联系的流称为输出流;与输入输出设备(如磁盘)相联系的流称为输入输出流。7.2C++的流库及其基本结构C++中包含几个预定义的流对象,:标准输入流cin与标准输入设备相关联标准输出流cout与标准输出设备相关联非缓冲型的标准出错流cerr与标准错误输出设备相关联(非缓冲方式)缓冲型的标准出错流clog与标准错误输出设备相关联(缓冲方式)在缺省情况下,指定的标准输出设备是屏幕,标准输入设备是键盘。2019/12/21《面向对象的程序设计》-武大资环院6/21iosstreambufistreamfsteambasestrstreambaseostreamifstreamistrstreamofstreamostrstreamconstreamistream_withassignfstreamstrstreamostream_withassigniostreamiostream_withassign7.2.2流类库C++流类库具有两个平行的基类,即streambuf类和ios类,所有其他的流类都是从它们直接或间接地派生出来的,其中:ios类为输入输出操作在用户一方的接口,负责高层操作;streambuf类为输入输出操作在物理设备一方的接口,负责低层操作。7.3预定义类型的输入输出7.3.1无格式输入输出基于C++类库的输入输出需使用两个流对象cin和cout,还要用与之相配套的两个输入输出运算符“”和“”,其一般的格式为cin变量;//输人cout常量或变量;//输出1.输出运算符从运算符角度来看,输出通过输出运算符“”来完成的,输出运算符“”也称插入运算符,它是一个双目运算符,有两个操作数,左操作数为ostream类的一个对象(如cout),右操作数为一个系统预定义类型的常量或变量。例如coutThisisastring.\n;完成的功能为写字符串“Thisisastring.”到流对象cout,cout为标准输出流,通常为屏幕。7.3.2格式化输入输出C++提供了两种进行格式控制的方法:一种是使用ios类中有关格式控制的成员函数进行格式控制;另一种是使用称为操纵符的特殊类型的函数进行格式控制。1.用ios类的成员函数进行格式控制格式控制主要是通过对状态标志字的操作来完成的。在ios类的public部分定义了一个枚举,它的每个成员分别定义状态标志字的一个位,每一位都称为一个状态标志位。2.输入运算符从运算符角度来看,输入操作通过输入运算符“”来完成。输入运算符“”也称提取运算符,它也是一个双目运算符,有两个操作数,左面的操作数是istream类的一个对象(cin),右面的操作数是系统预定义的任何数据类型的变量。例如:intx;cinx;此时,用户从键盘输入的数值会自动地转换为变量x的类型,并存入变量x内。enum{skipws=0x0001,//跳过输入中的空白,可用于输出left=0x0002,//左对齐输出,可用于输出right=0x0004,//右对齐输出,可用于输出internal=0x0008,//在符号位和基指示符后填入字符,可用于输出dec=0x0010,//转换基制为十进制数,可用于输入或输出oct=0x0020,//转换基制为八进制数,可用于输入或输出hex=0x0040,//转换基制为十六进制数,可用于输入或输出showbase=0x0080,//在输出时显示基指示符,可用于输入或输出showpoint=0x0100,//在输出时显示小数点,可用于输出uppercase=0x0200,//十六进制输出时,表示制式//和表示数值的字符一律为大写,可用于输出showpos=0x0400,//对正整数显示正号,可用于输出scientific=0x0800,//用科学表示法显示浮点数,可用于输出fixed=0x1000,//用定点形式显示浮点数,可用于输出unitbuf=0x2000,//在输出操作后立即刷新所有流,可用于输出stdio=0x4000,//在输出操作后刷新stdout和stderr,可用于输出};这些枚举元素的值有一个共同的特点:分别使二进制表示的状态标志字的不同位为“1”,如:skipws0x00010000000000000001left0x00020000000000000010right0x00040000000000000100表7-1控制输入输出格式的成员函数函数原型功能longios∷setf(longflags);longios∷unsetf(longflags);longios∷flags();longios∷flags(longflags);intios∷width();intios∷width(intw);intios∷precision(intp);charios∷fill();charios∷fill(charch);设置状态标志flags清除状态标志,并返回前状态标志测试状态标志设置标志flags,并返回前状态标志返回当前的宽度设置值设置域宽w,返回以前的设置设置小数位数p,返回以前的小数位数返回当前的填充字符设置填充字符ch,返回当前的填充字符例7.3成员函数进行格式控制。#includeiostream.hmain(){coutx_width=cout.width()endl;coutx_fill=cout.fill()endl;coutx_precision=cout.precision()endl;cout123123.45678endl;cout_________________________________\n;cout***x_width=10,x_fill=,x_precision=4***\n;cout.width(10);cout.precision(4);cout123123.45678234.567endl;coutx_width=cout.width()endl;coutx_fill=cout.fill()endl;coutx_precision=cout.precision()endl;cout_________________________________\n;cout***x_width=10,x_fill=&,x_precision=4***\n;cout.fill('&');cout.width(10);cout123123.45678endl;cout.setf(ios::left);cout.width(10);cout123123.45678endl;coutx_width=cout.width()endl;coutx_fill=cout.fill()endl;coutx_precision=cout.precision()endl;return0;}程序运行结果如下:x_width=0x_fill=x_precision=0123123.45678-----------------------------***x_width=10,x_fill=,x_precision=4***123123.4568234.567x_width=0x_fill=x_precision=4-----------------------------***x_width=10,x_fill=&,x_precision=4***&&&&&&&123123.4568123&&&&&&&123.4568x_width=0x_fill=&x_precision=4C++提供的预定义操纵符如下:(1)dec以十进制形式输入或输出整型数,可用于输入或输出。(2)hex以十六进制形式输入或输出整型数,可用于输入或输出。(3)oct以八进制形式输入或输出整型数,可用于输入或输出。(4)ws用于在输入时跳过前导的空白符,可用于输入。(5)endl插入一个换行符并刷新输出流,仅用于输出。(6)ends插入一个空字符’\0’,通常用来结束一个字符串,仅用于输出(7)flush刷新一个输出流,仅用于输出(8)setbase(intn)设置转换基格式为为n(n的取值为0、8、10或16),n的缺省值为0,即表示采用十进制,仅用于输出。(9)resetiosflags(longf)关闭由参数f指定的格式标志,可用于输入或输出(10)setiosflags(longf)设置由参数f指定的格式标志,可用于输入或输出(11)setfill(intch)设置ch为填充字符,缺省时为空格,可用于输入或输出(12)setprecision(intn)设置小数部分的位数,可用于输入或输出(13)setw(intn)设置域宽为n,可用于输入或输出例7.4操纵符的使用。#includeiostream.h#includeiomanip.hmain(){coutsetw(10)123567endl;//①cout123setiosflags(ios::scientific)setw(20)//②123.456789endl;cout123setw(10)hex123endl;//③cout123setw(10)oct123endl;//④cout123setw(10)dec123endl;//⑤coutresetiosflags(ios::scientific)setprecision(4)//⑥123.456789endl;coutsetiosflags(ios::left)setfill('#')setw(8)//⑦123endl;coutresetiosflags(ios::left)setfill('$')setw(8)//⑧456endl;return0;}程序运行结果为:123567①1231.234567e+02②1237b③7b173④173123⑤123.4568⑥123#####⑦$$$$$456⑧3.用户自定义的操纵符若为输出流定义操纵符函数,则定义形式如下:ostream&manip_name(ostream&stream){…//自定义代码returnstream;}若为输入流定义操纵符函数,则定义形式如下:istream&manip_name(istream&stream){…//自定义代码returnstream;}例7.5为输出流定义操纵符函数。#includeiostream.h#includeiomanip.hos