8.1 面向对象的标准库
C++所提及的父类被称为基类(base class),而继承而来的类侧成为派生类(derived class)
IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于读写存储在内存中的string对象。
流的特性:1.国际字符的支持 2.IO对象不可复制或者赋值,注意只有可以复制的类型才可以储存在vector之类的容器中,所以流对象是不能使用容器的。
8.2 条件状态
IO便准库管理一系列的条件状态(condition state)成员,用来标记给定的IO对象是否处于可用状态,或者碰到了那种特定的错误。
以下的strm代表三个流对象
strm::iostate 这是一个机器相关的整型名,这个变量根据各个iostream类定义,用于定义条件状态,它包含三个状态位
strm::badbit 用于指出被破坏的流,strm::failbit 用于指出失败的IO操作,strm::eofbit 用于指出六已经到达该文件的结束符
下面的方法用于取得或者处理上面的几个状态位:
s.eof() 是否到达结尾,这个是通过去读iostate的状态得到的,到达结尾的时候,iostate会被设置为eofbit,以下同
s.fail() 是否失败
s.bad() 是否被破坏
s.good() 是否正常有效
s.clear() 清除iostate所有的三个状态位
s.clear(flag) 清除 flag的状态位比如 s.clear(strm::failbit)可清除失败标志位
s.setstate(flag)设置flag代表的状态位,如果要设置多个状态位,可以用按位或的方式来设置
s.rdstate() 返回当前流的状态位
8.3 输出缓冲区的管理
每个IO对象都管理着一个缓冲区,用于储存程序读写的数据
1.输出缓冲区的刷新
有三个操纵符(manipulator)可以控制缓冲区的刷新
endl会输出一个换行符并且刷新缓冲区
ends会插入空字符NULL,并且刷新缓冲区
flush是最常用的操纵符,会不在输出中添加任何字符,然后刷新缓冲区
2.unitbuf操纵符会在每次执行完写操作后都刷新流的缓冲区,比如
cout<<unitbuf<<"1"<<"2"<<nounitbuf
注意使用玩unitbuf后要调用nounitbuf,流才会恢复成正常的,由系统来管理的缓冲区刷新
3.将输入和输出绑在一起
是用tie可以把输入和输出绑在一起,这样的结果是可以保证任何输出,包括给用户的提示,都在试图读出之前输出,具体用法
cin.tie(&cout); //把cout和cin绑定
ostream * old_tie=cin.tie();//把这个绑定储存
cin.tie(0); //解除绑定
cin.tie(&cerr);//把cin和cerr绑定
..
cin.tie(0);//把cin和cerr的绑定解除
cin.tie(old_tie);//绑定之前的绑定
8.4 文件的输入和输出
ifsream读取文件,ofstream写入文件,fstream读写同个文件
8.4.1文件流对象的使用
注意,fstream使用的文件名传入参数是C风格字符串而不是string
fstream file("anyfile");
1.打开文件后一定要检查文件是否打开成功
if(!file)
{
cerr<<"Unable to open file";
}
2可以通过close和open重新绑定文件与流
3.在用一个对象多次打开文件的时候,注意用clear清除流的状态
8.4.2 文件模式
打开文件时,无论是调用open或者是以文件名作为流初始化的一部分,都需指定文件模式。这些模式如下
in 读文件操作
out 写文件操作 要注意的是,以out模式打开的话,文件会被清空,并且丢弃文件之前储存的所有数据
app 每次写之前都会跳转到文件尾,追加
ate 打开文件后立即将文件定位到文件尾
trunc 打开文件时清空已存在的文件流
binary 以二进制方式进行IO读写
注意,这些模式可以同时指定,但是有些组合是没有意义的
8.4.3 一个打开并检查输入文件的程序
8.5 字符串流
1.字符串流对象的使用
2.字符串流提供的转换或者格式化
int a=20;
int b=30;
stringstream str;
str<< "a="<<a<<" b="<<b<<endl;
这时候str的内容是 a=20 b=30.