第11章流类库和输入_第1页
第11章流类库和输入_第2页
第11章流类库和输入_第3页
第11章流类库和输入_第4页
第11章流类库和输入_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

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

2、责在数据的产生者和数据流是一种抽象的概念,负责在数据的产生者和数据的使用者之间建立联系,并管理数据的流动。的使用者之间建立联系,并管理数据的流动。 第九章第九章 流类库和输入流类库和输入/ /输出输出9.1 C+的基本流类体系的基本流类体系 9.3 标准设备的输入标准设备的输入/输出输出 9.2 输入输出的格式控制输入输出的格式控制 9.4 文件的输入与输出文件的输入与输出 9.6 MFC中的文件处理中的文件处理 9.5 字符串流(内存流)字符串流(内存流) 9.1 C+的基本流类体系的基本流类体系整个流类体系是一个派生类体系。整个流类体系在头文件整个流类体系是一个派生类体系。整个流类体系在头

3、文件中说明,它包含了中说明,它包含了、和和。而输入输出文件流部分在。而输入输出文件流部分在中说明,它包含中说明,它包含。 图图9.1 输入输入/输出流类派生体系输出流类派生体系iosstreambufistreamostreamistream_withassigniostreamostream_withassigniostream_withassign指针指针9.1 C+的基本流类体系的基本流类体系iosistreamifstrstreamistream_withassignifstreamstreambuffilebufstrstreambufstdiobufiostream_initios

4、treamfstreamstrstreamstdiostreamostreamofstreamostream_withassign ostrstream9.1 C+的基本流类体系的基本流类体系在流类库中,最重要的两部分功能为标准输在流类库中,最重要的两部分功能为标准输入入/ /输出(输出(standard input/outputstandard input/output)和文件处)和文件处理。在理。在C+C+的流类库中定义了四个全局流对象:的流类库中定义了四个全局流对象:cincin,coutcout,cerrcerr和和clogclog。使用这四个流对象,。使用这四个流对象,可以完成人机交

5、互的功能。要使用这四个功能,可以完成人机交互的功能。要使用这四个功能,必须包含必须包含文件。文件。 文件处理完成永久保存的功能。在文件处理完成永久保存的功能。在VC+VC+的的MFCMFC编程中采用了序列化(编程中采用了序列化(SerializationSerialization)。)。 9.2 输入输出的格式控制输入输出的格式控制C+在类在类ios中提供格式化输入输出。格式控制符定义为公有的无名的枚举类型:中提供格式化输入输出。格式控制符定义为公有的无名的枚举类型:enum skipws=0 x0001/跳过输入中的空格字符跳过输入中的空格字符left=0 x0002/输出左对齐输出左对齐r

6、ight=0 x0004/输出右对齐输出右对齐internal=0 x0008/在输出符号或数制字符后填充在输出符号或数制字符后填充dec=0 x0010/在输入输出时将数据按十进制处理在输入输出时将数据按十进制处理oct=0 x0020/在输入输出时将数据按八进制处理在输入输出时将数据按八进制处理hex=0 x0040/在输入输出时将数据按十六进制处理在输入输出时将数据按十六进制处理showbase=0 x0080/在输出时带有表示数制基的字符在输出时带有表示数制基的字符showpoint=0 x0100/输出符点数时输出符点数时,必定带小数点必定带小数点uppercase=0 x0200/

7、输出十六进制输出十六进制,用大写用大写showpos=0 x0400/输出正数时输出正数时,加加”+”号号scientific=0 x0800/科学数方式输出浮点数科学数方式输出浮点数fixed=0 x1000/定点数方式输出实数定点数方式输出实数unitbuf=0 x2000/插入后插入后,立即刷新流立即刷新流stdio=0 x4000/插入后插入后,立即刷新立即刷新stdout和和stderr 9.2 输入输出的格式控制输入输出的格式控制采用格式控制,只要把对应位置采用格式控制,只要把对应位置1即可,取多种控制时,用或即可,取多种控制时,用或“|”运算符来运算符来合成。合成。【例【例9.1

8、】整型数输出。】整型数输出。#include void main(void)int inum=255;cout”十进制方式十进制方式”inumt;cout.flags(ios:oct|ios:showbase);cout”八进制方式八进制方式”inumt;cout.setf(ios:hex);cout”十六进制方式十六进制方式”inumendl;程序执行后输出:十进制方式程序执行后输出:十进制方式255 八进制方式八进制方式0377 十六进制方式十六进制方式0 xff 9.2 输入输出的格式控制输入输出的格式控制【例【例9.2】浮点数输出。】浮点数输出。#include void main()

9、double fnum=31.415926535;cout”缺省域宽为缺省域宽为:”cout.width()”位位”n; cout”缺省精度为缺省精度为:”cout.precision()”位位”n;cout”缺省表达方式缺省表达方式:”funmn; cout.setf(ios:scientific,ios:floatfield);cout”科学数表达方式科学数表达方式:”fnumn;cout.setf(ios:fixed,ios:floatfield); cout”定点表达方式定点表达方式:”fnumn;cout.precision(9); cout.setf(ios:scientific,

10、ios:floatfield); cout”定点定点9位科学数表达方式位科学数表达方式:”fnumendl;9.2 输入输出的格式控制输入输出的格式控制其中其中floatfield,是为了避免浮点数互相冲突的双重规定,所以是,是为了避免浮点数互相冲突的双重规定,所以是清除原浮点数第清除原浮点数第13和第和第14两位,再用新的一位去代替。程序执行两位,再用新的一位去代替。程序执行后输出:后输出:缺省域宽为缺省域宽为:0位位缺省精度为缺省精度为:6位位缺省表达方式缺省表达方式:31.4159科学数表达方式科学数表达方式:3.141593e+001定点表达方式定点表达方式:31.415927定点定点

11、9位科学数表达方式位科学数表达方式:3.141592654e+001 9.2 输入输出的格式控制输入输出的格式控制cin,coutcin,cout和和clogclog都是缓冲流。输出而言,都是缓冲流。输出而言,仅当输出缓冲区满才将缓冲区中的信息输出,仅当输出缓冲区满才将缓冲区中的信息输出,对输入而言,仅当输入一行结束,才开始从对输入而言,仅当输入一行结束,才开始从缓冲区中取数据,当希望把缓冲区中的信息缓冲区中取数据,当希望把缓冲区中的信息立即输出,可用立即输出,可用flushflush, 9.3 标准设备的输入标准设备的输入/ /输出输出标准设备输入不安全,健壮性差,错误的输入类标准设备输入不

12、安全,健壮性差,错误的输入类型导致错误的结果而且是无法预知的错误结果。注意型导致错误的结果而且是无法预知的错误结果。注意以下几点。以下几点。1cin为缓冲流。为缓冲流。不可能用刷新来清除缓冲区不可能用刷新来清除缓冲区,不不能输错,也不能多输!能输错,也不能多输! 2.输入数据类型必须与对应要提取的数据类型一致,输入数据类型必须与对应要提取的数据类型一致,否则出错。在编程中加入对状态字否则出错。在编程中加入对状态字state的判断的判断,可以提高输入的健壮性。可以提高输入的健壮性。 3.空格和回车都可以作为数据之间的分格符,但如空格和回车都可以作为数据之间的分格符,但如果是字符型和字符串,则空格

13、。回车符无法读入。果是字符型和字符串,则空格。回车符无法读入。 9.3 标准设备的输入标准设备的输入/ /输出输出enum ios_stategoodbit=0 x00; /流正常流正常eofbit=0 x01; /输入流结束输入流结束,忽略后继提取操忽略后继提取操 作;或文件结束,已无数据可取作;或文件结束,已无数据可取failbit=0 x02; /最近的最近的I/O操作失败操作失败,流可恢复流可恢复badbit=0 x04; /最近的最近的I/O操作非法操作非法,流可恢复流可恢复hardfail=0 x08; /I/O出现致命错误出现致命错误,流不可恢流不可恢 复复,VC+6.0不支持不

14、支持 9.3 标准设备的输入标准设备的输入/ /输出输出读取状态有关操作如下:读取状态有关操作如下:inline int ios:rdstate() const 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();sta

15、te=_i;unlock(); /人工设置状态人工设置状态,可用来清状态可用来清状态inline int ios:eof() const return state&eofbit; /返回流返回流(文件文件)结束位结束位inline int ios:fail() constreturn state&(badbit|failbit); /返回操作失败返回操作失败,流可恢复这两位流可恢复这两位inline int ios:good() constreturn state=0; /正常返回正常返回1,否则返回否则返回09.3 标准设备的输入标准设备的输入/ /输出输出【例【例9.3】提

16、高输入的健壮性。输入时需要故意输错,以】提高输入的健壮性。输入时需要故意输错,以测试健壮性。测试健壮性。程序:程序:x9_3.cpp9.3 标准设备的输入标准设备的输入/ /输出输出输入流成员函数声明:输入流成员函数声明:istream&istream:get(char &);/提取一个字符提取一个字符,放在字符型变量中放在字符型变量中istream&istream:get(unsigned char &);/同上一函数同上一函数istream&istream:get(signed char &);/同上一函数同上一函数istream&i

17、stream:get(char *,int,char=n);/提取字符串提取字符串,到串结束到串结束 符或指定长度为止符或指定长度为止istream&istream:get(unsigned char *,int,char=n); /同上同上istream&istream:get(signed char *,int,char=n); /同上同上istream&istream:getline(char *,int,char=n);/同上同上,但包括分隔符但包括分隔符istream&istream:getline(unsigned char *,int,char=n

18、);/同上同上istream&istream:getline(signed char *,int,char=n);/同上同上 9.3 标准设备的输入标准设备的输入/ /输出输出【例【例9.4】ignore()和和gcount()函数使用。函数使用。(运行两种情况下的输出运行两种情况下的输出)类类ostream串中输出字符的成员函数有:串中输出字符的成员函数有:ostream&ostream:put(char);/输出参数字符输出参数字符ostream&ostream:put(unsigned char);ostream&ostream:put(signed ch

19、ar);ostream&ostream:flush();/刷新一个输出流刷新一个输出流,用于用于count和和clog 9.4 文件的输入与输出文件的输入与输出 本节中文件指的是磁盘文件。本节中文件指的是磁盘文件。C+根据文件(根据文件(file)内容的数)内容的数据格式,可分为两类:二进制文件和文本文件。文本文件由字符据格式,可分为两类:二进制文件和文本文件。文本文件由字符序列组成,也称序列组成,也称ASCII码文件,在文本文件中存取的最小信息单码文件,在文本文件中存取的最小信息单位为字符(位为字符(character),而二进制文件中存取的最小信息单位为),而二进制文件中存取的最小

20、信息单位为字节(字节(Byte)。)。 使用文件的方法是固定的,首先打开一个文件,使磁盘文件使用文件的方法是固定的,首先打开一个文件,使磁盘文件和文件流对象建立联系,然后将某种格式的数据写入一个文件,和文件流对象建立联系,然后将某种格式的数据写入一个文件,以后可按同样格式从这个文件读出数据。最后当不再使用文件时,以后可按同样格式从这个文件读出数据。最后当不再使用文件时,要关闭文件,这时文件才能从缓冲区中完全写回磁盘。类要关闭文件,这时文件才能从缓冲区中完全写回磁盘。类ifstream支持从输入文件中提取数据的操作。而类支持从输入文件中提取数据的操作。而类ofstream完成完成数据写入文件中的

21、各种操作。数据写入文件中的各种操作。 9.4 文件的输入与输出文件的输入与输出9.4.1 文件的打开与关闭文件的打开与关闭 9.4.2 文件的读写文件的读写 9.4.1 文件的打开与关闭文件的打开与关闭文件的使用步骤如下:文件的使用步骤如下:1说明一个文件流对象。说明一个文件流对象。如果只输入用如果只输入用ifstream的对的对象,只输出用象,只输出用ofstream的对象,既输入又输出用的对象,既输入又输出用iofstream的对象。的对象。ifstream ifile;ofstream ofile;fstream iofile;这又被称为内部文件。这又被称为内部文件。9.4.1 文件的打

22、开与关闭文件的打开与关闭 2使用文件流对象的成员函数打开一个磁盘文件。使用文件流对象的成员函数打开一个磁盘文件。这样在这样在文件流对象和磁盘文件名之间建立联系。文件流中说明了三个文件流对象和磁盘文件名之间建立联系。文件流中说明了三个打开文件的成员函数。打开文件的成员函数。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*,in

23、t,int=filebuf:openprot); 9.4.1 文件的打开与关闭文件的打开与关闭三个文件流类都重载了一个带缺省参数的构造函数,与三个文件流类都重载了一个带缺省参数的构造函数,与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

24、两步可合成:两步可合成:fstream iofile(”myfile.txt”,ios:in|ios:out);如同动态分配内存一样,打开文件也应该判断是否成功,若打开成功,文件如同动态分配内存一样,打开文件也应该判断是否成功,若打开成功,文件流对象值为非零值,不成功为流对象值为非零值,不成功为0(NULL),文件流对象值物理上就是指它的地址。),文件流对象值物理上就是指它的地址。因此打开一个文件完整的程序为:因此打开一个文件完整的程序为:fstream iofile(”myfile.txt”,ios:in|ios:out);if(!iofile) cout”不能打开文件不能打开文件:”myf

25、ile,txt”)和插入运算符(和插入运算符()进行。)进行。【例【例9.7】复制文件。】复制文件。 程序:程序:Ex9_7.cpp9.4.2 文件的读写文件的读写【例【例9.8】按行进行复制文本文件。】按行进行复制文本文件。 程序:程序:Ex9_8.cpp9.4.2 文件的读写文件的读写【例【例9.9】文本式数据文件的创建与读取数据。】文本式数据文件的创建与读取数据。 程序:程序:Ex9_9.cpp本例是典型的本例是典型的C+数据存入文件和由文件获得数据的方法,按面向对数据存入文件和由文件获得数据的方法,按面向对象的说法为把象的说法为把对象存入文件和由文件重构对象。对象存入文件和由文件重构对

26、象。 对二进制文件的读写,对二进制文件的读写,C+也提供了成员函数来实现:也提供了成员函数来实现:istream&istream:read(char *,int);/从二进制流提取从二进制流提取istream&istream:read(unsigned char*,int);istream&istream:read(signed char *,int); ostream&ostream:write(const char *,int);/向二进制流插入向二进制流插入ostream&ostream:write(const unsigned char *,in

27、t);ostream&ostream:write(const signed char *,int); 读函数并不能知道文件是否结束,可用状态函数读函数并不能知道文件是否结束,可用状态函数int ios:eof()来判断。来判断。 9.4.2 文件的读写文件的读写【例【例9.10】创建二进制数据文件,以及数据文件的读取。】创建二进制数据文件,以及数据文件的读取。按按C+程序设计惯例,将该操作设计为成员函数。为与程序设计惯例,将该操作设计为成员函数。为与【例【例9.9】对比,采用同名的类,并有同样的数据成员。】对比,采用同名的类,并有同样的数据成员。 程序:程序:Ex9_10.cpp使用二

28、进制文件,可以控制字节长度,读写数据不会使用二进制文件,可以控制字节长度,读写数据不会出现二义性,可靠性高。同时不知格式是无法读取的,保出现二义性,可靠性高。同时不知格式是无法读取的,保密性好。密性好。 9.4.2 文件的读写文件的读写C+把每一个文件都看成一个有序的字节流,见把每一个文件都看成一个有序的字节流,见图图9.3.每一个文件或者以文件结束符(每一个文件或者以文件结束符(end of file marker)结束,或者在特定的字节号处结束。)结束,或者在特定的字节号处结束。 012436578n-1文件结束符文件结束符图图9-3 C+把文件看作有序的把文件看作有序的n个字节的流个字节

29、的流9.4.2 文件的读写文件的读写当打开一个文件时,该文件就和某个流关联起来了。当打开一个文件时,该文件就和某个流关联起来了。对文件进行读写实际上受到一个文件定位指针(对文件进行读写实际上受到一个文件定位指针(file position pointer)的控制,输入流的指针也称为读指针,)的控制,输入流的指针也称为读指针,每一次提取操作将从读指针当前所指位置开始,每次提取每一次提取操作将从读指针当前所指位置开始,每次提取操作自动将读指针向文件尾移动。输出流指针也称写指针,操作自动将读指针向文件尾移动。输出流指针也称写指针,每一次插入操作将从写指针当前位置开始,每次插入操作每一次插入操作将从写

30、指针当前位置开始,每次插入操作自动将写指针向文件尾移动。自动将写指针向文件尾移动。在在C+中可以由程序移动文件指针,从而实现文件的中可以由程序移动文件指针,从而实现文件的随机访问,即可读写流中任意一段内容。一般文本文件很随机访问,即可读写流中任意一段内容。一般文本文件很难准确定位,所以随机访问多用于二进制文件。难准确定位,所以随机访问多用于二进制文件。 9.4.2 文件的读写文件的读写在在ios类中说明了一个公有枚举类型:类中说明了一个公有枚举类型:enum seek_dirbeg=0;/文件开头文件开头cur=1;/文件指针的当前位置文件指针的当前位置end=2;/文件结尾文件结尾;istr

31、eam类中提供了三个成员函数类中提供了三个成员函数istream&istream:seekg(streampos);/指针直接定位指针直接定位istream&istream:seekg(streamoff, ios:seek_dir);/指针相对定位指针相对定位long istream:tellg();/返回当前指针位置返回当前指针位置流的指针位置类型流的指针位置类型streampos和流的指针偏移类型和流的指针偏移类型streamoff定义为长整定义为长整型,型, 9.4.2 文件的读写文件的读写datafile.seekg(-20L,ios:cur);表示将文件定位指针从当

32、前位置向文件头部方向移表示将文件定位指针从当前位置向文件头部方向移20个字节。个字节。datafile.seekg(20L,ios:beg);表示将文件定位指针从文件头向文件尾方向移表示将文件定位指针从文件头向文件尾方向移20个字节。个字节。datafile.seekg(-20L,ios:end);表示将文件定位指针从文件尾向文件头方向移表示将文件定位指针从文件尾向文件头方向移20个字节。个字节。tellg()和和seekg()往往配合使用,按【例往往配合使用,按【例9.10】中的定义和程序】中的定义和程序long pos=sdatafile.tellg();car2.Bdatafromfil

33、e(sdatafile);sdatafile:seekg(pos);motor2.Bdatafromfile(sdatafile);这时这时car2和和motor2中放的都是中放的都是car1的数据。的数据。 9.4.2 文件的读写文件的读写ostream类也提供了三个成员函数管理文件定位指针ostream&ostream:seekp(streampos);ostream&ostream:seekp(streamoff,ios:seek_dir);long ostream:tellp(); 9.4.2 文件的读写文件的读写【例【例9.11】使用随机访问对【例】使用随机访问对【例

34、9.10】进行改造。将入】进行改造。将入口(口(main())程序中的文件改为输入输出文件,写完后)程序中的文件改为输入输出文件,写完后将文件定位指针拨回文件开始处。对应商品类中两成员函将文件定位指针拨回文件开始处。对应商品类中两成员函数:数: Bdatatofile(fstream&dist);Bdatafromfile(fstream&dist);参数类型也已改为参数类型也已改为 fsream&。 9.5 字符串流(内存流)字符串流(内存流)可以把流的概念连接到字符串(可以把流的概念连接到字符串(string)上。文件在)上。文件在C+看来看来是字节流或字符流,串当

35、然更可以看作字符流。可以用输入输出操是字节流或字符流,串当然更可以看作字符流。可以用输入输出操作来完成串流的操作。其他的流是与设备相关,而串流是与内存相作来完成串流的操作。其他的流是与设备相关,而串流是与内存相关,所以也称内存流。串流类包括关,所以也称内存流。串流类包括ostrstream、istrstream、strstream。参见图。参见图9.2。它们在。它们在中说明。串流类中说明。串流类对象可以保存字符,也可以保存整数、浮点数。串流类对象采用文对象可以保存字符,也可以保存整数、浮点数。串流类对象采用文本方式,如同文本文件一样。其构造函数常用下面几个:本方式,如同文本文件一样。其构造函数

36、常用下面几个:istrstream:istrstream(const char * str);istrstream:istrstream(const char * str,int);ostrstream:ostrstream(char *,int,int=ios:out); 9.5 字符串流(内存流)字符串流(内存流)以串流为信息源:以串流为信息源:char str36=”This is a book.n”;char ch;istrstream input(str);inputch;/从输入设备从输入设备(串串)读入一个字符读入一个字符coutchendl;/输出输出T9.5 字符串流(内存流)字符串流(内存流)将整数和浮点数放入串中,并取出来将整数和浮点数放入串中,并取出来int inum1=93,inum2;double fnu

温馨提示

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

评论

0/150

提交评论