输入输出流
2023年12月21日 2023年12月21日
定义了读写流(控制台窗口的输入输出)的基本类型
处理控制台IO
头文件
1#include <iostream>
输入输出流
- | |
---|---|
只读 | istream |
只写 | ostream |
可读写 | iostream |
常用IO类对象
- | |
---|---|
cin | istream对象 |
cout | ostream对象 |
cerr | ostream对象 |
IO对象无拷贝或赋值
- 不能拷贝IO对象
- 不能将形参或返回类型设置为流类型
1ofstream out1, out2; 2 3out1 = out2; // 错误 4ofstream print(ofstream); // 错误:是函数声明,但参数和返回值只能是引用,无法初始化ofstream形参 5out2 = print(out2); // 错误:不能拷贝流对象
条件状态
condition state
IO操作的状态指示
strm是一种IO类型
标志位集合类型
- | |
---|---|
strm::iostate | 机器无关类型; 位集合 |
标志位
置位时 | |
---|---|
strm::badbit | 流崩溃:之后无法使用 |
strm::failbit | IO操作失败:复位后可继续使用 |
strm::eofbit | 流到达了文件结束 |
strm::goodbit | 流工作正常 |
查询标志位的接口
置位/为真时返回true | ||
---|---|---|
s.eof() | strm::eofbit | |
s.fail() | strm::badbit或strm::failbit | 用来判断流的总体状态 |
s.bad() | strm::badbit | |
s.good() | !(strm::eofbit或strm::badbit或strm::failbit) | 用来判断流的总体状态; 为true时流处于有效状态 |
设置标志位
- | |
---|---|
s.clear() | 复位所有标志位, 将流的状态设置为有效; 返回void |
s.clear(flags) | 复位指定标志位; 返回void |
s.setstate(flags) | 置位指定标志位; 返回void |
s.rdstate() | 读取当前装填,返回strm::iostate |
clear是重载函数
到达文件尾,eofbit和failbit都会被置位
使用clear复位
1// strm::iostate 2auto old_state = cin.rdstate(); 3cin.clear(); 4process_input(cin); 5cin.setstate(old_state); 6 7// 复位failtbit和badbit,其他标志位不变 8cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
输出缓冲
写操作耗时,输出缓冲可以将多次输出合为1次
刷新缓冲区的场景
-
程序正常结束,main函数执行return语句时,刷新缓冲
-
缓冲区满. 刷新后, 新的数据才能写入缓冲区
-
使用操纵符endl显式刷新缓冲区
-
如果使用操纵符unitbuf设置流的内部状态,每次输出后都会清空缓冲区
如cerr流对象 -
输出流A被关联到流B. 读写B时, A的缓冲区会被刷新
cout被cin和cerr关联. 读cin或者写cerr时, cout的缓冲区会被刷新
显式刷新缓冲区
-
单次
- endl 换行并刷新缓冲区 flush 仅刷新缓冲区 ends 输出空字符并刷新缓冲区 1cout << "hi!" << endl; 2cout << "hi!" << flush; 3cout << "hi!" << ends;
-
设置刷新机制
unitbuf 每次输出后立即刷新 nounitbuf 恢复原刷新机制 1cout << unitbuf; 2cout << nounitbuf;
将一个流关联到一个输出流
比如, 将流A关联到输出流B. 当我们读写流A时, 输出流B的缓冲区会被刷新
标准库将cin和cerr关联到输出流cout. 读cin或者写cerr时, cout的缓冲区会被刷新
- 查看被关联的输出流
1cin.tie(); // 无参数,返回指针,指向关联的输出流
- 关联到指定输出流
1cin.tie(&cout); // 关联到输出流cout
tie提供重载版本
1ostream *old_tie = cin.tie(nullptr); // 取消关联;old_tie指向cin原关联的输出流,无则为空 2 3cin.tie(&cerr); // 读取cin刷新cerr 4cin.tie(old_tie);