第七章C的IO流库首都师范大学.ppt
《第七章C的IO流库首都师范大学.ppt》由会员分享,可在线阅读,更多相关《第七章C的IO流库首都师范大学.ppt(149页珍藏版)》请在三一办公上搜索。
1、第八章 C+的 I/O 流库,C+为什麽要建立自己的输入输出系统?1 C 虽然具有一个灵活和功能强大的输入输出系统,但它并不支持自定义类型。例如:class account char name30;double balance;public:account();account(char*,double);,account acnt;scanf(“%account”,/错误,不支持 account 类型 因为输入函数 scanf 和输出函数 printf 的格式串形参 只能与系统预定义类型匹配,而无法识别用户的自 定义类型,并且也不能通过重载定义 scanf 和 printf 函数的新版本,使它
2、们的格式串形参能匹配任意用 户自定义类型。,2 面向对象程序设计必须定义众多的用户自定义类,如何以面向对象的设计原则和方法为自定义类设计 既规格统一,又适应个性化的输入输出操作行为是 十分必要的。因此 C+必须建立一个能通过对输入 输出操作重载的方法实现对任意自定义类型对象输 入输出支持的系统。,本章要点1 C+流库结构流库的概念、流库的组成。2 标准输入输出流输入输出流类的定义、输入输出运算符、输入输出的格式控制。3 自定义类的输入输出输入输出运算符的重载。4 文件的输入输出流文件的打开、关闭和读写。5使用 MFC 的对话框类实现输入输出,8.1 C+流库结构8.1.1 流库的概念 流(st
3、ream)是从源(数据的生产者)到目标(数据的使用者)被传输数据的引用。每个流都是一个与某种数据传输设备相关联的对象。流具有方向性:输入流是与输入设备(如键盘)关联的流。输出流是与输出设备(如显示器屏幕)关联的流。输入输出流是与输入输出设备(如磁盘)关联的流。,C+中包含的预定义流:cin 输入流,与输入设备关联。cout 输出流,与输出设备关联。cerr 非缓冲型错误信息流,与错误输出设备关联;clog 缓冲型错误信息流,与错误输出设备关联。在缺省情况下,指定的输入设备是控制台键盘,输出设备是控制台显示器终端。在任何情况下,指定的错误输出设备总是控制台显示器终端。,cin 和 cout 的使
4、用方法我们已经很熟悉了。cerr 和 clog 均是用来输出错误信息,它们的使用方法与 cout 基本相同,只不过它们所关联的设备始终是控制台显示器,而不随着 cout 关联设备的改变而变化。cerr 和 clog 之间的区别是:cerr 对输出的错误信息不缓冲,因而发送给它的任何内 容都立即输出。clog 输出的错误信息被缓冲,当缓冲区满时才进行输 出,也可以通过刷新流的方式(遇到操纵符 endl 或 flush)强迫刷新缓冲区导致显示输出。,下面给出一段使用预定义输入输出流信息的程序:cout sales;cout num;if(num=0)cerr The average can not
5、 be computed.n;else avgsales=sales/num;cout The average selling price per nuit was;cout avgsales n;,C+流库是用面向对象的设计方法建立起来的输入输出类库,它具有两个平行的根基类 streambuf 和 ios,库中所有其他的类均从它们直接或间接派生。系统中预定义流,cin、cout、cerr、clog 都是流库中相应类的对象。,8.1.2 streambuf 类 streambuf 类是流库的根基类,它为输入输出物理设 备提供缓冲区和流处理的一些通用方法。C+将输入输出流均视为字节流,因此缓冲区
6、是由 一个字符串和两个指针组成的。这两个指针分别指 向数据流在输入缓冲区中的插入位置和在输出缓冲 区的提取位置。streambuf 类提供对缓冲区的底层操作,例如设置缓冲区、对缓冲区指针进行操作、从缓冲区取字节、向缓冲区存储字节等。streambuf 类有三个派生类,filebuf 类、strstreambuf 类和 conbuf 类。它们的派生层次关系如图所示:,filebuf 类扩展了 streambuf 类的功能,用于文件流与 文件缓冲区相关联,实现对文件缓冲区中的字节序 列的读写操作:写文件:缓冲区内容按字节写到指定的文件中,然后刷新缓冲区。读文件:指定文件内容按字节读到缓冲区中。打开
7、文件:filebuf 与被读或写的文件相关联。,streambuf,关闭文件:filebuf 与被读或写的文件解除关联。strstreambuf 类扩展了 streambuf 类的功能,提供了将 内存作为输入输出设备时,进行提取和插入操作的 缓冲区管理。conbuf 类扩展了 streambuf 类的功能,用于控制台显 示器输出缓冲区关联和管理,提供光标控制、颜色 设置、活动窗口定义、清屏、行清除等屏幕控制功 能(注意,这些屏幕控制功能在有些编译器版本中 不提供,例如 visual C+)。通常情况下,对设备缓冲区的操作一般使用上述三 个派生类,很少直接使用基类 streambuf。,8.1.
8、3 ios 类 ios 类及其派生类为用户提供使用流的接口,该类具有一个 streambuf 类型指针指向流的缓冲区。ios 类及其派生类对象通过该指针使用 streambuf 及其派生类对象完成输入输出时的格式化或非格式化转换,并检查输入输出的错误。ios 是流库中的另一个根基类,它有四个直接派生类:输入流类 istream:class istream:virtual public ios;输出流类 ostream:class ostream:virtual public ios;,文件流类 fstreambase:class fstreambase:virtual public ios;字
9、符串流类 strstreambase:class strstreambase:virtual public ios;这四个派生类成为流类库中的基本流类,它们又组合派生出以下的流类:输入文件流类 ifstream:class ifstream:public istream,public fstreambase;输入字符串流类 istrstream:class istrstream:public istream,public strstreambase;输出文件流类 ofstream:class ofstream:public ostream,public fstreambase;,输出字符串流类
10、 ostrstream:class ostrstream:public ostream,public strstreambase;控制台输出流类 constream:class constream:public ostream;输入输出流类 iostream:class iostream:public istream,public ostream;输入输出文件流类 fstream:class fstream:public iostream,public fstreambase;输入输出字符串流类 strstream:class strstream:public iostream,public
11、strstreambase;,从上述的 istream、ostream 和 iostream 又分别派生出具有赋值运算符“=”重载的新类:带赋值的输入流类 istream_withassign:class istream_withassign:public istream;带赋值的输出流类 ostream_withassign:class ostream_withassign:public ostream;带赋值的输入输出流类 iostream_withassign:class iostream_withassign:public iostream;上述流类的派生层次结构如下图所示。,ios,
12、系统预定义流 cin、cout、cerr 和 clog 在系统头文件iostream.h 中被定义:extern _CRTIMP istream_withassign cin;extern ostream_withassign _CRTIMP cout;extern ostream_withassign _CRTIMP cerr;extern ostream_withassign _CRTIMP clog;显然,用户也可以用 istream 和 ostream 等流类定义自己的流对象,例如:istream is;ostream os;对预定义类型数据的输入输出操作已经定义为流类的操作,而对用户
13、自定义类型对象的输入输出操作则可以通过重载运算符“”和“”得以实现。,Java 的 I/O 流类在构造和使用上与 C+有一些有趣的差别:1 C+的 I/O 流类库是把所有的输入输出功能封装在 数量相对较少的几个流类中,自定义类则是通过重 载机制使得流类对象能够对自定义类对象进行输入 输出操作。而 Java 则几乎为每一种情况提供了一个独立的类。例如,底层的字节流操作类、按数据类型划分的各 种高级操作类,对底层 I/O 包装后进行某种特定操 作(如 Unicode 读写)的类,随机读写操作类,数 组读写类等等。,2 C+的流在缺省情况下是进行缓冲的,但 Java 的流 在缺省情况下是不缓冲的。但
14、可以调用提供了缓冲 功能的类对一个 Java 的流进行缓冲。3 在 Java 中,所有的整数和浮点数都是以大端字节顺 序进行输入输出的,与底层平台无关。这与 C+中 的情况不同,因此 Java 所产生的数据文件的可移植 性更高。,4 在典型的 C+程序中,字符均使用 ASCII 编码形式 表示(无论是单独使用的字符还是字符串中的字 符)。这与字符从输入设备读入或写到输出设备都 保持 ASCII 编码形式是一致的。一个典型的 Java 程序中,字符始终是用两个字节的 Unicode 形式表示的。当从输入设备读入 ASCII 编码 形式的字符时,必须先转换为 Unicode 形式后再写 入内存;当
15、将 Unicode 形式字符写到输出设备时,必须先转换为 ASCII 编码形式后再写入输出设备。Java 的流类的层次结构如下图所示:,OutputStream,InputStream,返回,Writer,Reader,8.2 标准输入输出流8.2.1 输入输出流类定义 istream 类和 ostream 类在流库中分别提供基本的标准输入输出操作,是使用流库的主要接口,在系统头文件 iostream.h 中,它们的类定义分别如下:class istream:virtual public iospublic:istream(streambuf*);/构造函数/从输入流中将字符读取到给定指针 c
16、har*指向的内存,直/至遇到分界符、文件结束符或读至(len-1)个字符为止。istream,/从输入流读取字符到给定的 streambuf,直至遇到分界符。istream,/从读入流读取给定数目的字符到 char*指向的内存空间。/如果发生错误时,getcount 函数可得到实际读入的数目。istream,/按给定偏移 streamoff(typedef long streamoff)移动输入/文件指针,指示偏移方向的枚举值 ios:seek_dir 的取值:/beg=从文件开始;cur=从当前位置;end=从文件尾。istream/对系统所有的预定义类型都给出了的重载定义。;,class
17、 ostream:virtual public iospublic:ostream(streambuf*);/构造函数ostream,streampos tellp();/返回输出流中当前指针位置。/可重载的输出运算符ostream,8.2.2 输入输出运算符的使用8.2.3 格式控制的输入输出输入输出的格式控制可以使得人机交互界面更加友好、美观。在 C 程序中,输入输出是使用 C 运行库的 scanf 和 printf 函数完成的,输入输出的格式是通过这两个函数的格式描述串参数控制的。在 C+程序中,虽仍然可以使用 scanf 和 printf 函数,但在面向对象的程序设计中,输入输出是使用
18、流类库中的输入输出流完成的,因此输入输出的格式控制必须使用流类库提供的格式控制的方法:使用 ios 类的格式控制成员函数;使用被称为格式操纵符的特殊函数。,1 用 ios 类成员函数进行输入输出格式化 ios 类提供了用于输入输出格式控制的成员函数。这些函数进行格式控制的方法是修改以下属性:格式标志属性 x_flags:标志的不同状态值指定输入输出数据的不同格式(如对齐规则、数值转换基、数字表示规则等)。输出域宽属性 x_width:指定输出数据所占显示区域的宽度。填充字符属性 x_fill:指定输出显示域中数据为占空间的填充字符;输出精度属性 x_precision:指定浮点数输出的小数部分
19、显示位数。,格式标志C+中每个流对象的输入输出格式都是依据指定格式进行的,也就是说,流对象的每次输入“”操作是按照当前格式标志 x_flags 中的格式状态完成的。该属性是一个 protected 成员,在类外访问该属性是通过公有的格式控制成员函数实现的。注意,该属性可以在 ios 的派生类内被访问。为了便于提供格式控制成员函数的参数和参数具有良好的可读性,ios 类定义了一个公有的无名枚举数据成员,用户可以使用这些特定的枚举元素,形成所需要的格式状态传递给相应的格式控制成员函数。,class _CRTIMP ios public:enum skipws=0 x0001,/跳过输入中的空白,用
20、于输入 left=0 x0002,/左对齐输出,用于输出 right=0 x0004,/右对齐输出,用于输出 internal=0 x0008,/符号或基数指示符与数字之间添加填充符,用于输出 dec=0 x0010,/基数为 10 进制,用于输入输出 oct=0 x0020,/基数为 8 进制,用于输入输出 hex=0 x0040,/基数为 16 进制,用于输入输出,showbase=0 x0080,/显示基数指示符,用于输出 showpoint=0 x0100,/显示小数点,用于输出 uppercase=0 x0200,/16 进制输出时,数基指示符和/数值中的字母一律为大写,用于输出 s
21、howpos=0 x0400,/正数前显示+符号,用于输出 scientific=0 x0800,/科学表示法浮点数,用于输出 fixed=0 x1000,/定点形式显示浮点数,用于输出 unitbuf=0 x2000,/输出后立即刷新流,用于输出。stdio=0 x4000,/刷新 stdout 和 stderr,用于输出。;inline long flags()const;/返回当前格式标志。,inline long flags(long _l);/设置指定格式 _l,返回原有格式。inline long setf(long _f,long _m);/依据掩码 _m 设置指定格式 _f,返
22、回原有格式。inline long unsetf(long _l);/清除指定格式 _l,并返回原有标志。inline int width()const;/返回当前域宽值。inline int width(int _i);/设置指定域宽 _i,并返回原有域宽值。inline ostream*tie(ostream*_os);/将流连接到_os 指向输出流,并返回原来的流指针。inline ostream*tie()const;/返回原来的流指针。,inline fill()const;/返回当前填充字符。inline char fill(char _c);/设置指定填充字符,并返回原有填充字符
23、。inline int precision(int _i);/设置指定浮点数精度,并返回原有浮点数精度。inline int precision()const;/返回当前的浮点数精度。inline int rdstate()const;/返回当前的错误状态。inline void clear(int _i=0);/根据掩码 _i 设置或清除错误状态位。protected:,long x_flags;int x_precision;char x_fill;int x_width;,格式枚举元素值有一个共同的特点,即使用不同位为 1 二进制数表示不同的格式值,也就是说,枚举元素值的二进制表示只有一
24、位为 1。例如:skipws0 x0001:0000 0000 0000 0001left0 x0002:0000 0000 0000 0010right0 x0004:0000 0000 0000 0100显然,所需要的特定格式标志将可以是一个枚举元素值或几个的枚举元素进行或运算组合而成,例如,欲设置左对齐 10 进制科学表示法显示浮点数的输出格式,则格式标志可以通过ios:left|ios:dec|ios:scientific得到,16 进制值为 0 x0812,10 进制值为 2066。,用成员函数对格式标志进行操作 置格式标志 所谓设置格式标志是将格式属性 x_flags 的某 一位置
25、1,使该位所对应的格式标志有效。设 置格式标志的成员函数是 setf,调用该成员函 数的一般形式为:流对象.setf(ios:格式标志值);例如:istream isobj;ostream osobj;isobj.setf(ios:skipws);osobj.setf(ios:left);,注意:isobj 和 osobj 为 istream 和 ostream 的用户定 义对象。在编程中使用最多的是通过系统预 定义流对象设置格式,例如:cin.setf(ios:skipws);cout.setf(ios:left);所设置的格式标志不改变格式属性 x_flags 的 原有的有效位,即在原有基
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第七 IO 首都师范大学
链接地址:https://www.31ppt.com/p-5638262.html