第13章C的IO流类库.ppt

上传人:sccc 文档编号:5634169 上传时间:2023-08-04 格式:PPT 页数:45 大小:103.51KB
返回 下载 相关 举报
第13章C的IO流类库.ppt_第1页
第1页 / 共45页
第13章C的IO流类库.ppt_第2页
第2页 / 共45页
第13章C的IO流类库.ppt_第3页
第3页 / 共45页
第13章C的IO流类库.ppt_第4页
第4页 / 共45页
第13章C的IO流类库.ppt_第5页
第5页 / 共45页
点击查看更多>>
资源描述

《第13章C的IO流类库.ppt》由会员分享,可在线阅读,更多相关《第13章C的IO流类库.ppt(45页珍藏版)》请在三一办公上搜索。

1、第13章 C+的I/O流类库,13.1 C+的流及流类库,13.1.1 C+的流 输入和输出是数据传送的过程,数据如流水从一处流向另一处。C+形象地将此过程称为流(stream)。C+的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。流表示了信息从源到目的端的流动。,1)输入流 在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,称为输入流。2)输出流在输出操作时,字节流从内存流向输出设备(如显示器、打印机、磁盘等),称为输出流。,流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其它形式的信息。,3)输入输出流的本质,实际

2、上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。当用cout和插入运算符“”从输入缓冲区中提取数据送给程序中的有关变量。,4)流类,在C+中,输入输出流被定义为类。C+的IO库中的类称为流类(stream class)。用流类定义的对象称为流对象。例如 cin和cout就是iostream_withassign类的对象。,13.1.2 流类库,C+流库是C+语言为完成输入/输出工作而预定义的类的集合。C+的IO流类库是用继承方法建立起来的一个输入输出类库,这些类构成一个层次结构的系统。它具有两个平行类:即streambuf类和ios类,这两个类是基本类,所有的流类都可以由它们

3、派生出来。,1.streambuf类,streambuf类提供物理设备的接口,它提供缓冲或处理流的通用方法,几乎不需要任何格式。缓冲区由一个字符序列和两个指针组成,这两个指针是输入缓冲区指针和输出缓冲区指针,它们分别指向字符要被插入或取出的位置。streambuf类提供对缓冲区的低级操作,如设置缓冲区、对缓冲区指针进行操作、从缓冲区取字符、向缓冲区存储字符。,streambuf有三个派生类,即filebuf、strstreambuf和conbuf,其成员函数大多采用内置函数方式定义,以提高效率。下图为它们之间的层次关系。,2.ios类,ios类是一个虚基类,它主要定义了用于格式化输入输出及出错

4、的成员函数。在ios类和它的各级派生类中,均含有一个指向流缓冲类streambuf的对象的指针。Ios类(及其派生类)使用streanbuf类以及它派生的文件缓冲类filebuf和字符缓冲类strstreambuf进行输入输出。常用iso流类的简要说明和类声明所在的头文件名见书第373页表13.1。,ios流类层次图,在头文件iostream.h中,提供了4个预定义的标准流对象:extern istream_withassign cin;/预定义代表标准输入设备键盘extern ostream_withassign cout;/预定义代表标准输出设备显示器extern istream_with

5、assign cerr;/预定义代表标准出错输出设备显示器extern istream_withassign clog;/预定义代表标准出错输出设备显示器。,说明,这四个标准流对象是程序中进行标准输入输出要用到的。cin对象是从标准输入设备(键盘)输入到内存的数据流,称为cin流或标准输入流。cout对象是从内存输入到标准输出设备(显示器)的数据流,称为cout流或标准输出流。cerr和clog均为向输出设备(显示器)输出出错信息。,132 格式化I/O 在很多情况下,程序员需要控制输入输出格式。C+提供了两种格式控制方法:使用ios类中有关格式控制的成员函数;使用称为控制符的特殊类型的函数。

6、1321 用ios类的成员函数进行格式控制 ios类中有几个成员函数可以用来对输入输出进行格式控制。进行格式控制主要是通过对格式状态字、域宽、填充字符以及输出精度的操作来完成的。,1格式状态字 C+可以给每个流对象的输入输出进行格式控制,以满足程序员对输入输出格式的需求。输入输出格式由一个long int类型的格式状态字确定,状态字的各位都控制一定的输入输出特征。在ios类的public部分定义了一个枚举,它的每个成员可以分别定义格式状态字的一个位,每一个位称为一个状态标志位。这个枚举的定义如下:enum skipws=0 x0001,left=0 x0002,right=0 x0004,in

7、ternal=0 x0008,dec=0 x0010,oct=0 x0020,hex=0 x0040,showbase=0 x0080,showpoint=0 x0100,uppercase=0 x0200,showpos=0 x0400,scientific=0 x0800,fixed=0 x1000,unitbuf=0 x2000,stdio=0 x4000;,2ios类中用于控制输入输出格式的成员函数 在ios类的说明中,定义了几个用于格式控制的公有成员函数,列举如下:long ios:flags();/返回当前格式状态字long ios:flags(long):/设置格式状态字并返回l

8、ong ios:setf(long);/设置指定的标志位long ios:unsetf(long);/清除指定的标志位int ios:width();/返回当前显示数据的域宽int ios:width(int);/设置当前显示数据域宽并返回原域宽char ios:fill();/返回当前填充字符char ios:fill(char);/设置填充字符并返回原填充字符int ios:precision();/返回当前浮点数的精度int ios:precision(int);/设置浮点数精度并返回原精度,例13-1 格式状态字的设置和清除#include using namespace std;in

9、t main()long f;int i;double x;i=200;x=53.6;f=cout.flags();/取当前格式状态字 coutThe flags is fendl;/The flags is 513 couti=i,x=xendl;/i=200,x=53.6 cout.unsetf(ios:dec);/终止十进制的格式设置 cout.setf(ios:hex|ios:showbase);/设置以十六进制输出并显示基数符号 cout.setf(ios:scientific);/指定科学记数法输出 couti=i,x=xendl;/i=0 xc8,x=5.360000e+001

10、cout.setf(ios:uppercase);/输出字母时以大写显示 couti=i,x=xendl;/i=0XC8,x=5.360000E+001 return 0;,例13-2 域宽和填充字符的设置#include using namespace std;int main()int i;double x,y;i=100;x=23.14159;y=23.575;coutDefault width is cout.width()endl;coutDefault fill is cout.fill()endl;coutDefault precision is cout.precision()

11、endl;couti x yendl;cout.width(10);couti x yendl;cout.precision(4);couti x yendl;cout.fill(*);cout.width(10);couti x yendl;return 0;,程序运行结果为:Default width is 0Default fill isDefault precision is 6100 23.1416 23.575 100 23.1416 23.575100 23.14 23.57*100 23.14 23.57,1322 使用I/O操纵符进行格式控制 使用ios类的成员函数进行输入输

12、出格式控制时,每个函数的调用需要写一条语句,而且不能将它们直接嵌入到输入输出语句中,使人感到不够简洁、方便。C+提供另一种进行输入输出格式控制的方法,这一方法使用一种称为操纵符的特殊函数。在很多情况下,使用操纵符进行格式化控制比用ios格式标志和成员函数要方便。C+预定义的操纵符分为带参数的操纵符和不带参数的操纵符。通常,不带参数的操纵符在iostream文件中定义,而带参数的操纵符在iomanip文件中定义。在进行输入输出时,操纵符被嵌入到输入或输出链中,用来控制输入输出格式,而不执行输入或输出操作。,定义在iostream头文件中的操纵符有:endl 输出时插入换行符并刷新流 ends 输

13、出时在字符串后插入空字符(NULL)作为尾符 flush 刷新,把流从缓冲区输出到目标设备 ws 输入时略去空白字符 dec 以十进制形式输入或输出整型数 hex 以十六进制形式输入或输出整型数 oct 以八进制形式输入或输出整型数,定义在iomanip头文件中的操纵符有:setbase(int n)设置转换基数为n(n取值为0、8、10或16),缺省时为0,表示采用十进制形式输出 resetiosflags(long f)清除由参数f指定的标志位,用于输入输出 setiosflags(long f)设置参数f指定的标志位 setfill(char c)设置填充字符 setprecision(

14、int n)设置浮点数精度(缺省为6)setw(int n)设置数据宽度 程序中如果使用带参数的操纵符,还必须使用预编译命令:include 将需要的头文件包含进来。,例13-3 操纵符的使用#include#include using namespace std;int main()int i;couti;coutDec:i endl;/以十进制形式输出 coutOct:octiendl;/以八进制形式输出 coutHex:setbase(16)iendl;/以十六进制输出 coutdecsetw(8)123456endl;cout123.4567 setiosflags(ios:scien

15、tific)123.456endl;coutsetfill(*)setw(10)123endl;coutsetiosflags(ios:left)setfill(#)setw(10)123endl;coutresetiosflags(ios:left)setfill($)setw(10)123endl;return 0;,程序的运行情况如下:Input i:100Dec:100Oct:144Hex:64 123456123.457 1.234560e+002*123123#$123,13.3 重载I/O运算符,C+创建自己的流库的主要目的,就是用户自定义类型数据的输入输出也能像系统预定义类型数

16、据的输入输出一样简单、方便,这是通过重载输入运算符“”和输出运算符“”来实现的。,13.3.1 重载输出运算符“”,一般格式:ostream 说明由于重载输出运算符时,其函数中的第一个参数必须是输出流,因此重载输出运算符必须是非成员函数。,例13-4 输出运算符“using namespace std;class Pointpublic:int x,y;Point(int i=0,int j=0)x=i;y=j;ostream,例13-5 输出运算符重载为类的友元函数#include class Pointpublic:Point(int i=0,int j=0)x=i;y=j;friend

17、ostream,13.3.2 重载输入运算符“”,一般格式:istream 说明重载输入运算符时,函数中的第二个参数必须是一个引用;重载输入运算符必须是非成员函数。,例13-6 输入运算符的重载#include class Pointpublic:Point(int i=0,int j=0)x=i;y=j;friend istream,ostream,134 文件流 C+把文件看作是字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二进制文件。在C+中,进行文件操作 首先建立一个文件流,然后把这个流和实际的文件相关联,这称为打开文件;文件打开

18、后,可以按要求进行读写操作,一般来说,在主存与外设的数据传输中,由主存到外设叫做输出或写,而由外设到主存叫做输入或读;完成输入输出后,还必须将已打开的文件关闭,即取消文件和流的关联。,1341 文件的打开和关闭1文件的打开 文件使用时,必须先打开,后使用。打开文件时必须指定文件的打开方式。C+为文件输入输出提供了3个类:ifstream、ofstream和fstream。与这三个类相对应,C+为文件输入输出提供了三种类型的流,即输入流、输出流以及输入/输出流。例如:ifstream in;/输入 ofstream out;/输出 fstream both;/输入和输出 将产生一个输入流(in)

19、,个输出流(out)和一个既可输入、又可输出的流(both)。,文件的打开有两种方式,用输入输出流的成员函数打开 用构造函数打开(1)用流ifstream、ofstream和fstream类对象的成员函数方式打开文件。open()函数是这三个流类的成员函数,其原型为:void open(const unsigned char*,int mode,int access=filebuf:openprot);其中第一个参数用来传递文件名,第二个参数mode的值决定文件的打开方式,第三个参数决定文件的保护方式,用户通常只使用缺省值。,打开方式是已经在ios类中定义了的枚举常量。常用的有:ios:in

20、打开一个文件用于输入(读)操作。ios:out 打开一个文件用于输出(写)操作 ios:ate 打开一个已有的文件,文件指针指向文件尾。ios:app 以输出方式打开文件,写入的数据添加在文件末尾 ios:trunc 打开一个文件。如果文件已存在,则删除其中全部数据;如果文件不存在,则建立新文件。如果已指定了ios:out,而未指定ios:app、ios:ate、ios:in,则同时默认此方式。ios:nocreate 打开一个已有的文件,如果文件不存在,则打开文件失败(即不创建一个新文件)。ios:noreplace 如果文件不存在则建立新文件,如果文件存在,则打开失败。noreplace是

21、不更新原有文件的意思。ios:binary 指定文件以二进制方式打开,而不是缺省说明的文本方式。,(2)用构造函数打开文件。用构造函数打开文件的格式是:ifstream 对象名(文件名)ofstream 对象名(文件名)fstream 对象名(文件名,打开方式)例如,语句ofstream fout(“mytest.txt”);它相当于语句:ofstream fout;fout.open(mytest.txt);,只有在打开文件之后,才能对文件进行读写操作。如果由于某些原因打不开文件(即执行函数open()失败),则流变量的值将为0。因此,在对文件进行操作前,必须确保文件已打开,否则要进行相应的

22、处理。为了确认打开一个文件是否成功,可以使用类似下面的办法进行检测:ifstream fin(mytest.txt);/打开输入文件if(!fin)cout”Cannot open file!n”;/错误处理代码 为了确保文件操作的顺利进行,在打开文件时通常都要判断是否成功。,2文件的关闭 当对一个打开的文件操作完毕后,应及时调用文件流的成员函数来关闭相应的文件。具体格式为:流对象名close();其中流对象名为待关闭的文件流的对象名。Close()函数不带任何参数,也不返回任何值。文件流的对象通过文件打开函数,建立起文件名与该对象的联系后,就可对文件进行读、写操作,文件关闭后,就断开了文件流

23、与对象间的联系。如果要对文件再次进行读、写,就要重新打开文件。,1342 文件的读写 当文件打开以后,即文件与流建立了联系后,就可以进行读写操作了。1文本文件的读写 对文本文件的读写操作可以用以下两种方法:(1)用流输出运算符“”输入输出标准类型的数据。在对磁盘文件的操作中,可以通过文件流对象和运算符“”实现对磁盘文件的读写,如同用cin、cout和对标准设备进行读写一样,只是必须用与文件相连接的文件流代替cin和cout。,例13-7 生成一个sqrtable.txt文件,该文件内容为100以内整数的平方根表,结果精确到小数点后4位。#include#include#include#incl

24、ude using namespace std;int main()ofstream table;table.open(sqrtable.txt);int i,j;if(!table)coutCannot open output file!n;return 1;table|;for(i=0;i10;i+)tablesetw(5)i;tableendl;,table-+;for(i=0;i10;i+)table-;tablefixedsetprecision(4);for(i=0;i10;i+)tableendl;tablesetw(2)i|;for(j=0;j10;j+)tablesetw(8

25、)sqrt(10*i+j);table.close();return 0;,(2)用文件流的put、get和getline等成员函数进行字符的输入输出。成员函数put用于输出一个字符,格式为:输出流对象.put(ch);成员函数get用于读入一个字符,它有3种形式:输入流对象.get();输入流对象.get(ch);输入流对象.get(字符数组或字符指针,字符个数n,终止字符);成员函数getline用于读入一行字符,其用法与带3个参数的get函数类似,即:输入流对象.getline(字符数组或字符指针,字符个数n,终止字符);,例13-8 将文件sqrtable.txt复制为文件mttabl

26、e.txt。#include#include using namespace std;int main()char c;ifstream fin(sqrtable.txt);if(!fin)coutCannot open input file!n;return 1;ofstream fout(mytable.txt);if(!fout)coutCannot open output file!n;return 1;while(fin.get(c)fout.put(c);return 0;,2二进制文件的读写 对二进制文件的读写主要用istream类的成员函数read和ostream类的成员函数w

27、rite来实现的。这两个函数的原型如下:istream,例13-9 将11000之间的所有素数以二进制形式存放在磁盘文件Prime.dat中。#include#include#include using namespace std;int main()fstream table;table.open(Prime.dat,ios:binary|ios:out);if(!table)coutsqrt(i)table.write(char*),例13-10 将例13-9 得到的Prime.dat中的数据读入内存并在显示器上显示。#include#include#include using names

28、pace std;int main()fstream table;table.open(Prime.dat,ios:binary|ios:in);if(!table)coutCannot open input file!n;return 1;int i;while(!table.eof()table.read(char*),3文件的随机读写 随机存取文件(又称直接存取文件)在访问文件中的元素时,不必考虑各个元素的排列次序或位置,可以根据需要访问文件中的任一个元素。为了进行随机存取,必须先确定文件指针的位置。在C+中,可以用以下几个函数来确定指文件指针位置。(1)seekg(pos);seekp

29、(pos);这两个函数都是从文件头开始,把文件指针向后移动pos个字符(字节)。其中seekg用于输入文件,而seekp用于输出文件。参数pos是相对于文件头的位移量,其类型是streamoff,这种类型在头文件iostream中定义如下:typedef streamoff long;可以看出,它实际上是long型。,(2)seekg(pos,orgin);seekp(pos,orgin);这两个函数实际上是前两个函数的重载函数。前两个函数从文件头移动文件指针,而这两个函数则是从指定的位置开始移动文件指针。参数origin表示文件指针的起始位置,pos表示相对于这个起始位置的位移量。origi

30、n的取值有以下三种情况:ios:beg 从文件头开始,把文件指针移动由pos指定的距离 ios:cur 从当前位置开始把文件指针移动由pos指定的距离 ios:end 从文件尾开始,把文件指针移动由pos指定的距离 seekg函数用输入文件,而seekp函数用于输出文件。(3)tellg()tellp()这两个函数用来返回文件指针的当前位置。其中tellg函数用于输入文件,tellp函数用于输出文件。,对文件进行随机读写关键在于控制文件的位置指针。即为了能进行随机读写,必须把文件指针移到适当的位置。例如:seekg(100);把输入文件的位置指针移到离文件头100个字节处;seekp(80);把输出文件的位置指针移到离文件头80个字节处;seekg(100,ios:cur);把输入文件指针移到当前位置后100个字节处;seekp(-80,ios:end);把输出文件指针向前移到离文件尾80个字节处。确定了指针位置后,其读写操作与顺序文件相同。程序设计 例13-11 有5个联系人的电话号码,编写一个程序,要求:(1)将它们保存到磁盘文件phonenumber.dat中;(2)修改文件中指定的第n个联系人的信息;(3)将文件中的数据显示出来。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号