第九章流类库和输入输出宿州学院_第1页
第九章流类库和输入输出宿州学院_第2页
第九章流类库和输入输出宿州学院_第3页
第九章流类库和输入输出宿州学院_第4页
第九章流类库和输入输出宿州学院_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第九章第九章 流类库和输入流类库和输入/ /输出输出本章的最主要目的就是把对象保存到磁盘文件中并从本章的最主要目的就是把对象保存到磁盘文件中并从磁盘文件重建对象磁盘文件重建对象。c+语言中并没有输入语言中并没有输入/输出语句,而是在标准库输出语句,而是在标准库里包含了一个里包含了一个i/o流类库,它与标准模板库同为流类库,它与标准模板库同为c+标标准库中最重要的组成部分。数据从一个对象到另一个对准库中最重要的组成部分。数据从一个对象到另一个对象的传送被抽象为象的传送被抽象为“流流”。数据的输入。数据的输入/输出就是通过输出就是通过输入输入/输出流来实现的。输出流来实现的。 流是一种抽象的概念,

2、负责在数据的产生者和数据流是一种抽象的概念,负责在数据的产生者和数据的使用者之间建立联系,并管理数据的流动。的使用者之间建立联系,并管理数据的流动。 第九章第九章 流类库和输入流类库和输入/ /输出输出9.1 c+的基本流类体系的基本流类体系 9.3 标准设备的输入标准设备的输入/输出输出 9.2 输入输出的格式控制(选读)输入输出的格式控制(选读) 9.4 文件的输入与输出文件的输入与输出 9.5 字符串流(选读)字符串流(选读) 9.6 文件与对象文件与对象 9.1 c+的基本流类体系的基本流类体系流类体系:流类体系:以抽象类模板以抽象类模板basic_ios为基类,流类模板派生体系见图为

3、基类,流类模板派生体系见图9.1。整个流类模板体系的。整个流类模板体系的标准标准i/o在头文件在头文件中说明,它包含中说明,它包含头文件头文件、和和。而输入输出。而输入输出文件流文件流部分在头文件部分在头文件中说明。中说明。 图图9.1 主要输入主要输入/输出流模板层次输出流模板层次 basic_ iosbasic_ streambufbasic_ istreambasic_ ostreambasic_ ifstreambasic_ iostreambasic_ ofstreambasic_ fstream指针指针9.1 c+的基本流类体系的基本流类体系 basic_ios类模板提供了对流进行

4、格式化输入输出和错类模板提供了对流进行格式化输入输出和错误处理的成员函数。所有派生都是公有派生。误处理的成员函数。所有派生都是公有派生。basic_istream类模板提供完成提取(输入)操作的成员函类模板提供完成提取(输入)操作的成员函数,而数,而basic_ostream类模板提供完成插入(输出)操作类模板提供完成插入(输出)操作的成员函数。的成员函数。basic_iostream类本质上是前两者的类本质上是前两者的聚合聚合,并没有增加成员。派生全部为公有派生并没有增加成员。派生全部为公有派生。 有关有关模板派生模板派生请参见教学指导书第请参见教学指导书第8章中章中“类模板的派类模板的派生

5、的讨论生的讨论” basic_streambuf不是不是basic_ios的派生类,而是一个的派生类,而是一个独立的类,只是独立的类,只是basic_ios有一个保护访问限制的指针指有一个保护访问限制的指针指向它。向它。 类类basic_streambuf的作用是管理一个流的缓冲区。的作用是管理一个流的缓冲区。流类体系说明:流类体系说明:9.1 c+的基本流类体系的基本流类体系标准输入标准输入/ /输出流对象:输出流对象: 在在c+c+的流类库的流类库中定义了四个全局流对象:中定义了四个全局流对象:cin,cout,cerr和和clog。可以完成人机交互的功能。可以完成人机交互的功能。 cin

6、标准输入流对象,键盘为其对应的标准设备。标准输入流对象,键盘为其对应的标准设备。 cout标准输出流对象,显示器为标准设备。标准输出流对象,显示器为标准设备。 cerr和和clog标准错误输出流,输出设备是显示器。标准错误输出流,输出设备是显示器。 其中其中cin、cout和和clog是带缓冲区的,缓冲区由是带缓冲区的,缓冲区由streambuf类对象来管理。而类对象来管理。而cerr为为非缓冲区流,一旦非缓冲区流,一旦错误发生立即显示。错误发生立即显示。 要使用这四个功能,必须包含要使用这四个功能,必须包含iostream 文件。文件。 9.1 c+的基本流类体系的基本流类体系重载的重载的提

7、取运算符提取运算符“”(stream_extraction operator)和和插入运算符插入运算符“和和(istream&,classname&);friend ostream&operator”或或“”和和“”或或“”的左操作数;第二个参数为用户定义类的引用,的左操作数;第二个参数为用户定义类的引用,作为右操作数。作为右操作数。流用作函数参数,必须是引用调用,不能是传流用作函数参数,必须是引用调用,不能是传值调用。因为这里要求处理流本身,而不是副本。值调用。因为这里要求处理流本身,而不是副本。【例【例9.5】改进自定义字符串类,重载插入运算符改进自定义字符串类,重载插入运算符“”。【例【

8、例9.6】用户定义的复数类用户定义的复数类complex的输入与输出。的输入与输出。 9.4 文件的输入与输出文件的输入与输出 本节中文件指的是磁盘文件。本节中文件指的是磁盘文件。c+根据文件(根据文件(file)内容)内容的数据格式,可分为两类:二进制文件和文本文件。的数据格式,可分为两类:二进制文件和文本文件。文本文文本文件件由字符序列组成,也称由字符序列组成,也称ascii码文件,在文本文件中存取码文件,在文本文件中存取的最小信息单位为字符(的最小信息单位为字符(character),而),而二进制文件二进制文件中存中存取的最小信息单位为字节(取的最小信息单位为字节(byte)。)。c+

9、把每一个文件都看成一个有序的字节流,见图把每一个文件都看成一个有序的字节流,见图9.2,每一个文件或者以文件结束符(每一个文件或者以文件结束符(end of file marker)结束,)结束,或者在特定的字节号处结束。或者在特定的字节号处结束。 012436578n-1文件结束符文件结束符图图9.2 c+把文件看作有序的把文件看作有序的n个字节的流个字节的流文件的基本概念:文件的基本概念:9.4 文件的输入与输出文件的输入与输出当打开一个文件时,该文件就和某个流关联起来了。对文件进行读当打开一个文件时,该文件就和某个流关联起来了。对文件进行读写实际上受到一个写实际上受到一个文件定位指针(文

10、件定位指针(file position pointer)的控制。的控制。 输入流的指针也称为读指针,每一次提取操作将从读指针当前输入流的指针也称为读指针,每一次提取操作将从读指针当前所指位置开始,每次提取操作自动将读指针向文件尾移动。所指位置开始,每次提取操作自动将读指针向文件尾移动。 输出流指针也称写指针,每一次插入操作将从写指针当前位置输出流指针也称写指针,每一次插入操作将从写指针当前位置开始,每次插入操作自动将写指针向文件尾移动。开始,每次插入操作自动将写指针向文件尾移动。9.4.1 文件的打开与关闭文件的打开与关闭 9.4.2 文本文件的读写文本文件的读写9.4.3 二进制文件的读写二

11、进制文件的读写 9.4.4 文件的随机访问(选读)文件的随机访问(选读) 9.4.1 文件的打开与关闭文件的打开与关闭文件使用步骤:文件使用步骤:1说明一个文件流对象,这又被称为内部文件:说明一个文件流对象,这又被称为内部文件:ifstream ifile;/只输入用只输入用ofstream ofile;/只输出用只输出用fstream iofile;/既输入又输出用既输入又输出用 9.4.1 文件的打开与关闭文件的打开与关闭2使用文件流对象的成员函数打开一个磁盘文件。这样在文使用文件流对象的成员函数打开一个磁盘文件。这样在文件流对象和磁盘文件名之间建立联系。文件流中说明了三个打件流对象和磁盘

12、文件名之间建立联系。文件流中说明了三个打开文件的成员函数。开文件的成员函数。void ifstream:open(const char*,int =ios:in, int=filebuf:openprot);void ofstream:open(const char *,int=ios:out, int=filebuf:opernprot);void fstream:open(const char*,int, int=filebuf:openprot); 第一个参数为要打开的磁盘文件名。第二个参数为打开方式,第一个参数为要打开的磁盘文件名。第二个参数为打开方式,有输入(有输入(in),输出()

13、,输出(out)等,打开方式在)等,打开方式在ios基类中定义为基类中定义为枚举类型。第三个参数为指定打开文件的保护方式,一般取默枚举类型。第三个参数为指定打开文件的保护方式,一般取默认。认。所以第二步可如下进行:所以第二步可如下进行:iofile.open(“myfile.txt”,ios:in|ios:out);文件打开方式文件打开方式: :是由在是由在ios类中定义的公有枚举成员决定:类中定义的公有枚举成员决定:enum open_mode in=0 x01,out=0 x02,ate=0 x04,app=0 x08,trunc=0 x10,binary=0 x80;9.4.1 9.4.

14、1 文件的打开与关闭文件的打开与关闭 inin标识打开文件用于输入操作标识打开文件用于输入操作( (从文件读取从文件读取) )。打开方式只要含。打开方式只要含inin,如文件不存在则返回失败。在打开为输入输出方式时(同时用如文件不存在则返回失败。在打开为输入输出方式时(同时用outout),),编程应注意判断是否失败,失败时千万不可再写入文件。编程应注意判断是否失败,失败时千万不可再写入文件。 outout标识打开标识打开文件用于输出操作文件用于输出操作( (写入文件写入文件) )。如文件不存在,则。如文件不存在,则建立新文件,如文件存在,未同时设建立新文件,如文件存在,未同时设app, in

15、app, in则文件清空。则文件清空。 trunctrunc标识打开文件,并清空它(文件长度截为标识打开文件,并清空它(文件长度截为0 0)。文件不存在)。文件不存在则建立新文件,与则建立新文件,与outout默认操作相同。但与默认操作相同。但与inin配合,文件不存在则返配合,文件不存在则返回失败。回失败。 appapp标识打开文件用于输出,原文件内容保留,新数据接在尾部标识打开文件用于输出,原文件内容保留,新数据接在尾部 ateate意思是意思是at endat end,标识打开文件,文件指针在文件尾,但文件,标识打开文件,文件指针在文件尾,但文件指针可以移动,即新数据可写到任何位置。文件

16、是否清空由其它标识指针可以移动,即新数据可写到任何位置。文件是否清空由其它标识决定。决定。 后三个标识最好配合后三个标识最好配合outout、inin等一起用,因为不同的等一起用,因为不同的c+c+平台,要平台,要求不同,一起用不会出错。如不一起用,至少求不同,一起用不会出错。如不一起用,至少vc+vc+不认这种格式。不认这种格式。 binarybinary标识以二进制方式打开文件。同时用标识以二进制方式打开文件。同时用outout时,如文件不存时,如文件不存在,则建立新文件,并且新文件能用,不必清状态字。在,则建立新文件,并且新文件能用,不必清状态字。打开方式解释:9.4.1 文件的打开与关

17、闭文件的打开与关闭 三个文件流类都重载了一个带默认参数的三个文件流类都重载了一个带默认参数的构造函构造函数数,功能与,功能与open函数一样:函数一样:ifstream:ifstream(const char*, int=ios:in, int=filebuf:openprot);ofstream:ofstream(const char*,int=ios:out, int=filebuf:openprot);fstream:fstream(const char*,int, int=filebuf:operprot);所以所以1,2两步可合成:两步可合成:fstream iofile(”myfi

18、le.txt”,ios:in|ios:out);9.4.1 文件的打开与关闭文件的打开与关闭打开文件也应该判断是否成功,若成功,文件流对打开文件也应该判断是否成功,若成功,文件流对象值为非零值,不成功为象值为非零值,不成功为0(null),),文件流对象文件流对象值物理上就是指它的地址值物理上就是指它的地址。因此打开一个文件完整的程序为:因此打开一个文件完整的程序为:fstream iofile(”myfile.txt”,ios:in|ios:out);if(!iofile) /“!”为重载的运算符,见为重载的运算符,见9.3.1节节 cout”不能打开文件不能打开文件:”myfile.txt

19、”)和插入运算符)和插入运算符(”完成完成重构重构对象,而只用一个对象,而只用一个“”完成对象完成对象存入存入文文件。件。9.4.2 文本文件的读写文本文件的读写文本数据文件的读写:文本数据文件的读写:按按c+的常规,的常规,资源获取是由构造函数实现,而资资源获取是由构造函数实现,而资源释放是由析构函数完成源释放是由析构函数完成。所以与内存动态分配一。所以与内存动态分配一样,由文件重构对象放在构造函数中,把对象存入样,由文件重构对象放在构造函数中,把对象存入文件则放在析构函数中。详细内容见文件则放在析构函数中。详细内容见9.6节,更深节,更深层次的理由见下一章异常处理。【例层次的理由见下一章异

20、常处理。【例9.9】只是为】只是为了更清楚地显示文件的操作,常规做法请读者参见了更清楚地显示文件的操作,常规做法请读者参见【例【例9.13】。】。9.4.3 二进制文件的读写二进制文件的读写对二进制文件进行读写的成员函数:对二进制文件进行读写的成员函数:istream&istream:read(char *,int); /从二进制流提取从二进制流提取istream&istream:read(unsigned char*,int);/第一个参数指定存放有效输入的变量地址第一个参数指定存放有效输入的变量地址,必须必须强制转换强制转换为为char*类型类型/第二个参数指定提取的字节数第二个参数指定提

21、取的字节数,/函数从输入流提取指定数量的字节送到指定地址开始的单元函数从输入流提取指定数量的字节送到指定地址开始的单元ostream&ostream:write(const char *,int);/向二进制流插入向二进制流插入ostream&ostream:write(const unsigned char *,int);/第一个参数指定输出对象的内存地址第一个参数指定输出对象的内存地址,必须必须强制转换强制转换为为char*类型类型/第二个参数指定插入的字节数第二个参数指定插入的字节数,/函数从该地址开始将指定数量的字节插入输入输出流函数从该地址开始将指定数量的字节插入输入输出流9.4.3

22、 二进制文件的读写二进制文件的读写文件结束判断:文件结束判断:读函数并不能知道文件是否结束,可用状态函数读函数并不能知道文件是否结束,可用状态函数int ios:eof()来判断文件是否结束。必须指出系统是根据来判断文件是否结束。必须指出系统是根据当前操作当前操作的实际情况设置状态位,如需根据状态位来判的实际情况设置状态位,如需根据状态位来判断下一步的操作,必须在一次操作后立即去调取状态位,断下一步的操作,必须在一次操作后立即去调取状态位,以判断本次操作是否有效。以判断本次操作是否有效。【例【例9.10】创建二进制数据文件,以及数据文件的读创建二进制数据文件,以及数据文件的读取。这两项操作设计

23、为成员函数。给出与【例取。这两项操作设计为成员函数。给出与【例9.9】不】不同的读写方式:同的读写方式:9.4.3 二进制文件的读写二进制文件的读写二进制文件优点:二进制文件优点: 可以控制字节长度,读写数据时不会出现二义可以控制字节长度,读写数据时不会出现二义性,性,可靠性高可靠性高。同时不知格式是无法读取的,。同时不知格式是无法读取的,保密保密性好性好。文件结束后,系统不会再读(见。文件结束后,系统不会再读(见eofbit的说的说明),但明),但程序不会自动停下来程序不会自动停下来,所以要判断文件中,所以要判断文件中是否已没有数据。如写完数据后没有关闭文件,直是否已没有数据。如写完数据后没

24、有关闭文件,直接开始读,则必须把文件定位指针移到文件头。如接开始读,则必须把文件定位指针移到文件头。如关闭文件后重新打开,文件定位指针就在文件头关闭文件后重新打开,文件定位指针就在文件头。9.4.4 文件的随机访问(选读)文件的随机访问(选读)文件的随机访问:文件的随机访问:在在c+c+中可以由程序控制文件指针的移动,从而实现文件的中可以由程序控制文件指针的移动,从而实现文件的随机访问随机访问,即可,即可读写流中任意一段内容读写流中任意一段内容。一般文本文件很难准。一般文本文件很难准确定位,所以随机访问多用于二进制文件。确定位,所以随机访问多用于二进制文件。如【例如【例9.99.9】中对象中两

25、个字符串是按实际串长存放的,不是按】中对象中两个字符串是按实际串长存放的,不是按数组元素来存放的,而【例数组元素来存放的,而【例9.109.10】中是按数组长度来存放的,】中是按数组长度来存放的,每个对象数据长度固定,所以便于随机访问。每个对象数据长度固定,所以便于随机访问。在在ios类中说明了一个公有枚举类型:类中说明了一个公有枚举类型:enum seek_dirbeg=0, /文件开头文件开头cur=1, /文件指针的当前位置文件指针的当前位置end=2 /文件结尾文件结尾;随机访问指针控制字:随机访问指针控制字:9.4.4 文件的随机访问(选读)文件的随机访问(选读)输入流指针控制字设置

26、成员函数:输入流指针控制字设置成员函数:istream&istream:seekg(streampos); /指针直接定位指针直接定位istream&istream:seekg(streamoff, ios:seek_dir); /指针相对定位指针相对定位long istream:tellg(); /返回当前指针位置返回当前指针位置流的指针位置类型流的指针位置类型streampos和流的指针偏移类型和流的指针偏移类型streamoff定定义为长整型,也就是可访问文件的最大长度为义为长整型,也就是可访问文件的最大长度为4g例:例:datafile.seekg(-20l,ios:cur);/表示将

27、文件定位指针从当前位置向文件头部方向移表示将文件定位指针从当前位置向文件头部方向移20个字节。个字节。datafile.seekg(20l,ios:beg);/表示将文件定位指针从文件头向文件尾方向移表示将文件定位指针从文件头向文件尾方向移20个字节。个字节。datafile.seekg(-20l,ios:end);/表示将文件定位指针从文件尾向文件头方向移表示将文件定位指针从文件尾向文件头方向移20个字节。个字节。tellg()和和seekg()往往配合使用。往往配合使用。/指针不可移到文件头之前或文件尾之后。指针不可移到文件头之前或文件尾之后。9.4.4 文件的随机访问(选读)文件的随机访

28、问(选读)输入流指针控制字设置成员函数:输入流指针控制字设置成员函数:ostream&ostream:seekp(streampos);ostream&ostream:seekp(streamoff,ios:seek_dir);long ostream:tellp(); 为了便于记忆,函数名中为了便于记忆,函数名中g是是get的缩写,而的缩写,而p是是put的的缩写。缩写。对输入输出文件定位指针只有一个但函数有两组对输入输出文件定位指针只有一个但函数有两组,这,这两组函数功能完全一样。两组函数功能完全一样。 【例【例9.11】使用随机访问对【例使用随机访问对【例9.10】进行改造。】进行改造。

29、9.5 字符串流(选读)字符串流(选读)字符流概念:字符流概念: 字符串(字符串(string)也可以看作)也可以看作字符流字符流。可以用输入输出操。可以用输入输出操作来完成串流的操作。串流与内存相关,所以也称作来完成串流的操作。串流与内存相关,所以也称内存流内存流。 串流类包括串流类包括ostrstream、istrstream、strstream,它们在,它们在中说明。串流类对象可以保存字符,也可以保存中说明。串流类对象可以保存字符,也可以保存整数、浮点数。串流类对象采用整数、浮点数。串流类对象采用文本方式文本方式。其构造函数常用下面几个:其构造函数常用下面几个:istrstream:is

30、trstream(const char * str);istrstream:istrstream(const char * str,int);ostrstream:ostrstream(char *,int,int=ios:out);strstream:strstream(char *,int,int); 其中第二个参数说明数组大小,第三参数为文件打开方式其中第二个参数说明数组大小,第三参数为文件打开方式。【例【例9.12】9.6 文件与对象文件与对象在面向对象的在面向对象的c+程序设计中,文件应该程序设计中,文件应该在构造函数中打开在构造函数中打开,并并创建对象创建对象;而在;而在析构函数中

31、保存和关闭文件,并撤销对象析构函数中保存和关闭文件,并撤销对象。当撤销对象时,能自动释放资源。释放资源包括将对象中的信当撤销对象时,能自动释放资源。释放资源包括将对象中的信息再次存入磁盘文件。程序运行中,总要对保存在对象的数据息再次存入磁盘文件。程序运行中,总要对保存在对象的数据成员里的信息进行操作,这时应该将信息适时保存到相应的磁成员里的信息进行操作,这时应该将信息适时保存到相应的磁盘文件中,以免数据意外丢失。这些都是常规操作,是面向对盘文件中,以免数据意外丢失。这些都是常规操作,是面向对象的象的c+程序设计的固定框架。程序设计的固定框架。 规范化操作:规范化操作:在面向对象的程序设计中,信

32、息总是放在对象在面向对象的程序设计中,信息总是放在对象的数据成员里。这些信息最终应该保存到文件的数据成员里。这些信息最终应该保存到文件中。当程序开始运行时要由打开的文件重新创中。当程序开始运行时要由打开的文件重新创建对象。在运行过程中,放在对象的数据成员建对象。在运行过程中,放在对象的数据成员里的信息得到利用和修改。运行结束时必须把里的信息得到利用和修改。运行结束时必须把这些信息重新保存到文件中,然后关闭文件。这些信息重新保存到文件中,然后关闭文件。9.6 文件与对象文件与对象【例【例9.13】将商店的货物,定义为一个货物数组类。数将商店的货物,定义为一个货物数组类。数组对象动态建立,初始为组

33、对象动态建立,初始为2个元素,不够用时扩充一倍。用个元素,不够用时扩充一倍。用文本数据文件建立数组元素对象,要求放在构造函数中,文本数据文件建立数组元素对象,要求放在构造函数中,而数据的保存和文件的关闭放在析构函数中。第一次运行而数据的保存和文件的关闭放在析构函数中。第一次运行时,建立空的数据文件,由键盘输入建立数组元素对象,时,建立空的数据文件,由键盘输入建立数组元素对象,并写入文件,程序退出时,关闭文件;下一次运行由该文并写入文件,程序退出时,关闭文件;下一次运行由该文件构造对象,恢复前一次做过的工作。件构造对象,恢复前一次做过的工作。这是一个标准的面向对象的程序设计,也是对前面各章内容这

34、是一个标准的面向对象的程序设计,也是对前面各章内容的小结。注意,本例使用了的小结。注意,本例使用了多重的插入运算符重载多重的插入运算符重载。 第九章第九章 流类库和输入流类库和输入/ /输出输出结束结束谢谢!谢谢!9.2 输入输出的格式控制(选读)输入输出的格式控制(选读)访问访问x_flags的重载函数声明如下:的重载函数声明如下:inline long ios:flags() const; /返回当前标志字返回当前标志字inline long ios:flags(long ); /把参数作为新的标志字把参数作为新的标志字,并返回原标志字并返回原标志字(下同下同)inline long io

35、s:setf(long ,long ); /在原标志字上增加控制在原标志字上增加控制, /第一个参数为增加的控制第一个参数为增加的控制,第二个参数表示取代原来哪几位第二个参数表示取代原来哪几位inline long ios:setf(long ); /增加控制增加控制(多项多项)inline long ios:unsetf(long ); /清除指定位上的控制清除指定位上的控制9.2 输入输出的格式控制输入输出的格式控制(选读)(选读)相关接口函数为:相关接口函数为:inline int ios:width() const; /返回当前域宽返回当前域宽inline int ios:width(

36、int ); /把参数作为新的域宽把参数作为新的域宽,返回原域宽返回原域宽inline char ios:fill() const; /返回当前填充字符返回当前填充字符inline char ios:fill(char );/参数为新填充字符参数为新填充字符,返回原填充字符返回原填充字符inline int ios:precision(int ); /参数作为新精度参数作为新精度,返回原精度返回原精度inline int ios:precision() const; /返回当前精度返回当前精度9.2 输入输出的格式控制(选读)输入输出的格式控制(选读)【例【例9.1】整型数输出。】整型数输出。

37、#includeusing namespace std;int main(void)int inum=255;cout十进制方式十进制方式inumt;cout.flags(ios:oct|ios:showbase); /八进制带数制基输出是前面加八进制带数制基输出是前面加0;对对vc+参数等效参数等效0 x00a0cout八进制方式八进制方式inumt;cout.setf(ios:hex,ios:basefield );/basefield代表控制代表控制 /进位基制的三位进位基制的三位ios:dec|ios:oct|ios:hex。 /因是或关系因是或关系,仍带基输出仍带基输出,格式为格式为

38、0 x.cout十六进制方式十六进制方式inumendl;return 0;程序输出:程序输出:十进制方式十进制方式255 八进制方式八进制方式0377 十六进制方式十六进制方式0 xff9.2 输入输出的格式控制(选读)输入输出的格式控制(选读)【例【例9.2】浮点数输出。】浮点数输出。int main()double fnum=31.415926535;cout默认域宽为默认域宽为:cout.width()位位n; cout默认精度为默认精度为:cout.precision()位位n; cout默认表达方式默认表达方式:fnumn; /按值大小按值大小,自动决定定点还是科学数方式自动决定定

39、点还是科学数方式cout.setf(ios:scientific,ios:floatfield); cout科学数表达方式科学数表达方式:fnumn;cout.setf(ios:fixed,ios:floatfield); /设为定点设为定点,取消科学数方式取消科学数方式cout定点表达方式定点表达方式:fnumn;cout.precision(9); /精度精度9位指小数点后位指小数点后9位位cout.setf(ios:scientific,ios:floatfield); cout 9位科学数表达方式位科学数表达方式fnumn;return 0;其中其中floatfield代表浮点数的两控

40、代表浮点数的两控制位制位ios:scientific|ios:fixed为了避免浮点数互相冲突的双为了避免浮点数互相冲突的双重规定,所以先重规定,所以先清除原浮点数清除原浮点数两个输出控制位两个输出控制位,再用新的一,再用新的一位去代替位去代替。9.2 输入输出的格式控制(选读)输入输出的格式控制(选读)流操作子(流操作子(setiosflags stream manipulator)可代替流格式)可代替流格式控制成员函数。控制成员函数。它们的使用格式如第一章所介绍的它们的使用格式如第一章所介绍的setw()等使等使用的格式。注意,绝大多数流操作子仅适用于新的用的格式。注意,绝大多数流操作子仅

41、适用于新的c+标准流标准流类库(头文件不带类库(头文件不带.h)。)。操作符操作符含义含义boolapha把把true和和false表示为字符串表示为字符串*noboolalpha把把true和和false表示为表示为0、1showbase产生前缀,指示数值的进制基数产生前缀,指示数值的进制基数*noshowbase不产生进制基数前缀不产生进制基数前缀showpoint总是显示小数点总是显示小数点*noshowpoint只有当小数部分存在是才显示小数点只有当小数部分存在是才显示小数点操作符操作符含义含义showpos在非负数值中显示在非负数值中显示+*noshowpos在非负数值中不显示在非负

42、数值中不显示+*skipws输入操作符跳过空白字符输入操作符跳过空白字符noskipws输入操作符不跳过空白字符输入操作符不跳过空白字符uppercase在十六进制下显示在十六进制下显示0x,科学计数法中显示,科学计数法中显示e*nouppercase在十六进制下显示在十六进制下显示0 x,科学计数法中显示,科学计数法中显示e*dec以十进制显示以十进制显示(vc支持支持)hex以十六进制显示以十六进制显示(vc支持支持)oct以八进制显示以八进制显示(vc支持支持)left将填充字符加到数值的右边将填充字符加到数值的右边right将填充字符加到数值的左边将填充字符加到数值的左边interna

43、l将填充字符加到符号和数值的中间将填充字符加到符号和数值的中间*fixed以小数形式显示浮点数以小数形式显示浮点数scientific以科学计数法形式显示浮点数以科学计数法形式显示浮点数flush 刷新刷新ostream缓冲区缓冲区(vc支持支持)操作符操作符含义含义ends插入字符串结束符,刷新插入字符串结束符,刷新ostream缓冲区缓冲区(vc支持支持)endl 插入换行符,然后刷新插入换行符,然后刷新ostream缓冲区缓冲区(vc支持支持)ws“吃掉吃掉”空白字符空白字符(vc支持支持)/以下这些参数化的流操作子要求以下这些参数化的流操作子要求#includesetfill(ch)用

44、用ch填充空白字符填充空白字符(vc支持支持)setprecision(n)将浮点精度设置为将浮点精度设置为n (vc支持支持)setw(n) 按照按照n个字符来读或者写个字符来读或者写(vc支持支持)setbase(b)以进制基数以进制基数b为输出整数值为输出整数值(vc支持支持)注:注:*表示默认的流状态表示默认的流状态cin,cout和和clog都是都是缓冲流缓冲流。对输出而言,仅当输出缓冲区满。对输出而言,仅当输出缓冲区满才将缓冲区中的信息输出,对输入而言,才将缓冲区中的信息输出,对输入而言,仅当输入一行结束,仅当输入一行结束,才开始从缓冲区中取数据才开始从缓冲区中取数据,当希望把缓冲

45、区中的信息立即输出,当希望把缓冲区中的信息立即输出,可用可用flush,加,加endl也有同样功能,回车并立即显示,不必等缓也有同样功能,回车并立即显示,不必等缓冲区满(冲区满(endl清空缓冲区)。清空缓冲区)。 9.2 输入输出的格式控制(选读)输入输出的格式控制(选读)【例【例9.2_1】采用流操作子的浮点数输出。】采用流操作子的浮点数输出。#include#includeusing namespace std;int main() double fnum=31.415926535; cout默认域宽为默认域宽为:cout.width()位位n; cout默认精度为默认精度为:cout.

46、precision()位位n; cout默认表达方式默认表达方式:fnumn; /按值大小按值大小,自动决定定点还是科学数方式自动决定定点还是科学数方式 cout科学数表达方式科学数表达方式:scientificfnumn; /设为科学数方式设为科学数方式 cout定点表达方式定点表达方式:fixedfnumn; /设为定点设为定点,取消科学数方式取消科学数方式 cout9位科学数表达方式位科学数表达方式setprecision(9)scientificfnumn; return 0;读取状态的有关操作如下:读取状态的有关操作如下:inline int ios:rdstate() const

47、return state; /读取状态字读取状态字inline int ios:operator!() constreturn state&(badbit|failbit); /可用操作符可用操作符!()代替代替fail()inline int ios:bad() return state & badbit; /返回非法操作位返回非法操作位inline void ios:clear(int _i) lock();state=_i;unlock(); /人工设置状态人工设置状态,可用来清状态可用来清状态inline int ios:eof() const return state&eofbit;

48、 /返回流返回流(文件文件)结束位结束位inline int ios:fail() constreturn state&(badbit|failbit); /返回操作非法和操作失败这两位返回操作非法和操作失败这两位inline int ios:good() constreturn state=0; /正常返回正常返回1,否则返回否则返回09.3.1 9.3.1 提高标准输入提高标准输入/ /输出的稳健性输出的稳健性【例【例9.3】提高输入的稳健性。】提高输入的稳健性。int main() char str256; int i; cout请输入整数请输入整数:i;/可故意输入若干非数字字符可故意

49、输入若干非数字字符,下次再输入若干字符加数字串下次再输入若干字符加数字串 /加若干非数字字符进行检测加若干非数字字符进行检测 while(cin.fail() cout状态字为:状态字为:cin.rdstate()endl; cin.clear(0); cin.getline(str,255); /读空缓冲区读空缓冲区 cout输入错误输入错误,请重新输入整数请重新输入整数i; cin.getline(str,256); /读空缓冲区读空缓冲区,吃掉回车符吃掉回车符 cout请输入字符串请输入字符串endl; cin.getline(str,255); cout输入整数为输入整数为:iendl

50、; cout输入字符串为输入字符串为:strendl; return 0;9.3.2 9.3.2 标准输入标准输入/输出成员函数(选读)输出成员函数(选读)【例【例9.4】ignore()和和gcount()函数使用。函数使用。int main() char str255; int i,n; cout输入字符输入字符endl; /输入输入z,一旦输入一旦输入z全部结束,不能输入其它字符全部结束,不能输入其它字符 i=cin.get(); coutendl; n=cin.rdstate(); /读取状态字读取状态字 cout状态字为:状态字为:nendl; /状态字为状态字为1,流结束流结束 c

51、out当输入字符时当输入字符时,取得的是取得的是:iendl; /-1,输入输入z时时,返回返回eof,即即-1 if(n=0) cin.ignore(255,n); /清除多余的字符和回车符清除多余的字符和回车符 cin.clear(0); / a 使流恢复正常使流恢复正常 cout输入字符串输入字符串1:endl; cin.getline(str,255); coutendl;9.3.2 9.3.2 标准输入标准输入/输出成员函数(选读)输出成员函数(选读) cout状态字为:状态字为:cin.rdstate()endl; i=cin.gcount(); cout字符串为字符串为:strt

52、读入字符数为读入字符数为:it; cout串长为串长为:strlen(str)endl; cin.clear(0); / a 使流恢复正常使流恢复正常 cout输入字符串输入字符串2:endl; cin.getline(str,255); coutendl; cout状态字为:状态字为:cin.rdstate()endl; i=cin.gcount(); cout字符串为字符串为:strt读入字符数为读入字符数为:it; cout串长为串长为:strlen(str)endl; return 0;注意注意,若无两个,若无两个a行,输入行,输入z后,不再理会余下的所有输入。后,不再理会余下的所有输

53、入。9.3.3 9.3.3 重载插入和提取运算符重载插入和提取运算符【例【例9.5】改进自定义字符串类,重载插入运算符改进自定义字符串类,重载插入运算符“”:重载插入运算符重载插入运算符“”声明为声明为mystring的友元:的友元:friend ostream & operator(ostream & ,const mystring &); /流类作为形式参数必须是引用流类作为形式参数必须是引用定义为:定义为:ostream & operator(ostream & s,const mystring & cstr) return scstr.strt;本例中线性表本例中线性表orderedl

54、ist的元素的元素node的数据域的数据域key类型由模板参数类型由模板参数t决定,实例化后为决定,实例化后为mystring,打印函数为:,打印函数为:template void orderedlist:print() int i; for(i=0;i=last;i+)coutslisti.key;if(i%5=4) coutendl; coutendl;更重要的是不用更重要的是不用show()函数,格式一致了,可以同时用于基本数据类函数,格式一致了,可以同时用于基本数据类型,如整型、实型、字符型,也可用于标准字符串型,如整型、实型、字符型,也可用于标准字符串string。【例【例9.6】用

55、户定义的复数类型用户定义的复数类型complex的输入与输出。的输入与输出。#includeusing namespace std;class complex double real,image;public: complex(double r=0.0, double i=0.0):real(r),image(i) /这里省略若干成员函数这里省略若干成员函数,以节约篇幅以节约篇幅,详见【例详见【例4.7】 friend ostream&operator(istream&s,complex&a); /流类作为形式参数必须是引用流类作为形式参数必须是引用;ostream&operator(ostr

56、eam&s,const complex &z) return s(z.real,z.image(istream&s,complex &a) /格式为格式为d,(d),(d,d) double re=0,im=0; char c=0; sc; if(c=()/是否由括号开始是否由括号开始 srec; /实部实部 if(c=,) simc; /虚部虚部 if(c!=) s.clear(ios:failbit); /漏了括号给一个操作失败标志漏了括号给一个操作失败标志 else s.putback(c); /无括号,返回一个字符到输入缓冲区无括号,返回一个字符到输入缓冲区 sre; /实数实数 if

57、(s) a=complex(re,im); /当流当流s正常,给正常,给a赋值赋值 return s;9.3.3 9.3.3 重载插入和提取运算符重载插入和提取运算符putback()声明如下:声明如下:stream&istream:putback(char);它将最后一次从输入流中得到的字它将最后一次从输入流中得到的字符放回到输入流中符放回到输入流中。int main()complex a,b,c;cout输入一个实数输入一个实数a;cout输入一个用括号括起来的实数输入一个用括号括起来的实数b;cout输入一个用括号括起来复数输入一个用括号括起来复数c;couta=atb=bt c=cn;

58、return 0;9.3 9.3 标准设备的输入标准设备的输入/ /输出输出9.4.2 文本文件的读写文本文件的读写【例【例9.7】复制文件。】复制文件。 int main() char ch; ifstream sfile(d:ex9_6ex9_6.cpp); ofstream dfile(e:ex9_6.cpp); /只能创建文件,不能建立子目录,如路径不存在则失败只能创建文件,不能建立子目录,如路径不存在则失败 if(!sfile) cout不能打开源文件不能打开源文件:d:ex9_6ex9_6.cppendl; return -1; if(!dfile) cout不能打开目标文件不能打

59、开目标文件:e:ex9_6.cppch)dfile”)运算符在)运算符在默认情况下是跳过默认情况下是跳过空白空白字符的,这样复制的文件会缺少一些字符的,这样复制的文件会缺少一些字符。字符。第二第二,该程序能确定文件是否,该程序能确定文件是否复制结束复制结束。流类成员函数和运。流类成员函数和运算符全是返回本类型的引用,这里就是流文件对象自身,当算符全是返回本类型的引用,这里就是流文件对象自身,当文件结束时,返回文件结束时,返回nullnull,这时不再复制,退出循环。,这时不再复制,退出循环。第三第三,复制是,复制是按字节进行按字节进行的,效率很低,按字节传递开销极的,效率很低,按字节传递开销极

60、大,但该程序能正确复制任意类型的文件,不仅是文本文件大,但该程序能正确复制任意类型的文件,不仅是文本文件(看作按字符),二进制文件(看作按字节)也一样可正确(看作按字符),二进制文件(看作按字节)也一样可正确完成。如果是文本文件,我们可以按行进行复制。完成。如果是文本文件,我们可以按行进行复制。第四第四,!sfile!sfile中的!是重载的运算符,在状态函数中重载,中的!是重载的运算符,在状态函数中重载,当该操作出现不正常状态,返回当该操作出现不正常状态,返回操作非法和操作失败这两位操作非法和操作失败这两位 。【例【例9.8】按行复制文本文件】按行复制文本文件。int main() char

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论