c程序设计第九章.ppt_第1页
c程序设计第九章.ppt_第2页
c程序设计第九章.ppt_第3页
c程序设计第九章.ppt_第4页
c程序设计第九章.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

第九章 C+流,了解I/O流类库中每个流类的大致作用和它们之间的继承关系,系统头文件iostream.h,fstream.h,strstrea.h,iomanip.h中各包括那些流类。 掌握文件流的使用。,9.1 流的概念,“流”就是物质从一处向另一处流动的过程。C+流就是指信息的输入输出过程,具体地说就是信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存)输入和从内存向外部输出设备(如显示器)输出的过程。 为了实现信息的流动,C+定义了I/O类库,其中的每一个类都称作相应的流或流类,用以完成某一方面的功能。 根据每一个流类定义的对象也常被称作流。如,根据文件流类(fstream)定义的一个对象fio,可以称作fio流或fio文件流,用它可以同磁盘上的一个文件相联系,实现对该文件的输入输出,fio就等同于与之相联系的文件。,C+的I/O类主要有ios,istream.ostream,iostream,ifstream,ofstream,fstream,istrstream,ostrstream,strstream等,其中ios为根基类,其余都是他的直接或间接派生类。(P308 图91) 上述I/O类,被包含在iostream.h,fstream.h,strstrea.h这三个系统头文件中。 头文件iomanip.h则包含了setw等大多数操纵符的定义以及iostream.h中的所有内容。,C+中数据的输入输出(简称I/O)包括三个方面: (1)对标准输入设备键盘和对标准输出设备显示器的输入输出,简称标准I/O。 (2)对在外存磁盘上文件的输入输出,简称文件I/O。 (3)对内存中指定的字符串空间的输入输出,简称为串I/O。,在一个程序或者编译单元中,当需要进行标准I/O操作时,则必须包含头文件iostream.h;当需要进行文件I/O操作时,则必须包含头文件fstream.h;当需要进行串I/O操作时,则必须包含头文件strstrea.h;如果在进行上述I/O操作时要用到setw等操纵符,则必须包含iomanip.h。,9.1.2 预定义流对象,C+有四个预定义的流对象: cin 标准输入 cout 标准输出 cerr 标准出错信息输出 clog 带缓冲的标准出错信息输出 其中,cin为istream流类的对象,其余三个为ostream流类的对象。所以,要使用这些流对象,就要在程序的开头包含头文件iostream.h,如果同时要使用setw等操纵符,就必须包含iomanip.h,当然,包含了iomanip.h 就不必在包含iostream.h。,9.1.3 提取操纵符和插入操纵符,的功能是从输入流中提取数据赋给一个变量,因此称之为提取操作符。 从键盘上输入的每个数据之间必须用空白字符(空格、回车、制表符)分开。 的功能是把表达式的值插入到输出流中,因此称之为插入操作符。,9.1.4 有格式的输入输出和无格式的输入输出,数据都有其内部存储格式和外部表现形式。 (1)无格式的输入输出,数据的内部存储格式和外部表现形式完全相同,所以,无格式的输入输出只能针对磁盘文件,而且必须调用流对象专门的成员函数实现。 (2)有格式的输入输出是在输入输出过程中完成内部存储格式和外部表现形式之间适当的转换。,有格式的输入输出针对的是键盘、显示器、打印机等字符设备以及磁盘中的文本文件,文本文件在DOS下可以用type命令显示其内容。 cin,cout等预定义的流对象以及操作符只能用于有格式的输入输出,因为与它们连接的键盘、显示器是字符设备。,9.1.5 操纵符,C+流提供了许多可以与操作符配合使用的特殊函数,称为操纵符。每一个操纵符都与一个具体的函数相联系,使得可以通过他们间接调用与之联系的函数,完成相应的输入输出或输入输出控制功能。如endl,setw就是操纵符。 例:cout“value=”setw(6)I; cout流对象通过操纵符setw间接地调用了cout类的成员函数width( ),即相当于: cout“value=”; cout.width(6); coutI;,9.2 输入输出的格式控制,9.2.1格式控制标志的设置 在ios中,有一个用于数据成员格式控制的变量,专门用来记录格式控制标志,通过设置标志,可以人为的控制有格式输入输出的效果,各格式控制标志的含义如P312表所示,例题9.1 数据控制实例 #include void main() int x=35,y=391,z=1024; coutx y zendl; coutoctx y zendl; couthexx y zendl; cout.setf(ios:uppercase); coutx y zendl; cout.setf(ios:showbase); coutx y zendl; coutdecx y zendl; ,35 391 1024 43 607 2000 23 187 400 23 187 400 0X23 0X187 0X400 35 391 1024,9.3 文件操作,以前对数据的输入输出都是在键盘和显示器上进行的,不能保存下来。如果想让输入输出的数据能够被保存下来,就要利用磁盘,把这些信息以文件的形式组织并存储。 保存数据的文件按存储方式分为两种类型,一种是文本文件格式,简称文本文件或字符文件、ASCII码文件;另一种是二进制格式的文件,简称二进制文件或字节文件。,文本文件每个字节单元存放一个ASCII码,代表一个字符,被读出后,能够直接送到显示器上显示或打印机上打印,供人们直接阅读。 二进制文件的文件内容是数据的内部表示,是从内存中直接复制过来的。 对于字符信息,数据的内部表示就是字符的代码,所以在文本文件和在二进制文件中的内容没有区别;但对于数值信息,数据的内部表示和字符代码表示截然不同。如对于一个短整型数128,它的内部表示占用两个字节:00000000 10000000,若表示成十六进制则为00 80,而它的字符代码表示则占三个字节,用十六进制表示分别为:31 32 38,对于文本文件,当从内存向文本文件输出数据时需要自动转换成它的ASCII码,从文本文件向内存输入数据时,需要自动转换成它的内部表示。 对于二进制文件,输入输出则不需要转换,仅是内外存信息的直接拷贝,速度自然要比文本文件的处理要快的多,但二进制文件不能以字符形式输出供人们直接阅读。 另外,当向文本文件输出一个换行符n时,则将被看作为输出了回车r和换行n两个字符;相反,当从文本文件中读取回车和换行两个字符时,也被看作一个换行符。,C+系统把各种外部设备也看作相应的文件。如把标准输入输出设备键盘和显示器看作为输入输出文件,其文件名(又称设备名)为con。向它输出信息时,con指显示器,从它输入信息时,con指键盘。由于键盘和显示器都是字符设备,所以,文件con为字符格式文件。,无论是文本文件还是二进制文件,在访问它之前,都要定义一个文件流类的对象,并用该对象打开它,以后对该对象的访问操作就是被它打开的文件的访问操作。对文件操作结束后,再用该对象关闭它。,对文件的访问操作包括输入和输出两种: 输入是指从外部文件向内存变量输入数据,实际上是系统先把文件内容读入到该文件的内存缓冲区里,然后再从该缓冲区中取出数据赋给相应变量,用于输入操作的文件称为输入文件。 输出是指把内存变量或表达式的值写入到外部文件中,实际上是先写入到该文件的内存缓冲区中,待缓冲区满后,再由系统一次写入到外部文件中,用于输出操作的文件称为输出文件。 (输入和输出都是相对于内存变量而言),在程序中使用文件时,需要用#include命令,用它所提供的ifstream(输入文件流类),ofsream(输出文件流类),fstream(输入输出文件流类)来定义所需的文件流对象。,9.3.2文件流对象对象的建立,每个文件流类都有一个open成员函数,并且具有完全相同的声明格式,具体声明格式为: void open(const char *fname,int mode); fname参数用于指向要打开的文件,是一个文件名字符串,可以带有盘符和路径,mode参数用于指定打开文件的方式,对应的实参是ios类中定义的open_mode枚举类型的枚举常量或这些枚举常量按位或的表达式,具体含义参见P321,定义文件流对象并打开文件举例,(1)ofstream fout; fout.open(“a:xxk.dat”); 首先定义了一个输出文件流fout,使系统为其分配一个文件缓冲区,然后调用open成员函数打开a盘上的xxk.dat文件,由于调用的成员函数省略了打开方式参数,所以采用ofstream类的默认打开方式ios:out,即打开文件只用于数据输出,只向它写入数据。执行这个调用时,若文件a:xxk.dat存在,则清除该文件的内容,使之成为一个空文件,若该文件不存在,则就在a盘上建立一个名为xxk.dat的空文件。通过fout打开这个文件后,以后对fout对象的输出操作就是对a:xxk.dat的操作。,(2)ifstream fin; fin.open(“a:wr.dat”,ios:in|ios:nocreate);,首先定义了一个输入文件流对象fin,并使其在内存中得到一个文件缓冲区,然后采用ifstream的默认打开方式ios:in打开a盘上的xxk.dat文件,若该文件不存在则不建立新文件,使打开该文件的操作失败,此时,fin带回的值为0,由(!fin)是否为真判断打开文件是否失败。,(3)ofstream ofs; ofs.open(“a:xxk.dat”,ios:app);,首先定义了一个输出文件流对象ofs,同样在内存得到一个缓冲区,然后打开文件a:xxk.dat,并规定以追加数据方式打开文件,即不破坏原有文件的内容,只允许向尾部写入新数据。,每一种文件流类中,既定义了无参构造函数又定义了带参构造函数,并且所带参数与open函数的参数完全相同。当定义一个带有实参表的文件流对象时,将自动调用相应的带参构造函数,打开第一个实参所指向的文件,并规定按第二个实参所给的打开方式进行操作。所以它同先定义不带参数的文件流对象,后通过流对象调用open成员函数打开文件的功能完全相同。,上述四例的等价语句如下:,(1)ofstream fout(“a:xxk.dat”); (2) ifstream fin(“a:wr.dat”,ios:in|ios:nocreate); (3)ofstream ofs(“a:xxk.dat”,ios:app); (4)fstream ofs(“a:abc.ran”,ios:in|ios:out|ios:binary);,每个文件流类中都提供了一个关闭文件的成员函数close(),当打开的文件操作结束后,需要关闭它,使文件流与对应的物理文件断开联系,并能够保证最终输出到文件缓冲区中的内容,无论是否已满,都将立即写入到对应的物理文件中。文件流对应的文件被关闭后,还可以利用该文件流调用open成员函数打开其它的文件。 关闭任何一个流对象对应的文件,就用这个流对象调用close成员函数即可。 如,fout.close();就关闭了流对象fout对应的a:xxk.dat文件。,(4)fstream fio; fio.open(“a:abc.ran”,ios:in|ios:out|ios:binary);,首先定义了一个输入输出文件流对象fio,同样在内存得到一个缓冲区,然后按输入和输出方式打开二进制文件a:abc.ran。此后,既可以按字节向该文件写入信息又可以从该文件读出信息。,文本文件的访问操作,C+文件包括字符文件和字节文件两种类型,对它们的访问操作各不相同。 对字符文件的访问操作包括向字符文件顺序输出数据和从字符文件顺序输入数据这两个方面。所谓顺序输出就是依次把数据写入到文件的末尾(当然文件结束符也随之后移,它始终占据整个文件空间的最后一个字节位置),顺序输入就是从文件开始位置起依次向后提取数据,直到碰到文件结束符为止。,(1) 向字符文件输出数据 向字符文件输出数据有两种方法,一种是调用从ostream流类中继承来的插入操作符重载函数,另一种是调用从ostream流类中继承来的put成员函数。它们的声明格式如下: ostream,例1. 向a盘上的wr1.dat文件输出020之间的整数,含0和20在内。 #include #include #include void main(void) ofstream f1(“a:wr1.dat“); if (!f1) /当f1打开失败时进行错误处理 cerr“a:wr1.dat file not open!“endl; exit(1); for(int i=0;i21;i+) f1i“ “; /向f1文件流输出i值 f1.close(); /关闭f1所对应的文件 ,例2. 把从键盘上输入的若干行文本字符原原本本地存入到a盘上wr2.dat文件中,直到从键盘上按下Ctrl+z组合键为止。此组合键代表文件结束符EOF。 #include #include #include void main(void) char ch; ofstream f2(“a:wr2.dat“); if (!f2) /当f1打开失败时进行错误处理 cerr“File of a:wr2.dat not open!“endl; exit(1); ch=cin.get(); /从cin流中提取一个字符到ch中 while(ch!=EOF) f2.put(ch); /把ch字符写入到f2流中,此语句也可用f2ch代替 ch=cin.get(); /从cin流中提取下一个字符到ch中 f2.close(); /关闭f2所对应的文件,例3. 假定一个结构数组a中的元素类型pupil包含有表示姓名的字符指针域name和表示成绩的整数域grade,试编写一个函数把该数组中的n个元素输出到字符文件“a:wr3.dat”中。 #include #include void ArrayOut(pupil a, int n) ofstream f3(“a:wr3.dat“); if (!f3) /当f3打开失败时进行错误处理 cerr“File of a:wr3.dat not open!“endl; exit(1); for(int i=0; in; i+) endlai.gradeendl; f3.close(); ,(2) 从字符文件输入数据 从打开的字符文件中输入数据到内存变量有三种方法。 一种是调用提取操作符重载成员函数,每次从文件流中提取用空白符隔开的一个数据,这同使用提取操作符从cin流中读取数据的过程和规定完全相同,在读取一个数据前文件指针自动跳过空白字符,向后移到非空白字符时读取一个数据。 第二种是调用get()成员函数,每次从文件流中提取一个字符(不跳过任何字符,当然回车和换行两个字符被作为一个换行字符看待)并作为返回值返回,或者调用get(char&)成员函数,每次从文件流中提取一个字符到引用变量中,同样不跳过任何字符。 第三种是调用getline(char* buffer, int len, char=n)成员函数,每次从文件流中提取以换行符隔开的一行字符到字符指针buffer所指向的存储空间中。,上述介绍的在istream流类中的每个成员函数的声明格式分别如下: istream 在通常情况下,若一个文件是使用插入操作符输出数据而建立的,则当作输入文件打开后,应使用提取操作符输入数据;若一个文件是使用put成员函数输出字符而建立的,则当作输入文件打开后,应使用get()或get(char&)成员函数输入字符数据;若每次需要从一个输入文件中读入一行字符时,则需要使用getline成员函数。,例4. 从例1所建立的a:wr1.dat文件中输入全部数据并依次显示到屏幕上。 #include #include #include void main(void) ifstream f1(“a:wr1.dat“, ios:in | ios:nocreate); /定义输入文件流,并打开相应文件,若打开失败则f1带回0值 if (!f1) /当f1打开失败时进行错误处理 cerrx) /依次从文件中输入整数到x, /当读到的是文件结束符时条件表达式的值为0 coutx ; coutendl; f1.close(); /关闭f1所对应的文件 该程序运行结果如下: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20,例5. 从例2所建立的a:wr2.dat文件中按字符输入全部数据,把它们依次显示到屏幕上,并且统计出文件内容中的行数。 #include #include #include void main(void) ifstream f2(“a:wr2.dat“, ios:in | ios:nocreate); if (!f2) cerr“a:wr2.dat file not open!“endl; exit(1); char ch; /用ch读入字符 int i=0; /用i统计行数 while(f2.get(ch) /依次从文件中输入字符到c

温馨提示

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

评论

0/150

提交评论