8-1IO类
iostream定义用于读写流的基本类型
fstream定义读写命名文件的类型
sstream定义读写内存string对象的类型
为支持宽字符的语言,标准库定义了一组类型和对象来操纵wchar_t类型的数据
宽字符版本的类型和函数的名字以w开头
IO类型间的关系
概念上,设备类型和字符大小都不会影响我们要执行的IO操作
用>>读取数据时,我们不用管从哪里读取,也不用管输入的字符是存在char对象内,还是存在char_t对象内
通过继承机制,我们可以忽略不同类型的流之间的差异
继承机制使我们可以将一个派生类(继承类)对象当作其基类(被继承类)来使用
例如:
1、IO对象无拷贝和赋值
因为不能拷贝和赋值,IO对象也不能用于形参或返回值
2、条件状态
如果输入了字符串,读操作就会失败,其后续的IO操作都会失败
确定一个流状态最简单的方法是把它当成条件使用
查询流的状态
将流作为条件使用,只知道流是否有效,不知道其具体原因
IO库定义了一个与机器无关的iostate类型它提供了表达流状态的完整功能。这个类型应作为一个位集合来使用
badbit表示系统级错误,如不可恢复的读写错误。一旦badbit被置位,流就不能使用了
发生可恢复错误后,failbit被置位。错误可修正,流还可以继续使用
如果到达文件结束位置,eofbit和failbit都会被置位
goodbit的值为0,表示流未发生错误
如果badbit、failbit、eofbit被置位,则检测流状态的条件会失败
管理条件状态
clear不接受参数的版本会将所有的错误标志位复位
clear接受一个iostate的版本,表示流的新状态
rdstate读出当前条件状态,然后用位操作将需要复位的位复位,来生成新的状态
3、管理输出缓冲
每个输出流都有一个缓冲区,用来保存读写的数据
刷新输出缓冲区
操纵符endl:换行并刷新缓冲区
操纵符fiush:刷新缓冲区,并不输出额外的字符
操纵符ends:向缓冲区插入一个空字符,然后刷新缓冲区
unitbuf操纵符
unitbuf操纵符告诉流接下来的每一次写操作之后都会进行一次fiush操作
nounitbuf操纵符负责重置流,使流使用正常系统管理的刷新缓冲区机制
关联输入和输出流
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作,都会使输出流刷新
标准库将cin和cout关联在一起,cin>>i;这条语句会使cout的缓冲区被刷新
tie有两个版本:
不带参数的版本返回指向输出流的指针,如果这个对象关联到了一个输出流,则返回指向这个流的指针;如果未关联到流,则返回空指针
带参数的版本接受一个指向ostream的指针,将自己关联到这个ostream
x.tie(&o);表示将流x关联到输出流o
每个流最多关联到一个流,但多个流可以同时关联到一个ostream
8-2文件输入输出
和cin、cout一样,<<、>>、getline在这里都适用
1、使用文件流对象
我们想读写一个文件时,可以定义一个文件流对象,并将对象与文件流关联起来
每个文件流类都定义了一个open成员函数,它视情况打开为读或写的模式
定义了一个输入流in,并打开了文件iFile
定义了一个输出流out,它未与任何文件关联
用fstream代替iostream&
接受一个iostream引用(或指针)类型的参数的函数,可以用对应的fstream(或sstream)来调用
成员函数open和close
如果定义了一个空文件流对象,可以用open将它与文件关联
如果调用open失败,则failbit会被置位
一旦一个文件流已经打开,它会保持与对应文件的关联
调用open失败后,随后的试图使用文件流的操作都会失败
为了将文件流关联到另一个文件,首先要关闭已关联的文件
自动构造和析构
input在每次循环中都要创建和销毁一次
当fstream离开其作用域时,与之关联的文件会自动关闭
2、文件模式
每个流都有一个关联的文件模式,用来指出如何使用文件
以out模式打开文件会丢弃已有数据
默认情况下,我们打开一个ofstream文件时,文件的内容会被丢弃
阻止一个ofstream清空给定文件内容的方法是同时显式地指定app模式或in模式
每次调用open时都会确定文件模式
8-3string流
使用istringstream
我们的某些工作是对整行文本进行处理,面对处理行内的单个单词的工作时,可以考虑使用istringstream
有一个文件,它保存人们的联系方式,这些人可能有一个或多个电话号码,例如:
定义一个类来描述它