IO对象无拷贝和赋值
ofstream out1, out2;
out1 = out2; //错误:不能对流对象赋值
ofstream print(ofstream); //错误:不能初始化ofstream参数
out2= print(out2); //错误:不能拷贝流对象
由于不能拷贝IO对象,所以不能将其设置为形参或者返回类型。
由于读写IO对象会改变其状态,因此进行IO操作的函数通常以引用方式传递和返回流,且传递和返回的引用不能是const
条件状态
strm::iostate | strm是一种IO类型。iostate是一种机器相关的类型,提供表达条件状态的完整功能 |
---|---|
strm::badbit | 指出流已崩溃 |
strm::failbit | 指出一个IO操作失败 |
strm::eofbit | 指出流到达文件的结束 |
strm::goodbit | 指出流未处于错误状态。此值保证为0 |
s.eof() | 若流s的eofbit置位,则返回true |
s.fail() | 若流s的failbit或者badbit置位,则返回true |
s.bad() | 若流s的badbit置位,则返回true |
s.good() | 若流s处于有效状态,则返回true |
s.clear() | 将流s中所有条件状态位复位,将流的状态设置为有效。返回void |
s.clear(flags) | 根据给定的flags标志位,将流s中对象条件状态位复位。flags的类型为strm::iostate。返回void |
s.setstate(flags) | 根据给定的flags标志位,将流s中对象条件状态位复位。flags的类型为strm::iostate。返回void |
s.rdstate() | 返回流s的当前条件状态,返回值类型为strm::iostate |
通常应该在使用一个流之前检查它是否处于良好状态,最简单的检查方法是将其作为一个条件来使用:
while(cin >> word)
//
管理输出缓冲
导致缓冲刷新的可能原因:
- 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行
- 缓冲区满
- endl、flush、ends等操纵符显示刷新缓冲区。
cout << "hi!" <<endl; //输出hi和一个换行,然后刷新缓冲区
cout << "hi!" <<flush; //输出hi,然后刷新缓冲区,不附加任何额外字符
cout << "hi!" <<ends; //输入hi和一个空字符,然后刷新缓冲区
- 在输出操作之后,可以使用操纵符unitbuf设置流的内部状态,来清空缓冲区
cout << unitbuf; //所有输出操作后都会立即刷新缓冲区
//任何输出都立即刷新,无缓冲
cout << nounitbuf; //回到正常缓冲方式
- 一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,cin和cerr都关联到cout。因此,读cin或者写cerr都会导致cout的缓冲区被刷新。(每个流同时最多关联到一个流,但多个流可以同时关联到同一个ostrem)
cin.tie( &cout); //仅仅用于展示,标准库将cin和cout关联在一起
//old_tie指向单枪关联到cin的流(如果有的话)
ostream *old_tie = cin.tie( nullptr ); //cin不再与其他流关联
//将cin和cerr关联:不是一个好的主意,cin应该关联cout
cin.tie( &cerr); //读取cin会刷新cerr而不是cout
cin.tie( old_tie ); //重建cin和cout间的正常关联
注意:如果程序异常终止,输出缓冲区是不会被刷新的。当一个程序崩溃后,输出的数据很可能停留在缓冲输出去中等待打印。