流类库流类库
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8.1 C++基本I/O流库的层次结构
在C++程序中,数据可以从键盘流到程序,也可以从 程序流向屏幕或磁盘文件。从流中获取数据的操作称为 提取操作,向流中添加数据的操作称为插入操作,数据 的输入/输出应通过IO流实现。每个流是一种与设备相联 系的对象,在默认情况下,指定的标准输入设备指键盘, 指定的标准输出设备指显示终端(屏幕)。 程序设计中经常需要在设备之间传送数据。例如, 把某些数据从内存输出到显示屏,把某些数据从内存传 送到某个文件中,把从键盘输入的数据传送到内存,把 从键盘输入的数据传送到某个文件中,把某个文件中的 数据传送到内存,等等。这些都属于设备之间的数据传 送。 大部分数据的传送是以内存为一方,以某个输入/输 出设备为另一方的。通常把目的地为内存的数据传送称 为输入,把源地为内存的数据传送称为输出。
8.3 文件的I/O操作
8.1 C++基本I/O流库的层次结构
8.1.1 I/O流类的概念 输入/输出是每一个程序的必须具备的基本功能。输 入(Input)是指数据从外部输入设备传送到计算机内存的 过程;输出(Output)是指将程序运算结果从计算机内存传 送到外部输出设备的过程。 IO是一种基本的数据传递操作,它可以理解为字符 序列在计算机内存与外设之间的 流动。C++将数据从一 个对象到另一个对象的流动抽象为流(Stream) ,将实现 设备之间交 换信息的类称为流类,按面向对象方法组织 的多个流类及其类层次集合构成了I/O流类库, 简称为流 库。在流库中的每一个流类都定义了一种设备之间的信 息交换方式。按信息流动方向的不同,可以分为输入流 和输出流:与输入设备(如键盘)相联系的流称为输入流, 与输出设备(如屏幕)相联系的流称为输出流;与输入/输 出设备相联系的流称为输入/输出流。
8.2 I/O格式控制 取状态标志重载了两个成员函数,其函数原 型分别为 long ios::flags() const; long ios::flags(long flags); 第一个成员函数的功能为返回当前流的状态 标志位数值;第二个成员函数的功能为设置指定 位的状态标志,并返回设置前的状态标志位数值。
8.1 C++基本I/O流库的层次结构
8.1.2 ios类的层次关系 程序设计中,大部分情况下都使用以ios类为基类的 类层次。ios类是一个抽象类,但ios类的派生类都是对象 类。用户通过定义ios类层次中某个派生类的对象,就可 以使用该对象所属的类,以及这些类的父类、父父类提 供的各种公有成员函数,实现各种形式数据的传送。ios 的层次模型图如图8-1所示。
8.2 I/O格式控制
【例8.1】 分别用十进制格式、十六进制格式和科学 计数法格式输出三个数。 程序的输出结果如下: count = 432 state = 4d2 x = 5.555500e+002
8.2 I/O格式控制
2.精度、域宽、填充字符的设置 精度用于控制处理结果的输出精度。ios类中重载了 两个设置精度的成员函数: int ios::precision(); int ios::precision(int n); 其中,第一个成员函数用于返回当前的输出精度; 第二个成员函数用于设置输出精度为n位。 域宽用于控制输出格式。ios类中重载了两个设置域 宽的成员函数:
8.1 C++基本I/O流库的层次结构
图8-1 iso类层次结构
8.1 C++基本I/O流库的层次结构
8.1.3 streambuf类的层次关系 streambuf类及其派生类主要完成数据通过缓冲区的 交换。所谓缓冲区,就是内存中数据的一个中转存放地。 缓冲区通常比较大,这样,在数据发出地和数据目的地 之间附加的缓冲区就可以解决数据交换设备速度相差过 大造成的资源浪费问题,并可方便数据传送时的格式控 制。 streambuf类为所有的 streambuf类层次对象设置了 一个固定的内存缓冲区,该内存缓冲区能动态地划分成 用作输入的取区和用作输出的存区,这两个区可以重叠 也可以不重叠。取区定义了一个指示当前取字符位置的 取指针,存区定义了一个指示当前存字符位置的存指针。
8.2 I/O格式控制
表8.1 无参数操作符及其功能
操作符
功能 选择I/O十进制格式化标志 插入换行符并刷新输出缓冲流
dec
endl ends flush hex oct ws
插入空字符
刷新输出缓冲流 选择I/O十六进制格式化标志 选择I/O八进制格式化标志
从输入流中提取空字符
8.2 I/O格式控制
8.2 I/O格式控制
2.有参数操作符 有参数操作符实现了复杂的输入/输出格式控制。表 8.2给出了有参数操作符及其功能。
表8.2 有参数操作符及其ห้องสมุดไป่ตู้能
操作符 resetionflag(long n) setbase(int n) setfill(int c) setionflags(long n) setprecision(int n) setw(int n)
8.1 C++基本I/O流库的层次结构
图8-2 streambuf
8.2 I/O格式控制
8.2.1 ios类成员函数的格式控制 ios类是所有ios类层次的基类,ios类中提供了所有派 生类中都需要的流的状态设置、状态报告成员函数,以 及精度、域宽设置等的成员函数。ios类在头文件ios.h中。 1.状态设置和状态报告 ios类中定义了控制输入/输出格式的状态标志。状态 标志共15个,每个状态标志占一个二进制位,每个二进 制位称做一个格式状态位。格式状态位的值由ios类中定 义的下列枚举数值表示:
8.2 I/O格式控制
enum { skipws left right internal dec oct hex showbase showpoint uppercase showpos scientific fixed unitbuf stdio }; = 0x0001, = 0x0002, = 0x0004, = 0x0008, = 0x0010, = 0x0020, = 0x0040, = 0x0080, = 0x0100, = 0x0200, = 0x0400, = 0x0800, = 0x1000, = 0x2000, = 0x4000 //跳过输入中的空白字符 //输出左对齐 //输出右对齐 //在输出符号数制字符后填充字符 //将数据按十进制处理 //将数据按八进制处理 //将数据按十六进制处理 //输出时带有表示数制基的字符 //输出浮点数时总是带小数点 //输出十六进制时所有字母均用大写 //输出正整数时加“+” //用科学计数法输出浮点数 //用定点数方式输出实数 //每次插入后立即刷新流 //插入后立即刷新stdout和stderr
8.2 I/O格式控制
8.2.2 操作符的格式控制 操作符是一种功能和成员函数类同,但使用更为便 捷的语言成分。由于操作符都返回引用类型,因此操作 符可以连用。用户在程序中使用操作符既可以简化程序 编写,又可以使程序结构变得更加清晰。 C++语言中有两种操作符:一种是无参数操作符;一 种是有参数操作符。操作符定义在文件iomanip.h中。 1.无参数操作符 无参数操作符实现了常用的输入/输出格式控制;表 8.1给出了无参数操作符及其功能。
中82io格式控制操作符功能dec选择io十进制格式化标志endl插入换行符并刷新输出缓冲流endsends插入空字符插入空字符表81无参数操作符及其功能flush刷新输出缓冲流hex选择io十六进制格式化标志oct选择io八进制格式化标志ws从输入流中提取空字符82io格式控制例82计数法格式输出三个数
8.1 C++基本I/O流库的层次结构
filebuf类在streambuf类的基础上增加了文件处理功 能。filebuf类使用文件来保存缓冲区中的字符序列。当写 文件时,把缓冲区中的字符序列写到某个指定文件中; 当读文件时,把某个指定文件中的字符序列读到缓冲区 中。 strstreambuf类在streambuf类的基础上增加了动态 内存管理功能。strstreambuf类实现从内存到缓冲区的信 息交换和从缓冲区到内存的信息交换,从而可以在计算 机内存之间交换数据信息。 stdiobuf类主要用于C++语言的流类层次方法和C语 言的标准输入/输出方法混合使用时系统的缓冲区管理。 streambuf类的层次关系如图8-2所示。
8.2 I/O格式控制
该语句将把状态标志的hex对应位设置为1。由于枚 举数值hex是在ios类中定义的,因此参数要写成ios::hex。 当一次要设置多个状态标志位时,用逻辑或符号(||) 连接要设置的状态标志位。例如,下边的例子输出时状 态标志设置位为dec和scientific: float v = 5640000000000; cout.setf(ios::dec || ios::scientific); cout << v << endl; ios类中还提供了清除状态标志和取状态标志的成员 函数。清除状态标志的函数原 型为 long ios::unsetf(long flags); 该成员函数的功能是把指定位的状态标志设置为0。
8.2 I/O格式控制
说明: (1) 符号0x表示十六进制。如果设置了某个状态标志 位,则对应位为1,否则为0。例如,dec = 0x0010就表 示状态标志的二进制数为0000000000010000。 (2) 允许同时有一个以上的状态标志位为1。例如, 0x0011就表示skipws为1和left为1。 ios类中定义了设置状态标志的成员函数setf(),其函 数原型为: long ios::setf(long flags); 该成员函数的功能为把指定位的状态标志设置为1。 例如,若要输出为十六进制数,则可在输出语句前 加如下语句: cout.setf(ios::hex);
面向对象程序设计
第8章 流类库
8.1 C++基本I/O流库的层次结构
C++语言中的流类主要由两个流类结构组成:一个是 以streambuf类为基类的类层次;另一个是以ios类为基 类的类层次。streambuf类及其派生类主要完成信息通过 缓冲区的交换;ios类及其派生类在streambuf类实现的 缓冲区信息交换的基础上,增加了各种格式化的输入/输 出控制方法。ios类使用streambuf类(以及它的派生类)功 能的方法,是在ios类中定义了一个保护权限的指向 streambuf类的指针。 程序设计中,大部分情况下都使用以ios类为基类的 类层次。ios类是一个抽象类,但ios类的派生类都是对象 类。用户通过定义ios类层次中某个派生类的对象,就可 以使用该对象所属的类,以及这些类的父类、父父类提 供的各种公有成员函数,实现各种形式数据的传送。
8.2 I/O格式控制
int ios::width(); int ios::width(int n); 其中,第一个成员函数用于返回当前的域宽值;第 二个成员函数用于设置域宽为n位。 填充字符用于控制输出样式。系统默认的填充 字符为空格,也可设置用户希望的填充字符。ios类中重 载了两个设置填充字符的成员函数: char ios::fill(); char ios::fill(char c); 其中,第一个成员函数用于返回当前的填充字符值; 第二个成员函数用于设置填充字符为c。
【例8.2】 分别用十进制格式、十六进制格式和科学 计数法格式输出三个数。 程序中,hex和dec分别是设置十六进制和十进制的 操作符。hex操作符的函数体定义如下: ios& hex(ios& o) { o.setf(ios::hex); return o; } dec操作符的函数体定义和hex操作符的类同。由于 操作符的返回值是引用类型,因此可以在一行内连续使 用。
功能 清除n指定的格式化标志 设置以n表示的整型基数 (0-10为十进制) 设置以c表示的填充字符 设置n指定的格式化标志 设置以n表示的数值精度 设置以n表示的I/O域宽
8.2 I/O格式控制
【例8.3】 设计一个有参数操作符使用方法的例子。 程序运行的结果为: PI = 3.141592654 17 k=f d = ****324.57 程序中D行表示:域宽共10位,数值精度为5位,其 余位填充字符 '*'。因此,输出结果的最后一行为“d = ****324.57”。