收藏 分享(赏)

c++第十四章.ppt.ppt

上传人:hwpkd79526 文档编号:9119180 上传时间:2019-07-24 格式:PPT 页数:42 大小:247.50KB
下载 相关 举报
c++第十四章.ppt.ppt_第1页
第1页 / 共42页
c++第十四章.ppt.ppt_第2页
第2页 / 共42页
c++第十四章.ppt.ppt_第3页
第3页 / 共42页
c++第十四章.ppt.ppt_第4页
第4页 / 共42页
c++第十四章.ppt.ppt_第5页
第5页 / 共42页
点击查看更多>>
资源描述

1、第14章 输入/输出流类库,输入/输出:程序与计算机外设之间的数据交换。 输入:程序从外设接收数据。 输出:程序将数据输出到外设。 C+语言本身没有专门的输入/输出语句,但C+的编译系统通常都提供输入/输出流类库,用于用户输入/输出。,14.1 概述 14.2 基本I/O流类体系 14.3 标准设备的输入/输出 14.4 重载提取和插入运算符 14.5 文件 14.6 综合应用举例作业:4,8,11,12,14.1 概述 流,数据的输入/输出以字节为单位,依次逐个进行。 数据的字节序列称为字节流,简称流(Stream)。按对字节内容的解释方式分,字节流分为字符流(也称文本流)和二进制流。 字符

2、流:将字节流的每个字节按ASCII字符解释。数据传输时需做转换,效率较低,但字符流可直接编辑、显示或打印,字符流文件通行于各类计算机。 例如int型数值1234567在内存中占4字节,但输出前要先转换成数值串“1234567”后,才能输出。反之亦然。 源程序文件和文本文件都是字符流。 二进制流:将字节流的每个字节按二进制方式解释。数据传输时不做转换,效率高,但异类计算机对数据的二进制存放格式存在差异,且无法人工阅读,二进制流文件可移植性较差。 输入/输出流的类体系称为流类,流类的实现称为流类库。,文件,文件:相关数据的字节序列集合。 计算机中的程序、数据、文档常以文件形式存于外存。 输入/输出

3、设备具有字节流特征,也是文件。例如键盘是输入文件,显示器、打印机是输出文件。 不同的文件所允许的操作可能不同。例如对于磁盘文件,可以将数据写入文件,也可以将数据从文件中取出;而对于打印机文件,只能将数据写入,而不能从打印机文件中取出数据。 文件名:为文件取的名字,以区别不同的文件。 文件名通常由使用标识符,但不同的计算机系统,对文件名的组成规则有所不同,参见有关操作系统。 程序可通过文件名来使用文件。,缓冲,缓冲区:系统在主存中开辟的、用来临时存放输入/输出数据的区域。如先将输入的数据送到缓冲区,再从缓冲区中取出。 缓冲区的作用:因输入/输出设备的速度比CPU慢得多,若CPU直接与外设交换数据

4、,必然占用大量CPU时间,降低CPU的使用效率。使用缓冲后,CPU只要从缓冲区中取数据或者把数据写入缓冲区,而不必等待外设的具体输入/输出操作,显著提高了CPU的使用效率。 按在缓冲区中是否立即处理,流分为缓冲流和非缓冲流。常用缓冲流,仅在特殊场合,才用非缓冲流。 非缓冲流:一旦数据送入缓冲区,立即处理。 缓冲流:仅当缓冲区满或当前送入的数据为新的一行字符时,系统才对流中的数据进行处理(称为刷新)。,14.2 基本I/O流类体系 概述,基本I/O流类体系:如图所示,在iostream.h中说明,支持C+输入/输出程序设计。,类istream:类ios的公有派生类,提供输入操作。 类ostrea

5、m:类ios的公有派生类,提供输出操作。 类iostream:由类istream和ostream公有派生,并未增加新成员,以支持输入和输出操作。 类ios:类istream和ostream的虚基类,提供流的格式化输入/输出和错误处理,并通过指向类streambuf的对象的指针成员来管理流缓冲区。 类streambuf:管理流缓冲区。 实际编程时,常用类ios、istream、ostream和iostream提供的公有接口成员函数来输入/输出。,预定义的标准流与提取和插入运算符,预定义的标准流对象:cin、cout、cerr和clog。 需在程序中包含头文件“iostream.h”方可使用。 c

6、in为标准输入流,缺省代表键盘。 cout为标准输出流,缺省代表显示器。 cerr和clog为标准错误信息输出流,缺省代表显示器。 cerr为非缓冲流,其余为缓冲流。 提取运算符:用于从流中提取一个字节序列。 插入运算符:用于向流中插入一个字节序列。 cin使用提取运算符实现数据的输入,其余三个标准流使用插入运算符实现数据的输出。 输入流自动将要输入的字节序列形式的数据变换成计算机内部形式的数据(二进制数或ASCII)后,再赋给变量,变换后的格式由变量的类型确定。输出流自动将要输出的数据变换成字节序列后,送到输出流中。,例14.1 使用流cerr和clog实现数据的输出。 #include v

7、oid main(void) float a,b;cerrab;if(b!=0) couta/b=a/bn;else cerr“除数为零!n“; cout、cerr和clog的用法相同但作用不同。 cout的输出可重定向(请参见有关操作系统的介绍)。 cerr和clog的输出不可重定向。 clog为缓冲流,输出的数据不能及时显示。 通常将程序中的提示信息(输入提示和出错提示等)用cerr输出,结果数据用cout输出,而clog很少使用。,流的格式控制,格式化输入/输出仅用于文本流,而二进制流是原样输入输出,不必做格式化转换。“iomanip.h”中预定义了13个格式控制函数,用于控制输入/输出

8、数据的格式,如下表所示。,例14.2 用格式控制函数指定输出数据的域宽和数制。 #include #includevoid main(void) int a=256,b=128;cout setw(8) a“b=“bn;cout hex a“b=“ dec bn; ,指定变量a按十六进制输出,b按十进制输出。 注意,hex、dec、oct的设置是互斥的,一旦设置,一直有效,直到下一次设置数制为止。,指定输出变量a的域宽为8,变量b仍按缺省的域宽输出。 注意,setw设置的域宽仅对其后的一次插入有效。,流的错误处理,state是类ios中说明的整型数据成员,用于记录输入/输出操作的状态,它的有关

9、二进制位的含义由ios类中说明的公有枚举类型io_state声明的枚举常量来描述。 公有枚举类型io_state的声明:enum io_state goodbit =0x00, /输入/输出操作正常eofbit =0x01, /已到达文件尾failbit =0x02, /输入/输出操作出错badbit =0x04, /非法输入/输出操作hardfail=0x80 /无法恢复的错误;,类ios中读取I/O状态的成员函数:int rdstate(); /读取I/O状态字。int bad(); /若非法操作,返回非零,否则返回0。void clear(int=0);/清除流中的错误,参数缺省值为0。

10、int eof(); /若到文件尾,返回非零,否则返回0。int fail(); /若I/O错,返回非零,否则返回0。int good(); /若I/O正常,返回非零,否则返回0。 若仅清除输入流状态字中的某位,可用clear()函数。如:cin.clear(cin.rdstate() 在I/O操作后,应检测是否发生I/O错误。若发生I/O错误,则应在处理错误之后,清除流中的错误标志,以便进行后续I/O操作。但对I/O错误处理不当可能导致程序不能正常运行。,例14.3 输入不正确的数据时,导致程序出错。 #include void main(void) int i,s;couti;s=cin.

11、rdstate();couti;s=cin.rdstate();cout“num=“in; ,现象:程序运行时,若输入字符或字符串将产生死循环。 原因:从输入流提取数值时,若发现是非数字字符(串),则不提取,仅置非法I/O操作标志位。尽管在while循环中清除了错误状态位,但并未清除输入流中原有字符(串)。再次输入整数时,又是原有字符(串),产生死循环。,解法:在L行增加语句:while(cin.get()!=n); 以清除输入流中的原有字符(串)。,14.3 标准设备的输入/输出,基本类型数据分为三类: 字符 字符串 数值(整数、实数和双精度数) 基本类型数据的输入由类istream多次重载

12、“”运算符实现。 基本类型数据的输出由类ostream多次重载“”运算符实现。,基本类型数据的输入,使用cin输入基本类型的数据时应注意: 当用户输入的数据送到缓冲区中,仅当输入一行的结束符(Enter键)时,才提取数据;只有把输入缓冲区中的数据提取完后,才开始新的输入。 在缺省情况下,空格作为输入数据之间的分格符,在输入的数据之间可以用一个或多个空格分开。但输入字符给字符变量时,空格算字符。 输入数据的类型必须与提取数据的变量类型一致,否则会出现错误。若程序中没有相应的出错处理程序,则导致计算结果不正确。 在输入数据时,换行符(Enter键)有两个作用:一是,告知系统,输入到缓冲区中的数据可

13、以提取;二是,从输入流中提取数据时,作为空格字符处理。,字符和字符串的输入,输入字符的成员函数:int istream:get();/提取一个字符,并作为返回值。常用。istream功能:从输入流提取一个字符串(但不提取结束字符),并复制到第一个参数所指存储区。其中,第二个参数为至多提取的字符个数(指定值为n时,至多提取n-1个字符,尾部增加一个字符串结束符0),第三个参数为输入字符串的结束字符(缺省值为换行符)。这三个函数并不常用。,提取一个字符,并赋给字符型引用参数,输入字符串的成员函数:istream功能:与前三个函数相似,区别在于它们从输入流中提取的字符串包括结束字符(若实际提取的字符

14、个数小于第二个参数指定的字符个数),复制到第一个参数所指存储区的字符串不包括结束字符。比较常用。,基本类型数据的输出,标准输出流cout、cerr和clog可输出各种基本类型的数据。 标准输出流输出整数时,缺省的设置为:数制为十进制、域宽为0、数字右对齐、以空格填充。 标准输出流输出实数时,缺省的设置为:精度为六位小数、浮点输出、域宽为0、数字右对齐、以空格填充。当输出的实数的整数部分超过七位或有效数字在小数点右边第四位之后时,则转换为科学计数法输出。 输出字符或字符串时,缺省的设置为:域宽为0、字符右对齐、以空格填充。 域宽为0的含义是按数据的实际占用的字符位数输出,在输出的数据之间没有空格

15、。,字符的输出,类ostream中输出字符的成员函数: ostream 对于标准输出流,通常只有cout和clog需要用flush()强制刷新输出流的缓冲区。,14.4 重载提取和插入运算符,因标准流只能直接输入/输出基本类型的数据,故自定义类型的数据只有转化成基本类型的数据后才可使用标准流。 直接输入/输出类类型的数据,需重载“”运算符。 重载提取运算符的格式: friend istream,返回值类型必须是istream&,以便连续做“”运算。,左操作数类型,右操作数类型,或为ClassName,返回值类型必须是ostream&,以便连续做“”运算。,左操作数类型,右操作数类型,或为Cla

16、ssName,因左操作数非本类ClassName的对象,故该运算符只能重载为类的友元。,例14.4 重载提取和插入运算符,直接输入/输出对象。 #include class Money int Dollar,Cents; public: friend ostream ,istream ,程序的一次运行结果: 输入两个整数:100 25 ¥100元 25分,说明:此处类型不可改为istream。 原因:执行“return is;”语句时,无法调用istream类的访问权限为protected的赋值运算符重载函数。,14.5 文件 概述,按对字节内容的不同解释,将文件分为: 文本文件(ASCII码

17、文件):每个字节为字符。 二进制文件:每个字节为二进制数据。 自定义文件流对象的用法: 先用文件流对象打开文件,使文件流对象与指定文件挂钩; 后用文件流对象对文件做读/写数据等操作; 不再使用指定文件时,应使用文件流对象及时关闭已打开的文件,使文件流对象与指定文件脱钩。 注意自定义文件流对象与预定义标准流对象在使用上的异同。,文件流类:ifstream:输入文件流类,实现文件输入。ofstream:输出文件流类,实现文件输出。fstream :输入/输出文件流类,实现文件输入/输出。 文件流使用举例: 说明一个文件流对象,如:ifstream infile(“myfile1.txt“);ofs

18、tream outfile;fstream iofile; 用文件流对象的成员函数open或构造函数打开文件,如:outfile.open(“myfile2.txt“); 用提取、插入运算符或其它成员函数对文件读/写,如:infilech; 不再使用指定文件时,应及时关闭文件,如:infile.close();,文件的打开,用文件流类的成员函数open打开文件: void ifstream:open( const char* , int=ios:in, int=filebuf:openprot ); void ofstream:open( const char* , int=ios:out,

19、int=filebuf:openprot ); void fstream:open( const char* , int, int=filebuf:openprot );,指定打开的文件名(可含盘符和路径):如“d:t1.dat”。,指定文件的打开方式: 输入文件流的缺省值为ios:in:按输入文件方式打开文件。 输出文件流的缺省值为ios:out:按输出文件方式打开文件。 输入输出文件流没有缺省的打开方式,在打开文件时应指明。,指定打开文件的保护方式:缺省值与filebuf:sh_compat相同。 filebuf:sh_compat:共享 filebuf:sh_none:独享 filebu

20、f:sh_read:读共享 filebuf:sh_write:写共享,文件的打开方式:用ios类中定义的公有枚举类型open_mode中的枚举常量来描述。enum open_mode in=0x01, /输入(读)方式out=0x02, /输出(写)方式ate=0x04, /添加方式,文件指针最初指向文件尾app=0x08, /追加方式,文件指针始终指向文件尾trunc=0x10, /截断文件方式nocreate=0x20, /不建文件方式noreplace=0x40,/不替换文件方式binary=0x80 /二进制方式; 因每种打开方式都用一个二进位表示,故在不矛盾的情况下,可用运算符“|”

21、(二进制按位或)将多种打开方式组合使用。,文件打开方式说明 不以binary方式打开的文件,都是文本文件。 输入文件仅可用in、nocreate和binary及其组合打开。 文件指针从0开始连续编号(0代表文件头),以字节为单位,用于指示文件的读/写位置,文件每读/写一个字节,文件指针就后移一个字节。文件指针的初值由文件打开方式指定,若文件打开方式含app或ate,则文件指针指向文件尾,否则指向文件头,如:,用文件流类的构造函数打开文件 文件流类ifstream、ofstream和fstream的构造函数所带参数与各自的成员函数open()所带参数完全相同。因此,在说明这三种文件流类的对象时,

22、通过调用各自的构造函数,也能打开文件。 读方式打开文件ifstream f1(“file1.dat“,ios:in|ios:nocreate); 写方式打开文件ofstream f2(“file2.txt“); 读方式打开文件fstream f3(“file3.dat“,ios:in|ios:nocreate);,文件打开与否的判别 文件打开后,应判断打开是否成功。若不成功,则后续的文件读/写操作就没有实际意义。 举例ifstream f2;f2.open(“file.dat“,ios:in|ios:nocreate);if( !f2 ) cout“不能打开输入文件:file.datn“; e

23、xit(1); ,因在ios类中重载了取反运算符“!”:int ios:operator!() return fail(); 这样,若文件打开成功,则“!f2”为0,否则“!f2”为非0。 此处亦可直接写成:f2.fail() 此处也可用文件流类的成员函数is_open(),写成:f2.is_open()=0,文件的关闭,在撤消文件流对象时,由系统自动调用文件流对象的析构函数关闭文件。 用文件流对象的成员函数close()关闭文件,例如:ifstream infile(“f1.dat“);inflile.close(); /关闭文件f1.dat 文件流类的成员函数close()的原型:void

24、 ifstream:close();void ofstream:close();void fstream:close(); 及时关闭文件的好处: 及时释放所占资源; 使一个文件流对象可分时与多个文件关联; 使有限的可同时打开的文件总数得到充分利用。,功能:把文件缓冲区的数据写入文件,释放所占资源,切断文件流对象与文件的关联。,文本文件的使用,文件流类ifstream、ofstream和fstream并未直接定义文件操作的成员函数。 对文件的操作通过调用其基类ios、istream、ostream中的成员函数实现。 对文件流对象的基本操作与标准输入/输出流的操作相同,即可通过提取运算符“”和插入

25、运算符“”来读写文件。,例14.5 复制源文件到目标文件中。 #include #include void main(void) char ch,f1256,f2256;coutf1;coutf2;ifstream in(f1,ios:in|ios:nocreate);ofstream out(f2);if(!in) coutch )outch; ,取消提取运算符跳过文件中空白符的缺省设置。因文件复制必须包含空白符。,inch操作的返回值为in,成为while语句的条件。因不是基本类型数据,无法直接运算,除非做类型转换。 ios类仅重载了一个类型转换函数:operator void*( ) r

26、eturn fail( ) ? 0 : this; ,问:可否用while(!in.eof() inch;outch; 代替左边的代码?,隐式类型转换:(void*)in fail()?0:this,或,while(in.get(ch)outch;,问:本程序为何能复制任意类型的文件?,例14.6 设文本文件data.txt中有若干实数,每个实数之间用空格或换行符隔开。求出文件中的这些实数的平均值。 #includevoid main(void) float sum=0,t;int count=0;ifstream in(“data.txt“,ios:in|ios:nocreate);if(!

27、in) coutt) /依次读一个实数sum+=t,count+;cout“n平均值=“sum/count“,count=“count; ,设data.txt文件的内容为:24 56.9 33.7 45.688 99.8 20 50 程序运行结果:平均值=52.25,count=8,二进制文件的使用,用二进制文件方式读写数据时,数据不做变换,直接传送。 二进制文件的读写操作: 使用读写字符的文件流的成员函数(如例14.5); 使用文件流的成员函数read()和write()。 成员函数read()的原型:istream功能:将t所指内存的前n字节数据写入二进制文件。,例14.7 将150之间的

28、所有偶数存入二进制文件data.dat中。 #include #includevoid main(void) ofstream out(“data.dat“,ios:out|ios:binary);if(!out) cout“不能打开data.datn“; exit(1);for(int i=2;i50;i+=2)out.write( (char*) ,将整型指针转换成字符型指针,以符合该函数第一个参数类型的要求。,例14.8 从例14.7产生的数据文件data.dat中读取二进制数据,并按每行10个数的形式显示。,#includevoid main(void) int i,a; ifstre

29、am in(“data.dat“,ios:in|ios:binary|ios:nocreate);if(!in) cout“不能打开文件data.datn“; return; for(i=1; in.read(char*) ,函数调用分析: 读sizeof(int)个字节数据送a; 返回的文件流对象in做for语句的表达式2,无法直接运算,除非转换转换成基本类型的数据。 对象in的唯一类型转换函数“void*”将in隐式转换成基本类型的数据做为for语句的表达式2参加运算。见例14.5。,作用:读4个字节数据送a,若输入出错(包括文件结束)则返回零,否则为非零。,文件的随机读写,顺序读写:按先

30、后顺序读/写文件中的数据,如前所述。 随机读写:从文件的任何指定位置读/写数据,主要用于二进制文件。随机读写的前提是移动文件指针。 移动输入流文件指针的成员函数:istream,streampos和streamoff与long同型。 pos和off指定文件指针相对于参考点的移动值。若为负值,则前移,否则后移。文件头为前,文件尾为后。,seek_dir是ios类中定义的公有枚举类型:enum seek_dir /参考点 beg=0 , /文件头cur=1, /当前位置end=2 /文件尾; dir指定文件指针移动的参考点。,文件指针移动举例:设有二进制输入文件流对象ff.seekg(-50,io

31、s:cur); /文件指针从当前位置前移50个字节f.seekg(50,ios:cur); /文件指针从当前位置后移50个字节f.seekg(-50,ios:end);/文件指针从文件尾前移50个字节注意:在移动文件指针时,必须保证移动后的指针值大于等于0且小于等于文件尾字节编号,否则将导致后续读/写出错。 移动输出流文件指针的成员函数:ostream /输出流功能:返回当前文件指针值(相对于文件头)。 随机文件的读写分两步: 先将文件指针移到开始读写的位置; 再用文件读写函数读或写数据。,例14.9 将5100之间的奇数存入二进制文件,然后再将文件中的第2029之间的数依次读出并输出。 #i

32、nclude void main(void) int i,x;ofstream out(“d.dat“,ios:out|ios:binary);if(!out) cout“不能打开文件d.datn“; return; for(i=5;i100;i+=2)out.write(char*) ,14.6 综合应用举例,例14.10 下列程序显示并保存2,1000内的所有素数。显示、保存素数的格式为:每行10个素数,每一素数占7个字符位置,右对齐。最后一行不足10个素数时按一行输出。 #include #include #include typedef unsigned long UL;class CPrime/定义求解start,end内所有素数的类 protected:UL start,end; /endstart1int IsPrime(UL i);/若 i 是素数则返回1,否则返回0 public:CPrime(UL s=2ul,UL e=1000ul);UL /设置/取得start,UL ,ostream /向文件流对象f输出2,1000内的所有素数 ,

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报