1. IO类
不同头文件包含了读写不同对象的类型。
上述的io类型都继承自同一个类型,即istream,因此可以像使用istream一样使用上述io类型。比如可以沿用>>,<<,getline
对不同类型的对象进行操作而无需区分具体类型。
1.1 IO对象无拷贝和赋值
2.1 条件状态
流一旦发生错误,后续的IO操作都会失败。因此在使用一个流之前应该检查它是否在无错状态。
将流作为判断条件只能得出流是否有效的结论,无法告诉我们到底发生了什么。
机器无关的iostate类型:IO库定义了四个iostate类型的常量表达式,具有不同的位情况,表示流的不同状态,可使用位运算符对该类型进行置位检测或者设置多个标志位。以如下方式使用那些常量表达式:
if(cin.rdstate() == ios::goodbit)
四个iostate类型的常量表达式:
badbit
:系统级错误,不可恢复,流不可使用。同时会置位failbit。
failbit
:可恢复错误。如读入和期望值不同的数据。可以修正,流还可以继续使用。
eofbit
:到达文件结束位置。注意会同时置位failbit和eofbit。
以上三个值任何一个被置位,检测流状态都会失败。
goodbt
:值为0,表示未发生错误。
通常只需要检查failbit
的情况就可以判断当前流状态。
管理条件状态:
流对象的rdstate成员返回一个iostate类型的值,对应当前流状态。
setstate置位给定条件位,表示发生了对应错误。
clear成员有两个重载的版本:不接收参数版本和接受iostate参数的版本。不接收参数的版本清除所有错误标志位。带参数的版本直接将流状态置为参数的位状态。
2.2 管理输出缓冲
缓冲机制:将多个输出操作组合为单一的对设备写操作。当刷新缓冲区时,数据才真正写到设备。
刷新缓冲区的情况:
1.程序正常结束,即程序return
之后;
2.缓冲区满时。
3.使用操作符endl
;
4.使用操纵符unitbuf
设置流内部状态。cerr
对象可用于设置unitbuf
,因此cerr
都是立刻输出的。
5.一个输出流可能被关联到另一个流。如cin和cerr都被关联到cout,所以当读cin或者写cerr时都会刷新cout的缓冲区。
可用tie函数完成输入输出流的关联。tie有两个重载的版本,一个无参数的版本,返回指向输出流的指针,如果当前对象关联到了一个输出流,则返回该输出流的指针,如果没有关联到流,则返回空指针。一个有参数的版本,接收一个指向输出流的指针,将自己关联到该输出流。同时返回当前关联到的流指针。示例如下:
刷新缓冲区的操作:
如果不想每次输出时都要加上刷新缓冲区的操作,可以使用uintbuf
:
一个好习惯就是在打印调试信息时经常刷新缓冲区。
3. 文件输入输出
创建文件流时,可以选择指定文件名或者不指定文件名,如果提供了文件名**,会自动调用文件流类的open成员函数**。否则需要显式通过open成员函数把空的文件流对象和文件关联起来。
如果open函数失败,failbit会被置位。对一个关联了文件的文件流执行open会报错,failbit置位,随后对该文件流的操作会失败,要想让该文件流重新关联文件,必须先关闭已经关联的文件。open成功后,iostate会被置为goodbit;
在要求使用基类的地方可以用继承类型的对象来代替。fstream继承自iostream,所以某些需要iostream类型的参数可以用fstream代替。
**当一个fstream对象被销毁时,close会被自动调用。**也就是说,当fstream离开它的作用域时,与之相关联的文件会自动关闭。
3.1 文件模式
用文件名初始化流隐式打开文件和用open打开文件都可以指定文件模式。
trunc,out,app一般只用于ofstream。
使用方式:
在每次调用open时都会给一次确定文件模式的机会,所以需要关闭文件再重新打开才能修改文件模式。
使用方式:
4. string流
istringstream一般用于将一串以空格分开的字符处理为单个字符。可以理解为对string操作引入>>运算符。
ostringstream用于累积构造输出,在某一时间统一输出。可以理解为对string操作引入<<运算符。