第13章C++流和文件流_第1页
第13章C++流和文件流_第2页
第13章C++流和文件流_第3页
第13章C++流和文件流_第4页
第13章C++流和文件流_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

1、第第1313章章 C+C+流和文件流流和文件流 C+语言中没有专门的输入语言中没有专门的输入/输出(输出(I/O)语句,)语句,C+中的中的I/O操作是通过一组标准操作是通过一组标准I/O函数和函数和I/O流流来实现的。来实现的。 C+的标准的标准I/O函数是从函数是从C语言继承而来的,语言继承而来的,同时对同时对C语言的标准语言的标准I/O函数进行了扩充。函数进行了扩充。 C+的的I/O流不仅拥有标准流不仅拥有标准I/O函数的功能,而函数的功能,而且比且比I/O函数更方便、更可靠。函数更方便、更可靠。13.1 什么是流什么是流 C+中把数据之间的传输操作称作流。在中把数据之间的传输操作称作流

2、。在C+中,中,流既可以表示数据从内存传送到某个载体或设备中,流既可以表示数据从内存传送到某个载体或设备中,即输出流;也可以表示数据从某个载体或设备传送即输出流;也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。到内存缓冲区变量中,即输入流。 在进行在进行I/O操作时,操作步骤如下:操作时,操作步骤如下: (1)打开操作,使流和文件发生联系,建立联)打开操作,使流和文件发生联系,建立联系后的文件才允许数据流入或流出;系后的文件才允许数据流入或流出; (2)输入或输出操作;)输入或输出操作; (3)结束后,使用关闭操作使文件与流断开联)结束后,使用关闭操作使文件与流断开联系。系。

3、C+中所有流都是相同的,但操作的文件可以不中所有流都是相同的,但操作的文件可以不同。同。 使用流以后,程序用流统一对各种计算机设备和使用流以后,程序用流统一对各种计算机设备和文件进行操作,使程序与设备、程序与文件无关,从文件进行操作,使程序与设备、程序与文件无关,从而提高了程序设计的通用性和灵活性。而提高了程序设计的通用性和灵活性。 也就是说,无论与流相联系的实际物理设备差别也就是说,无论与流相联系的实际物理设备差别有多大,流都采用相同的方式运行。有多大,流都采用相同的方式运行。 这种机制使得流可以跨越物理设备平台,实现流这种机制使得流可以跨越物理设备平台,实现流的透明运作,而与实际的物理设备

4、无关。例如,往显的透明运作,而与实际的物理设备无关。例如,往显示器上输出字符和向磁盘文件或打印机输出字符,尽示器上输出字符和向磁盘文件或打印机输出字符,尽管接收输出的物理设备不同,但具体操作过程是相同管接收输出的物理设备不同,但具体操作过程是相同的。的。13.1.1 预定义流预定义流 在程序开始运行时,在程序开始运行时,C+会自动打开会自动打开4个流,这个流,这些流是些流是C+流类库的预定义流,如下表所列。流类库的预定义流,如下表所列。流流含义含义所属类库所属类库默认设备默认设备cin标准输入标准输入iostream.h键盘键盘cout标准输出标准输出iostream.h显示器显示器cerr没

5、有被缓冲的没有被缓冲的标准错误输出标准错误输出iostream.h显示器显示器clog被缓冲了的标被缓冲了的标准错误输出准错误输出iostream.h显示器显示器 C+的流通过重载运算符的流通过重载运算符“”执行输出执行输出和输入操作。和输入操作。 输出操作是向流中插入一个字符序列,因此,在输出操作是向流中插入一个字符序列,因此,在流操作中,将运算符流操作中,将运算符“”称为称为提取运算符提取运算符。1cout cout是与标准输出设备连接的预定义输出流,是与标准输出设备连接的预定义输出流,称为汇。称为汇。C+的插入运算符的插入运算符“”向输出流发送字符。向输出流发送字符。实际上,位于插入运算

6、符右侧的字符串被存储在实际上,位于插入运算符右侧的字符串被存储在“”左侧的流中。例如:左侧的流中。例如: cout name number n; cout是数据的目的地,插入运算符是数据的目的地,插入运算符“”处流进程序。为了保留输入数据,输入语句处流进程序。为了保留输入数据,输入语句要求有目的地址,即指定数据类型的存储单元,例如:要求有目的地址,即指定数据类型的存储单元,例如: int i; cin i; 这段代码所进行的操作是:提取运算符这段代码所进行的操作是:提取运算符“”从从cin参数中提取一个整型输入数据,并存入一个对象参数中提取一个整型输入数据,并存入一个对象(变量),在此例中即为

7、整型数(变量),在此例中即为整型数i。 cin一般连接到标准输入设备即键盘(默认设一般连接到标准输入设备即键盘(默认设备)。备)。3cerr cerr类似标准错误文件。类似标准错误文件。cerr与与cout的差别在于:的差别在于: (1)cerr是不能重定向的;是不能重定向的; (2)cerr不能被缓冲,它的输出总是直接传送到不能被缓冲,它的输出总是直接传送到标准输出设备上。标准输出设备上。 错误信息是写到错误信息是写到cerr的项。即使在各种其他输出的项。即使在各种其他输出语句中,如果使用下列语句,则错误信息语句中,如果使用下列语句,则错误信息“Error”总能保证在显示器上显示出来:总能保

8、证在显示器上显示出来: cerr Error n;4clog clog是不能重定向的,但是可以被缓冲。在某些是不能重定向的,但是可以被缓冲。在某些系统中,由于缓冲,使用系统中,由于缓冲,使用clog代替代替cerr可以改进显示可以改进显示速度:速度: clog Error n;13.1.2 C+的流类库的流类库 C+提供了一个流类库,流类库由若干完成提供了一个流类库,流类库由若干完成I/O操作的基础类以及若干支持特定种类的源和目标的操作的基础类以及若干支持特定种类的源和目标的I/O操作类组成。操作类组成。 流类库的基础类利用继承关系组织起来,其类层流类库的基础类利用继承关系组织起来,其类层次如

9、下图所示,这些类的说明如表次如下图所示,这些类的说明如表13.2所列。所有所列。所有使用流类库的程序必须用使用流类库的程序必须用“#include”编译指令将编译指令将iostream.h包含进来。包含进来。 ios istream ostream istrstream istream _withassign ifstream iostream ofstream ostream _withassign ostrstream fstream strstream I/OI/O流类库的类层次流类库的类层次输入流类输入流类istream通用输入流类和其他输入流的基类通用输入流类和其他输入流的基类ios

10、tream.hifstream输入文件流类输入文件流类fstream.histream_withassigncin的输入流类的输入流类iostream.histrstream输入字符串流类输入字符串流类strstrea.h输出流类输出流类ostream通用输出流类和其他输出流的基类通用输出流类和其他输出流的基类iostream.hofstream输出文件流类输出文件流类fstream.hostream_withassigncout、cerr和和clog的输出流类的输出流类iostream.hostrstream输出字符串流类输出字符串流类strstrea.hI/O流类流类iostream通用通

11、用I/O流类和其他流类和其他I/O流的基类流的基类iostream.hfstreamI/O文件流类文件流类fstream.hstrstreamI/O字符串流类字符串流类strstrea.h13.2 13.2 格式化格式化I/OI/O 在以前的程序中,所有在以前的程序中,所有I/O采用的格式都是由采用的格式都是由C+流类库提供的默认方式。流类库提供的默认方式。 在实际应用中,常常需要准确控制数据(特别在实际应用中,常常需要准确控制数据(特别是整数、浮点数与字符串)的是整数、浮点数与字符串)的I/O格式。格式。 流类库可用两种方法控制数据的格式:使用流类库可用两种方法控制数据的格式:使用ios类的

12、成员函数和使用类的成员函数和使用I/O操纵符。操纵符。13.2.1 使用使用ios成员函数成员函数 每一个每一个C+流都有自己当前的数据格式控制状态,流都有自己当前的数据格式控制状态,这些状态用一个长整数表示,即这些状态用一个长整数表示,即ios类的数据成员类的数据成员x_flags,称为格式化标志字。,称为格式化标志字。 这些格式化标志字在这些格式化标志字在ios类中定义为公有的枚举量。类中定义为公有的枚举量。 在在iostream.h头文件中定义了以下枚举类型:头文件中定义了以下枚举类型:enum skipws = 0 x0001, /跳过输入中的空白跳过输入中的空白(空格、制表符、回车、

13、换行等空格、制表符、回车、换行等) left = 0 x0002, /输出左对齐输出左对齐 right = 0 x0004, /输出右对齐输出右对齐 internal = 0 x0008, /在符号或基位与数值之间补齐空格在符号或基位与数值之间补齐空格 dec = 0 x0010, /按十进制按十进制I/O oct = 0 x0020, /按八进制按八进制I/O hex = 0 x0040, /按十六进制按十六进制I/O showbase = 0 x0080, /输出数制的基输出数制的基 showpoint = 0 x0100, /强制浮点数输出小数点强制浮点数输出小数点 uppercase

14、= 0 x0200, /十六进制采用大写输出十六进制采用大写输出 showpos = 0 x0400, /在正数前加上在正数前加上“+” scientific = 0 x0800, /浮点数使用科学记数法浮点数使用科学记数法 fixed = 0 x1000, /浮点数使用普通记数法浮点数使用普通记数法 unitbuf = 0 x2000, /每次插入后刷新所有流每次插入后刷新所有流 stdio = 0 x4000 /每次插入后刷新标准输出和标准错误输出流每次插入后刷新标准输出和标准错误输出流;(1)setf() 成员函数成员函数setf()用于设置状态标志。例如,设置输用于设置状态标志。例如,

15、设置输出流出流cout的的showbase标志使用如下语句:标志使用如下语句: cout.setf(ios:showbase); 设置输入流设置输入流cin的的skipws标志使用如下语句:标志使用如下语句: cin.setf(ios:skipws); 注意:格式标志前的限定注意:格式标志前的限定“ios:”不可缺少,因不可缺少,因为这些标志是在为这些标志是在ios类中定义的。类中定义的。 在在setf()中还可用位或操作中还可用位或操作“|”将多个标志连在一将多个标志连在一起。例如:起。例如: cout.setf(ios:scientific|ios:showpoint); 同时设置同时设置

16、scientific和和showpoint两个标志。两个标志。(2)unsetf() 成员函数成员函数unsetf()用来取消格式标志,用来取消格式标志,unsetf()的的用法与用法与setf()相似。相似。(3)flags() 成员函数成员函数flags()用于获取当前格式标志的状态,用于获取当前格式标志的状态,即返回保护成员即返回保护成员x_flags的当前值。的当前值。(4)precision() 该函数的说明如下:该函数的说明如下: int precision(int num); 用于设置或返回(不带参数时)浮点数的输出精用于设置或返回(不带参数时)浮点数的输出精度,也就是通过这个公

17、共成员函数设置度,也就是通过这个公共成员函数设置ios类的保护类的保护数据成员数据成员x_precision的值,该成员的默认值为的值,该成员的默认值为6。 precision()函数的设置值一直有效,直到下一个函数的设置值一直有效,直到下一个precision()函数改变该值为止。函数改变该值为止。(5)width() 该函数的说明如下:该函数的说明如下: int width(int len); 用于设置或返回(不带参数时)输出数据的字段用于设置或返回(不带参数时)输出数据的字段宽度,也就是通过这个公共成员函数设置宽度,也就是通过这个公共成员函数设置ios类的保类的保护数据成员护数据成员x_

18、width的值。的值。 width()函数的设置值只对下一个输出有效。函数的设置值只对下一个输出有效。(6)fill() 该函数的说明如下:该函数的说明如下: char fill(char ch); 用于设置或返回(不带参数时)输出的填充字用于设置或返回(不带参数时)输出的填充字符,也就是通过这个公共成员函数设置符,也就是通过这个公共成员函数设置ios类的保护类的保护数据成员数据成员x_fill的值,该成员的默认值为空格。的值,该成员的默认值为空格。 fill ()函数的设置值一直有效,直到下一个函数的设置值一直有效,直到下一个fill()函数改变该值为止。函数改变该值为止。【例】【例】 分析

19、以下程序的执行结果。分析以下程序的执行结果。#include void main() int n=123; double d=1234.5678; cout.precision(10); cout.width(10); cout.fill(*); cout n endl; cout d endl; cout.precision(6); cout.width(6); cout n endl; cout d endl; *123 1234.5678 *123 1234.57 右对齐右对齐13.2.2 使用使用I/O操纵符操纵符 除除ios类成员函数之外,类成员函数之外,C+的流类库还提供了另的流类

20、库还提供了另一种更方便的一种更方便的I/O格式化方法,这种方法使用一种称格式化方法,这种方法使用一种称为操纵符的特殊函数,操纵符的特点是可以直接包含为操纵符的特殊函数,操纵符的特点是可以直接包含在在I/O表达式中。表达式中。 所有不带形参的操纵符都定义在头文件所有不带形参的操纵符都定义在头文件iostream.h中,而带形参的操纵符则定义在头文件中,而带形参的操纵符则定义在头文件iomanip.h中,因而使用相应的操纵符就必须包含相中,因而使用相应的操纵符就必须包含相应的头文件。表应的头文件。表13.3列出了这些列出了这些I/O操纵符。操纵符。 已在第已在第3章已介绍,这是不再讨论。章已介绍,

21、这是不再讨论。13.3 13.3 重载重载I/OI/O运算符运算符 C+的的I/O系统的另一个优点是可以重载系统的另一个优点是可以重载I/O运运算符。通过重载算符。通过重载I/O运算符,可以建立适合于类需运算符,可以建立适合于类需要的输入和输出界面。要的输入和输出界面。 I/O运算符重载的实质就是把用于变量输入输运算符重载的实质就是把用于变量输入输出的运算符转化为对于类对象的输入输出操作。出的运算符转化为对于类对象的输入输出操作。13.3.1 重载输出运算符重载输出运算符“” 在在C+中,输出操作称为插入,中,输出操作称为插入,“”称为插入称为插入运算符。当重载输出运算符运算符。当重载输出运算

22、符“”用于输出时,相当用于输出时,相当于创建一个插入符函数。插入符函数的格式如下:于创建一个插入符函数。插入符函数的格式如下: friend ostream & operator (ostream & stream,类名类名 & 类引用名类引用名) 函数体函数体; return stream; 该插入符函数是以友元方式说明的。其中的第一该插入符函数是以友元方式说明的。其中的第一个参数是个参数是ostream类对象的一个引用,即类对象的一个引用,即stream必须必须是一个输出流。是一个输出流。“类引用名类引用名”接收待输出的对象。接收待输出的对象。该函数返回该函数返回ostream的一个引用的

23、一个引用stream。“函数体函数体”中给出实现该插入符重载目的的代码。中给出实现该插入符重载目的的代码。【例】【例】 分析以下程序的执行结果。分析以下程序的执行结果。#include class Sample int x,y;public: Sample(int m,int n) x=m;y=n; friend ostream & operator (ostream & stream,Sample & s) cout x= s.x ,y= s.y endl; return stream; ;void main() Sample A(1,2),B(3,4); cout A ” 在在C+中,中,

24、“”运算符称为提取运算符,对它进运算符称为提取运算符,对它进行重载的函数称为提取符函数。这个运算符函数接收行重载的函数称为提取符函数。这个运算符函数接收流的输入信息。其格式如下:流的输入信息。其格式如下: friend istream & operator (istream & stream,类名类名 & 类引用名类引用名) 函数体函数体; return stream; 该提取符函数是以友元方式说明的。其中的第一该提取符函数是以友元方式说明的。其中的第一个参数是个参数是istream类对象的一个引用,即类对象的一个引用,即stream必须是必须是一个输入流。一个输入流。“类引用名类引用名”接收

25、输入对象的引用。该接收输入对象的引用。该函数返回函数返回istream的一个引用的一个引用stream。“函数体函数体”中给中给出实现该提取符重载目的的代码。出实现该提取符重载目的的代码。【例】【例】 分析以下程序的执行结果。分析以下程序的执行结果。#include class Sample int x,y;public: Sample() friend istream & operator (istream & stream,Sample & s) cout 输入输入x和和y的值的值 endl; cout s.x; cout s.y; return stream; friend ostrea

26、m & operator (ostream & stream,Sample & s) cout 输出输出x和和y的值的值 endl; cout x= s.x ,y= s.y A; cout A; 输入输入x和和y的值的值 x:5 y:8 输出输出x和和y的值的值 x=5,y=813.4 13.4 检测流操作的错误检测流操作的错误 在在I/O流的操作过程中可能出现各种错误,每一个流的操作过程中可能出现各种错误,每一个流都有一个状态标志字,以指示是否发生了错误以及流都有一个状态标志字,以指示是否发生了错误以及出现了哪种类型的错误,这种处理技术与格式控制标出现了哪种类型的错误,这种处理技术与格式控制

27、标志字是相同的。志字是相同的。ios类定义了以下枚举类型:类定义了以下枚举类型: enum io_state goodbit =0 x00,/不设置任何位,一切正常不设置任何位,一切正常 eofbit =0 x01, /输入流已经结束,无字符可读入输入流已经结束,无字符可读入 failbit =0 x02, /上次读上次读/写操作失败,但流仍可使用写操作失败,但流仍可使用 badbit =0 x04, /试图作无效的读试图作无效的读/写操作,流不再可用写操作,流不再可用 hardfail=0 x80 /不可恢复的严重错误不可恢复的严重错误 ; 对应于这个标志字各状态位,对应于这个标志字各状态位

28、,ios类还提供了以下类还提供了以下成员函数来检测或设置流的状态:成员函数来检测或设置流的状态: int rdstate(); /返回流的当前状态标志字返回流的当前状态标志字 int eof(); /返回非返回非0值表示到达文件尾值表示到达文件尾 int fail(); /返回非返回非0值表示操作失败值表示操作失败 int bad(); /返回非返回非0值表示出现错误值表示出现错误 int good(); /返回非返回非0值表示流操作正常值表示流操作正常 int clear(int flag=0); /将流的状态设置为将流的状态设置为flag 为提高程序的可靠性,我们应在程序中检测为提高程序的

29、可靠性,我们应在程序中检测I/O流流的操作是否正常。当检测到流操作出现错误时,可以的操作是否正常。当检测到流操作出现错误时,可以通过异常处理来解决问题。通过异常处理来解决问题。13.5 13.5 文文 件件 流流 文件是存储在磁盘、磁带等外部设备上的数据集文件是存储在磁盘、磁带等外部设备上的数据集合,每一个文件都必须有一个惟一名字。合,每一个文件都必须有一个惟一名字。 使用文件前必须首先打开,使用完毕后必须关闭使用文件前必须首先打开,使用完毕后必须关闭文件。文件。 对文件的操作是由文件流类完成的。文件流类在对文件的操作是由文件流类完成的。文件流类在流与文件之间建立连接,使用这些文件流类必须用流

30、与文件之间建立连接,使用这些文件流类必须用#include编译指令将头文件编译指令将头文件fstream.h包含进来。包含进来。13.5.1 文件的打开与关闭文件的打开与关闭 流可以分为流可以分为3类:输入流、输出流以及输入类:输入流、输出流以及输入/输出输出流,相应地必须将流说明为流,相应地必须将流说明为ifstream、ofstream以及以及fstream类的对象。例如:类的对象。例如: ifstream ifile; /说明一个输入流说明一个输入流 ofstream ofile; /说明一个输出流说明一个输出流 fstream iofile; /说明说明个输入个输入/输出流输出流 说明

31、了流对象之后,可使用函数说明了流对象之后,可使用函数open()打开文件。打开文件。文件的打开即是在流与文件之间建立一个连接。文件的打开即是在流与文件之间建立一个连接。open()的函数原型为:的函数原型为: void open(const char * filename, int mode, int prot=filebuf:openprot); 其中,其中,filename是文件名字,它可包含路径说明。是文件名字,它可包含路径说明。 mode说明文件打开的模式,它对文件的操作影响说明文件打开的模式,它对文件的操作影响重大,重大,mode的取值必须是以下值之一:的取值必须是以下值之一: io

32、s:in 打开文件进行读操作打开文件进行读操作 ios:out 打开文件进行写操作打开文件进行写操作 ios:ate 打开时文件指针定位到文件尾打开时文件指针定位到文件尾 ios:app 添加模式,所有增加都在文件尾部进行添加模式,所有增加都在文件尾部进行 ios:trunc 如果文件已存在则清空原文件如果文件已存在则清空原文件 ios:nocreate 如果文件不存在则打开失败如果文件不存在则打开失败 ios:noreplace 如果文件存在则打开失败如果文件存在则打开失败 ios:binary 二进制文件(非文本文件)二进制文件(非文本文件) 对于对于ifstream流,流,mode的默认

33、值为的默认值为ios:in;对于;对于ofstream流,流,mode的默认值为的默认值为ios:out。 prot决定文件的访问方式,取值如下:决定文件的访问方式,取值如下: 0 普通文件普通文件 1 只读文件只读文件 2 隐含文件隐含文件 4 系统文件系统文件 一般情况下,该访问方式使用默认值。一般情况下,该访问方式使用默认值。 与其他状态标志一样,与其他状态标志一样,mode的符号常量可以用位的符号常量可以用位或运算或运算“|”组合在一起,如组合在一起,如ios:in|ios:binary表示以表示以只读方式打开二进制文件。例如:只读方式打开二进制文件。例如: ifstream ifil

34、e; ifile.open(c:vcabc.txt,ios:ate);表示以文本文件形式打开表示以文本文件形式打开C:vc目录下的目录下的abc.txt文件,文件,文件指针定位到文件尾,准备进行读文件操作。而文件指针定位到文件尾,准备进行读文件操作。而操作:操作: ofstream ofile; ofile.open(c:vcabc.txt,ios:binary);表示以二进制文件形式打开表示以二进制文件形式打开C:vc目录下的目录下的abc.txt文文件,准备进行写文件操作。件,准备进行写文件操作。 其中,文件名中其中,文件名中“”的第一个的第一个“”为转义字符。为转义字符。 除了除了ope

35、n()成员函数外,成员函数外,ifstream、ofstream和和fstream三类流的构造函数也可以打开文件,其参数同三类流的构造函数也可以打开文件,其参数同open()函数。例如:函数。例如: ifstream ifile(c:vcabc.txt ); 说明一个输入流对象的同时,将这个流与文件说明一个输入流对象的同时,将这个流与文件“c:vcabc.txt”连接起来,使流连接起来,使流ifile可以用文本形式对可以用文本形式对该文件进行读操作。该文件进行读操作。13.5.2 文件的读写文件的读写 通过打开文件就建立通过打开文件就建立I/O流与文本文件的连接,之流与文本文件的连接,之后就可

36、以进行文件的读写操作了。后就可以进行文件的读写操作了。1文件读写方法文件读写方法 在在C+中提供了几种文件读写方法。中提供了几种文件读写方法。 (1)使用流运算符直接读写。)使用流运算符直接读写。 文件的读文件的读/写操作可以直接使用流的插入运算符写操作可以直接使用流的插入运算符“”,这些运算符将完成文件,这些运算符将完成文件的字符转换工作。的字符转换工作。 (2)使用流成员函数。)使用流成员函数。 常用的输出流成员函数如下:常用的输出流成员函数如下: put函数函数 该函数把一个字符写到输出流中。下面该函数把一个字符写到输出流中。下面两个语句默认是相同的,但第二个受该流的格式化参两个语句默认

37、是相同的,但第二个受该流的格式化参数的影响:数的影响: cout.put(A); /精确地输出一个字符精确地输出一个字符 cout )很)很相似,主要的不同点是相似,主要的不同点是get函数在读取数据时包括空白函数在读取数据时包括空白字符,而提取运算符在默认情况下拒绝接受空白字符。字符,而提取运算符在默认情况下拒绝接受空白字符。 getline函数函数 该函数的功能是允许从输入流中读该函数的功能是允许从输入流中读取多个字符,并且允许指定输入终止字符(默认值是取多个字符,并且允许指定输入终止字符(默认值是换行字符),在读取完成后,从读取的内容中删除该换行字符),在读取完成后,从读取的内容中删除该

38、终止字符。终止字符。 read函数函数 该函数从一个文件读字节到一个指定该函数从一个文件读字节到一个指定的存储器区域,由长度参数确定要读的字节数。虽然的存储器区域,由长度参数确定要读的字节数。虽然给出长度参数,但当遇到文件结束或者在文本模式文给出长度参数,但当遇到文件结束或者在文本模式文件中遇到文件结束标记字符时读就结束。件中遇到文件结束标记字符时读就结束。2文本文件的读写文本文件的读写 文本文件只适用于那些解释为文本文件只适用于那些解释为ASCII码的文件。码的文件。处理文本文件时将自动作一些字符转换,如输出换处理文本文件时将自动作一些字符转换,如输出换行字符行字符0 x0A时将转换为回车时

39、将转换为回车0 x0D与换行与换行0 x0A两个字两个字符存入文本文件,读入时也会将回车与换行两个字符存入文本文件,读入时也会将回车与换行两个字符合并为一个换行字符,这样内存中的字符与写入符合并为一个换行字符,这样内存中的字符与写入文件中的字符之间就不再是一一对应关系。文件中的字符之间就不再是一一对应关系。 文本文件的结束以文本文件的结束以ASCII码的控制字符码的控制字符0 x1A表示。表示。【例】【例】 分析以下程序的执行结果。分析以下程序的执行结果。#include #include int main() ofstream ofile(test); /打开打开test文件用于写,即输出文

40、件用于写,即输出 if (!ofile) cout test文件不能打开文件不能打开 endl; return 0; ofile This book is C+ 12345 endl; ofile.close(); ifstream ifile(test); /打开打开test文件用于读,即输入文件用于读,即输入 if (!ifile) cout test文件不能打开文件不能打开 str; ifile.close(); cout str endl; return 1; 本程序先在当前目录下建立一本程序先在当前目录下建立一个个test文本文件,并写入文本文件,并写入“This book is C

41、+ 12345”数据,然后打数据,然后打开该文件,将其中的数据输入到开该文件,将其中的数据输入到变量变量str中,由于读时遇到空格时中,由于读时遇到空格时终止,所以终止,所以str为为“This”。程序的。程序的执行结果如下:执行结果如下: This 【例】【例】 编写一个程序,将文本文件编写一个程序,将文本文件abc.txt复制到复制到文本文件文本文件xyz.txt。 解:使用输入流成员函数解:使用输入流成员函数get()从文本文件从文本文件abc.txt中读取一个字符中读取一个字符ch,然后使用输出流成员函数,然后使用输出流成员函数put()将字符将字符ch写入文本文件写入文本文件xyz.

42、txt中,继续这一过程直到中,继续这一过程直到get()读完为止。实现本例功能的程序如下:读完为止。实现本例功能的程序如下:#include #include int main() ifstream ifile(abc.txt); char ch; if (!ifile) cout abc.txt文件不能打开文件不能打开 endl; return 0; ofstream ofile(xyz.txt); if (!ofile) cout xyz.txt文件不能打开文件不能打开 endl; return 0; while (ifile.get(ch) ofile.put(ch); ifile.cl

43、ose(); ofile.close(); return 1;3二进制文件的读写二进制文件的读写 二进制文件不同于文本文件,它可用于任何类二进制文件不同于文本文件,它可用于任何类型的文件(包括文本文件),读写二进制文件的字型的文件(包括文本文件),读写二进制文件的字符不作任何转换,读写的字符与文件之间是完全一符不作任何转换,读写的字符与文件之间是完全一致的。致的。 一般地,对二进制文件的读写可采用两种方法:一般地,对二进制文件的读写可采用两种方法:一种是使用一种是使用get()和和put();另一种是使用;另一种是使用read()和和write()。 【例】以下程序建立一个输出文件流并将一个【

44、例】以下程序建立一个输出文件流并将一个Date结构体变量的二进制值写入到该文件中。结构体变量的二进制值写入到该文件中。 #include struct Date int mo,da,yr; ; void main() Date dt=2,20,2001; ofstream ofile(data.dat,ios:binary); ofile.write(char *)&dt,sizeof dt); ofile.close(); 4文件的随机读写文件的随机读写 每一个文件都有两个指针:一个是读指针,说明每一个文件都有两个指针:一个是读指针,说明输入操作当前在文件中的位置;另一个是写指针,说输入操作

45、当前在文件中的位置;另一个是写指针,说明下次写操作的当前位置。明下次写操作的当前位置。 每次执行输入或输出时,相应的读每次执行输入或输出时,相应的读/写指针将自写指针将自动向后移动。动向后移动。 C+语言的文件流不仅可以按这种顺序方式进行语言的文件流不仅可以按这种顺序方式进行读读/写,而且还可以随机地移动文件的读写,而且还可以随机地移动文件的读/写指针。有写指针。有一些外部设备(如磁带、行式打印机等)关联的流只一些外部设备(如磁带、行式打印机等)关联的流只能作顺序访问,但在许多情况下使用随机方式访问文能作顺序访问,但在许多情况下使用随机方式访问文件更加方便灵活。件更加方便灵活。(1)输出流随机

46、访问函数)输出流随机访问函数 输出流随机访问函数有输出流随机访问函数有seekp和和tellp。 一个输出文件流保存一个内部指针以指出下一一个输出文件流保存一个内部指针以指出下一次写数据的位置。次写数据的位置。seekp成员函数设置这个指针,因成员函数设置这个指针,因此可以以随机方式向磁盘文件输出。此可以以随机方式向磁盘文件输出。tellp成员函数返成员函数返回该文件位置指针值。这两个成员函数的原型如下:回该文件位置指针值。这两个成员函数的原型如下: ostream & ostream:seekp(流中的位置流中的位置); ostream & ostream:seekp(偏移量偏移量,参照位置

47、参照位置); streampos ostream:tellp(); 其中,其中,streampos被定义为被定义为long型,并以字节型,并以字节数为单位。数为单位。“参照位置参照位置”具有如下含义:具有如下含义: cur=1 相对于当前写指针所指定的位置。相对于当前写指针所指定的位置。 beg=0 相对于流的开始位置。相对于流的开始位置。 end=2 相对于流的结尾处。相对于流的结尾处。(2)输入流随机访问函数。)输入流随机访问函数。 输入流随机访问函数有输入流随机访问函数有seekg和和tellg。 在输入文件流中,保留着一个指向文件中下一在输入文件流中,保留着一个指向文件中下一个将要读数据的位置的内部指针,可以用个将要读数据的位置的内部指针,可以用seekg函数函数来设置这个指针。使用来设置这个指针。使用seekg可以实现面向记录的数可以实现面向记录的数据管理系统,用固定长度的记录大小乘以记录号便据管理系统,用固定长度的记录大小乘以记录号便得到相对于文件末尾的字节位置,

温馨提示

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

评论

0/150

提交评论