I/O 类型
I/O stream 定义读写控制台窗口类型
fstream 定义读写已命名文件类型
sstream 定义读写存储在内存中的 string 类型
I/O 对象不可复制或赋值
I/O 对象不可复制或赋值,不能存储在容器中,形参和返回值不能为 I/O 类型,可以使用 I/O 类型的指针或引用传递或返回对象
一般情况下,传递I/O对象进行读写时,使用非 const 引用方式传递,读写会改变流的状态,不能为 const
I/O 标准库的条件状态
检查流是否处于无错误状态
if (cin) {}
// 或者
while (cin >> val) {}
每个 I/O 定义了 3 个 iostate 的常量,分别表示特定的位模式,可与位操作符一同使用来设置或检查多个条件状态
badbit 系统级故障,不可恢复
failbit 可恢复错误,如读写数字时写入了字符,通常可以修整
eofbit 遇到文件结束符,此时还设置了 failbit
good 无错误
clear 讲条件重设为有效状态,在流出现问题补救后可用 clear 重设为可用状态
setstate可打开某个特定的状态,同时保留其他的状态量不变
int val
while(cin >> val, !cin.eof()) {
if (cin.bad())
throw runtime_error("IO system error occur");
if (cin.fail()) {
cerr << "bad data, try again";
cin.clear(istream::failbit);
contine;
}
// ok process ival
}
I/O 条件状态的访问
rdstate 返回一个 iostate 类型的值,该值为流的整个状态
istream::iostate old_state = cin.rdstate();
cin.clear();
process_cin();
cin.clear(old_state); // 重设为以前的状态
多重状态的处理
设置或清除多个状态可以使用位操作符生成多个状态位的值,或者多次调用 clear 或 setstate 函数
is.setstate(ifstream::badbit | ifstream::failbit); // 同时设置 is 的 badbit 和 failbit 为 1 ,其它位为 0
输出缓冲区的管理
每个 I/O 对象管理一个缓冲区
以下情况将刷新缓冲区:
1. 程序正常结束,main 返回
2. 一些不确定情况,缓冲区满了,此时缓冲区会在写下一个值之前刷新
3. 用操纵符(mainpular)显式刷新,列如 endl**见1.2.2o**
4. 每次输出操作执行完后,用 unitbuf 操纵符设置流的内部状态,从而清空缓冲区
5. 将输出流与输入流(tie)起来,此时,在读输入流时将刷新其关联的输出缓冲区
输出缓冲区的刷新
cout << "hi!" << flush; // 刷新流,不添加任何字符
cout << "hi!" << ends; // 刷新流,在缓冲区插入空字符 null,用得较少
cout << "hi!" << endl; // 刷新流,输出一个换行符
unitbuf
刷新所有输出,最好使用 unitbuf 操纵符。每次执行完后都会刷新流
cout << unitbuf << "first" << "second" << nounitbuf; // nounitbuf 操纵符将流恢复为正常的,由系统管理的缓冲区刷新方式
// 等价于
cout << "first" << flush << "second" << flush;
程序崩溃了,不会刷新缓冲区,最好保证所有输出都显示调用 flush
或 endl
而不是 ‘\n’