- 第 8 章 IO 库
- 8.1 IO 类
- 8.1.1 IO 对象无拷贝或赋值
- 8.1.2 条件状态
- 8.1.3 管理输出缓冲
- 8.2 文件输入输出
- 8.2.1 使用文件流对象
- 8.2.2 文件模式
- 8.3 string 流
- 8.3.1 使用 istringstream
- 8.3.2 使用 ostringstream
I O 库 类 型 和 头 文 件 头文件 类型 iostream istream, wistream 从流读取数据 ostream, wostream 向流写入数据 iostream, wiostream 读写流 fstream ifstream, wifstream 从文件读取数据 ofstream, wofstream 向文件写入数据 fstream, wfstream 读写文件 sstream istringstream, wistringstream 从 string 读取数据 ostringstream, wostringstream 向 string 写入数据 stringstream, wstringstream 读写 string \begin{array}{c} \hline \bold{IO 库类型和头文件}\\ \hline \begin{array}{l | l} \text{头文件} & \text{类型}\\ \hline \text{iostream} & \text{istream, wistream 从流读取数据}\\ \text{} & \text{ostream, wostream 向流写入数据}\\ \text{} & \text{iostream, wiostream 读写流}\\ \text{fstream} & \text{ifstream, wifstream 从文件读取数据}\\ \text{} & \text{ofstream, wofstream 向文件写入数据}\\ \text{} & \text{fstream, wfstream 读写文件}\\ \text{sstream} & \text{istringstream, wistringstream 从 string 读取数据}\\ \text{} & \text{ostringstream, wostringstream 向 string 写入数据}\\ \text{} & \text{stringstream, wstringstream 读写 string}\\ \end{array}\\ \hline \end{array} IO库类型和头文件头文件iostreamfstreamsstream类型istream, wistream 从流读取数据ostream, wostream 向流写入数据iostream, wiostream 读写流ifstream, wifstream 从文件读取数据ofstream, wofstream 向文件写入数据fstream, wfstream 读写文件istringstream, wistringstream 从 string 读取数据ostringstream, wostringstream 向 string 写入数据stringstream, wstringstream 读写 string
下面介绍的标准库流特性都可以无差别地应用于普通流、文件流和 string 流,以及 char 或宽字符版本。
8.1.1 IO 对象无拷贝或赋值- 不能拷贝 IO 对象
- 不能将形参或返回类型设置为流类型,通常函数以引用方式传递和返回流
- 读写 IO 对象会改变其状态,因此传递和返回的引用不应是 const
ofstream out1, out2;
out1 = out2; // 错误:不能对流对象赋值
ofstream print(ofstream); // 错误:不能初始化 ofstream 参数
out2 = print(out2); // 错误:不能拷贝流对象
8.1.2 条件状态
I O 库 条 件 状 态 s t r m : : iostate s t r m 表示一种 IO 类型,例如 ofstream。 iostate 是一种机器相关的类型,提供了表达条件状态的完整功能 s t r m : : badbit s t r m : : badbit 用来指出流已崩溃 s t r m : : failbit s t r m : : failbit 用来指出一个 IO 操作失败了 s t r m : : eofbit s t r m : : eofbit 用来指出流达到了文件结束 s t r m : : goodbit s t r m : : 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 类型为 s t r m : : iostate。返回 void s.setstate(flags) 根据给定的 flags 标志位,将流 s 中对应条件状态位置位。 flags 类型为 s t r m : : iostate。返回 void s.rdstate() 返回流 s 当前条件状态,返回值类型为 s t r m : : iostate \begin{array}{c} \hline \bold{IO 库条件状态}\\ \hline \begin{array}{l l} strm::\text{iostate} & strm\ \text{表示一种 IO 类型,例如 ofstream。}\\ & \text{iostate 是一种机器相关的类型,提供了表达条件状态的完整功能}\\ strm::\text{badbit} & strm::\text{badbit 用来指出流已崩溃}\\ strm::\text{failbit} & strm::\text{failbit 用来指出一个 IO 操作失败了}\\ strm::\text{eofbit} & strm::\text{eofbit 用来指出流达到了文件结束}\\ strm::\text{goodbit} & strm::\text{goodbit 永安里指出流未处于错误状态。此值保证为 0}\\ \text{s.eof()} & \text{若流 s 的 eofbit 置位,则返回 true}\\ \text{s.fail()} & \text{若流 s 的 failbit 或 badbit 置位,则返回 true}\\ \text{s.bad()} & \text{若流 s 的 badbit 置位,则返回 true}\\ \text{s.good()} & \text{若流 s 处于有效状态,则返回 true}\\ \text{s.clear()} & \text{将流 s 中所有条件状态复位,将流的状态设置为有效,返回 void}\\ \text{s.clear(flags)} & \text{根据给定的 flags 标志位,将流 s 中对应条件状态位复位。}\\ & \text{flags 类型为}\ strm::\text{iostate。返回 void}\\ \text{s.setstate(flags)} & \text{根据给定的 flags 标志位,将流 s 中对应条件状态位置位。}\\ & \text{flags 类型为}\ strm::\text{iostate。返回 void}\\ \text{s.rdstate()} & \text{返回流 s 当前条件状态,返回值类型为}\ strm::\text{iostate}\\ \end{array}\\ \hline \end{array} IO库条件状态strm::iostatestrm::badbitstrm::failbitstrm::eofbitstrm::goodbits.eof()s.fail()s.bad()s.good()s.clear()s.clear(flags)s.setstate(flags)s.rdstate()strm 表示一种 IO 类型,例如 ofstream。iostate 是一种机器相关的类型,提供了表达条件状态的完整功能strm::badbit 用来指出流已崩溃strm::failbit 用来指出一个 IO 操作失败了strm::eofbit 用来指出流达到了文件结束strm::goodbit 永安里指出流未处于错误状态。此值保证为 0若流 s 的 eofbit 置位,则返回 true若流 s 的 failbit 或 badbit 置位,则返回 true若流 s 的 badbit 置位,则返回 true若流 s 处于有效状态,则返回 true将流 s 中所有条件状态复位,将流的状态设置为有效,返回 void根据给定的 flags 标志位,将流 s 中对应条件状态位复位。flags 类型为 strm::iostate。返回 void根据给定的 flags 标志位,将流 s 中对应条件状态位置位。flags 类型为 strm::iostate。返回 void返回流 s 当前条件状态,返回值类型为 strm::iostate
对于下列程序:
int ival;
cin >> ival;
如果我们在标准输入上键入 Boo,读操作就会失败。一个流一旦发生错误,后续的 IO 操作都会失败。只有当其处于无错状态时,才可以从它读取数据。
确定一个流对象的状态,最简单的方法是将其当做一个条件来使用:
while (cin >> word) {
// ok:操作成功
}
(1)查询流的状态
流作为条件使用,只能告诉我们流是否有效,而无法告知具体信息。
IO 库定义了一个与机器无关的 iostate 类型,作为一个位集合来使用。IO 库定义了 4 个 iostate 类型的 constexpr 值,表示特定的位模式。可以用位运算符一起使用来一次性检测或设置多个标志位。
流状态说明badbit表示系统级错误。一旦被置位,流便无法再使用了。failbit可恢复错误,这种问题通常可以修正。eofbit表示文件结束。这时 failbit 也会被置位。goodbit值为 0 时,表示流未发生错误。 查询函数说明strm.good()所有错误均未置位,则返回 true。strm.bad()badbit 被置位,返回 truestrm.fail()failbit 或 badbit 被置位,返回 truestrm.eof()eofbit 被置位,返回 true- 如果 badbit、failbit 和 eofbit 任意一个被置位,检测流状态的条件都会失败
- 使用 good() 或 fail() 是确定流的总体状态的正确方法
- 事实上,将流当做条件使用的代码等价于 !fail()
(2)管理条件状态
auto old_state = cin.rdstate(); // 记住 cin 的当前状态
cin.clear(); // 使 cin 有效
process_input(cin); // 使用 cin
cin.setstate(old_state); // 将 cin 置为原有状态
我们也可以用位操作将所需位复位来生成新的状态:
// 复位 failbit 和 badbit,保持其他标志位不变
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
8.1.3 管理输出缓冲
每个输出流都管理一个缓冲区,用来保存程序读写的数据。由于设备的写操作可能很耗时,允许操作系统将多个输出操作组合为单一的设备写操作,这样可以带来很大的性能提升。
导致缓冲刷新(数据真正写到输出设备或文件)的原因有:
- 程序正常结束。缓冲刷新作为 main 函数 return 操作的一部分
- 缓冲区满了
- 使用操作符手动刷新,如 endl、flush、ends
- 使用操作符 unitbuf 设置流的内部状态,清空缓冲区。
- 默认情况下,对 cerr 设置了 unitbuf,因此写到 cerr 的内容都是立即刷新的
- 一个输出流被关联到另一个流。当另一个流进行读写操作时,该输出流的缓冲区会被刷新。
- 默认情况下,cin 与 cout 关联,cerr 也与 cout 关联。
(1)刷新输出缓冲区
三个可以刷新缓冲区的操作符:
cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?