1、流类库,C+流库 流:数据从源(数据的生产者)到漏(数据的消费者)的流动。流库:为完成输入输出工作而预定义的类的集合,这些类构成一个层次结构的系统 输出:将一个对象的状态换成一个字符序列,输出到某个地方。向“流”中添加数据 输入:从某个地方接收到一个字符序列,将其转换成一个对象的状态所要求的格式。从“流”中获取数据,流类库,流类库的基类:streambuf和ios类,所有的流类都是从它们直接或间接派生出的 streambuf类:负责缓冲区的处理。缓冲区由一个字符序列和两个指针组成,指针分别指向字符将被插入或被取出的位置。,filebuf:能够处理文件。把filebuf同某个文件的描述字相联系称
2、为打开该文件。 strstreambuf:提供了在内存中进行提取和插入操作的缓冲区管理。 conbuf:能处理输出,为输出操作提供缓冲区管理。,流类库,ios类:提供了使用流类的接口,都有一个指向streambuf的指针。ios是一个虚基类,定义了用于格式化输入输出及出错处理的成员函数。,ios类派生出4个类: 输入流(istream)针对系统全部的预定义类型重载了输入运算符“”,该类提供了流的大部分输入操作 输出流(ostream)针对系统全部的预定义类型重载了输入运算符“”,该类提供了流的主要输出操作: 文件流(fstreambase):提供了文件流的公共操作 串流(strstreamba
3、se):专门处理串流,流类库,4种基本流类组合派生出实用流: 输入/输出流(iostream): 输入/输出文件流(fstream): 输入/输出串流(strstream): 屏幕输出流(constream): 输入文件流(ifstream): 输出文件流(ofstream): 输入串流(istrstream): 输出串流(ostrstream): 例:iostream是通过多重继承从输入流类istream和输出流类ostream派生而来的。支持双向操作。class ios;class istream:virtual public ios;class ostream:virtual publi
4、c ios;class iostream:public istream,public ostream;,在istream、ostream、iostream类的基础上重载“=”,产生istream_withassign、ostream_withassign和 iostream_withassign,流类库,流类库,执行C+程序时,系统自动打开几个预定义流,用户在程序中直接使用 iostream.h:标准I/O流头文件,在该文件中对各个流类定义了各自的全局对象。 cin:是istream_withassign类的对象,称为标准输入流,缺省为键盘 cout:是ostream_withassign类的
5、对象,称为标准输出流,缺省为显示器 cerr和clog:是ostream_withassign类的对象,称为标准错误输出流,固定关联到显示器。cerr没有被缓冲,因而发送给它的任何内容都立即输出;相反clog被缓冲了,只有当缓冲区满时才输出,预定义类型的输入输出,输入运算符:双目运算符,有两个操作数,左操作数是istream类的一个对象,右操作数既可以是一个预定义类型的变量,也可以是重载了该运算符的类对象,缺省时:运算符跳过空白符,然后读入与输入变量类型相对应的值。因此,给一组变量输入值时可用空格或换行把键入的数值间隔开。int n;float x; cinnx;,当输入字符串时:运算符跳过空
6、白符,读入以下的非空白字符,直到遇到另一个空白字符为止,并在串尾放一个字符0。char *str; cinstr; 输入:object programming! 则:str=“object”,预定义类型的输入输出,不同类型的变量一起输入时,系统除检查是否含有空白符外,还完成输入数据与变量类型的匹配 int n; float x; cinnx; 输入:35.78 89.25 则:n=35 x=.78,输入运算符采用左结合方式工作,并返回它的左操作数。,预定义类型的输入输出,输出运算符:双目运算符,有两个操作数,左操作数是ostream类的对象,右操作数既可以是一个预定义类型的变量,也可以是重载了
7、该运算符的类对象,运算符:采用左结合方式工作,并且返回它的左操作数。 使用进行输出操作时,编译程序根据出现在运算符右边的变量的类型决定调用重载该运算符的哪个版本,运算符的重载,:重载格式为ostream operator(cout ,a),为复数类型重载,#include class complexprivate:float Re,Im;public:complex(float r=0,float i=0)Re=r;Im=i;friend ostream ,为复数类型重载,#include class complexprivate:float Re,Im;public:complex(floa
8、t r=0,float i=0)Re=r;Im=i;friend istream,输入1 2 3 4(注意不能输入1,2,3,4逗号不是间隔),a=?,运算符的重载,istream 相当于为istream类重载输入运算符,格式控制,格式控制方法: 使用ios类中有关格式控制的成员函数 使用称为控制符的特殊类型函数 用ios类成员函数控制格式 在ios类中说明了数据成员long x_flags,存放控制输入输出格式的状态标志,每个状态标志占一位。 设定了某个状态标志,则x_flags中对应位为1,否则为0,可以几个标志并存 例:对于12.0,如未置showpoint位,则输出12,若置此位,输出
9、12.000000,格式控制,用成员函数操作状态标志,设置状态标志setf,原型:long ios:setf(long flags); 使用:stream_obj.setf(ios:scientific); 其中:stream_obj多为cin、cout 设置多个标志时,彼此用或运算符|分隔 例:cout.setf(ios:dec|ios:scientific);,清除状态标志unsetf,原型:long ios:unsetf(long flags); 作用:把指定的状态标志位置0,即清除指定的状态标志,取状态标志flags,原型:long ios:flags();long ios:flags
10、(long flags); 作用:取状态标志,操作状态标志的成员函数举例,#include void showflags(long f) long i;for(i=0x8000;i;i=i1)if(i ,格式控制,设置域宽,原型:int ios:width();返回当前的域宽值int ios:width(int wid);设置域宽,并返回原域宽 特点:设置的域宽仅对下一个流输出操作有效,当一次输出操作完成后,域宽恢复为0,设置填充字符:当输出值不足以填满域宽时用该字符来填充,原型:char ios:fill();返回当前的填充字符char ios:fill(char c)用参数c重新设置填充字
11、符, 并返回填充前的字符,设置显示精度,原型:int ios:precision();返回当前的显示精度int ios:precision(int num)用参数num重新设置显 示精度,并返回设置前的显示精度,上述成员函数举例,#include void main() cout“default width is”cout.width()“n”;cout“default fill is”cout.fill()“n”;cout“default precision is”cout.precision()“n”;cout666“ “123.45678“n”;cout.precision(3); co
12、ut.width(8); cout666“ “123.45678“ “456.78“n”;cout“current width is”cout.width()“n”;cout“current precision is”cout.precision()“n”;coutfill(*); cout.width(8);cout666“ “123.45678“n”; ,default width is0 default fill is default precision is6 666 123.457666 123 457 current width is0 current precision is3
13、*666 123,格式控制,结论: 缺省域宽为0;缺省的填充字符为空格;缺省的输出精度为0,即按数据的实际精度输出 设置了显示精度后,若数据的实际精度与设置的精度不一致,则输出方法如下: 实际精度大于设置精度时,四舍五入后按设置的精度输出;实际精度小于设置的精度时,按实际精度输出 设置域宽后,只对其后最接近它的第一个输出有影响,第一个输出完成后系统立即把域宽置0,用控制符控制格式,ios类的成员函数控制输入输出格式时,必须由流对象来调用它们,且不能把它们直接嵌入到输入输出语句中。 控制符:类似于函数的运算符。用一个流引用作为参数,并返回同一个流的引用 标准控制符: dec:设置十进制转换基格式
14、标志 hex:设置十六进制转换基格式标志 oct:设置八进制转换基格式标志 ws:提取空白字符,仅用于输入 endl:插入换行符并刷新流,仅用于输出,用控制符控制格式,sesetiosflags(long f):清除由参数f指定的格式位,用于输入输出 setfill(int c):设置填充字符,对于右对齐输出,填充左面;对于左对齐输出填充右面。一次设置多次有效。用于输入输出 setprecision(int n):设置浮点数精度为n,用于输入输出 setw(int n):设置域宽为n,只对下一次的输出操作有效。用于输入输出 上述控制符在iostream.h中定义,控制符函数在iomanip.h
15、中定义,使用控制符函数时必须包含这两个头文件,控制符和控制符函数举例,#include #include void main() cout123setw(5)45688“n”;cout123setw(5)setfill(*)456setw(5)88“n”; ,123 45688 123*456*88,控制符和控制符函数举例,#include #include void main() float v1=1360.53;float v2=300.23;float v3=84430.23;coutsetiosflags(ios:showpoint|ios:fixed)setprecision(2)s
16、etfill(*)setiosflags(ios:right);cout“nCheck Value:$ “setw(10)v1;cout“nCheck Value:$ “setw(10)v2;cout“nCheck Value:$ “setw(10)v3; ,Check Value:$ *1360.53 Check Value:$ *300.23 Check Value:$ *84430.23,用户自定义控制符,用途: 当要对预先未定义的设备进行操作时,定义自己的控制函数能使得对这类设备的操作变得方便 当多次重复使用几个相同的控制符时,可以把这些控制符合并在一个控制函数中,以便于用户使用 为输
17、出流定义控制函数的格式为:ostream 调用时只要直接写出自定义控制符的名字:manip_name,文件操作方式,文件:C+把文件当成字符序列。按照数据的组织形式,可把文件分成ASCII文件和二进制文件 ASCII文件:每个字节放一个ASCII代码,表示一个字符,使用方便但占用的存储空间较多。缺省时文件以正文方式打开,即在输入时回车/换行序列转换成字符n,输出时字符n转换成回车/换行序列 二进制文件:把内存中的数据按其在内存中的存储形式原样写到外存储器中。二进制文件可以节省外存空间,但它的一个字节不对应一个字符 打开文件:进行文件的输入输出,首先建立一个文件流,把该流和实际的文件相关联 关闭
18、文件:取消文件和流的关联 文件流:输入文件流、输出文件流、输入/输出文件流,面向文件的流类,fstream.h:“文件流”头文件,在该文件中对各个文件流类进行了定义,但是没有预定义各自的全局对象。因为,在C+ 中文件类不是标准设备,不能预先定义。 在头文件fstream.h中给出了fstreambase、ifstream、ofstream、fstream类的定义。fstreambase是ifstream和ofstream的公共基类,fstream是ifstream和ofstream的派生类,都是公有继承关系 执行文件输入输出前的三件事: 在程序中包含头文件fstream.h 建立文件流,即说明
19、面向文件流类的对象 打开文件,即是使某个文件和某以文件流相关联。(文件名和文件的打开方式是传递给构造函数的实参),创建文件流时,需要使用面向文件的流类的构造函数。每个面向文件的流类都有四个重载的构造函数,?fstream():创建一个未打开的文件流 ?fstream(const char*,int mode,int prot=filebuf:openprot):创建一个打开的文件流 第一个参数指定与此文件流相关联的文件的名字 第二个参数mode决定文件的打开方式 app:追加数据 ate:文件指针移到文件尾 in:以输入方式打开文件 out:以输出方式打开文件 binary:二进制方式打开文件
20、 trunc:文件存在清除原有内容 nocreate:文件不存在失败 noreplace:文件存在失败 第三个参数决定文件的保护方式: 0 普通文件;1 只读文件;2 隐含文件;4 系统文件;8 备份文件,面向文件的流类,面向文件的流类,创建ifstream类对象时,缺省的mode值为ios:in; 创建ofstream类对象时,缺省的mode值为ios:out; 未显式指明以二进制方式打开文件,则缺省的方式为文本方式;,?fstream(int fd):创建一个打开的文件流,并把它链接到文件柄为fd的文件 ?fstream(int fd,char *buf,int len):创建一个打开的文
21、件流,并把它链接到文件柄为fd的文件 close函数:关闭与该流对象相链接的文件,并清除流的错误状态 open(const char *name,int mode,int prot=filebuf:openprot)函数:打开名为name的文件,例:建立一个输入输出文件流both,把它链接到文件data.dat上,并清除原有的文件内容 fstream both; both.open(“data.dat”,ios:in|ios:out|ios:trunc); fstream both(“data.dat”,”ios:in|ios:out|ios:trunc);,文件的读写文本文件,文本文件的读写
22、:使用输入运算符和输出运算符 例:把一个整数、浮点数、字符串写到文件data中,#include #include main() ofstream out(“data”);if(!out)cout“can not open file data.”;return 0; out256“ “198.69“ “C+ Languagen”; out.close(); return 1; ,文件的读写二进制,二进制文件的读写:使用istream类的公有成员函数get(char &)和ostream类的公有成员函数put(char) 例:在屏幕上显示任何文件的内容,#include #include main(int argc,char *argv) char ch;ifstream in(argv1);if(!in)cout“Cannot open file”;return 1;while(!in.eof() in.get(ch);coutch;return 0;,