You Know Nothing
  • 主页
  • 分类
  • 标签
  • 归档

C++ Primer 第八章 IO 库

  • 8.1 IO 类
    • 8.1.1 条件状态
    • 8.1.2 管理条件状态
    • 8.1.3 管理输出缓冲
    • 8.1.4 unitbuf 操纵符
    • 8.1.5 关联输入和输出流
  • 8.2 文件输入输出
    • 8.2.1 fstream 特有的操作
    • 8.2.2 文件模式
  • 8.3 string 流
    • fstream 特有的操作

8.1 IO 类

iostream头文件:

istream,wistream,ostream,wostream,iostream,wiostream类型。

fstream头文件:

ifstream,wifstream,ofstream,wofstream,fstream,wfstream类型。

sstream头文件:

istringstream,wistringstream,ostringstream,wostringstream,stringstream,wstringstream类型。

宽字符版本的类型和函数的名字以一个“w”开始。

IO 对象无拷贝和赋值。进行 IO 操作的函数通常以引用方式传递和返回值。读写一个 IO 对象会改变其状态,因此传递和返回的引用不能是const的。

8.1.1 条件状态

下表中 strm 是一种 IO 类型:

状态 含义
strm::iostate 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 复位,flags 类型为 strm::iostate,返回 void
s.setstate(flags) 根据 flags 置位,flags 类型为 strm::iostate,返回 void
s.rdstate() 返回流 s 的当前条件状态,返回值类型为 strm::iostate

badbit表示系统级错误,如不可恢复的读写错误,一旦被置位,流就无法再使用了。

failbit表示可恢复的错误,例如期望读取数值却读到一个字符等错误。这种问题通常是可以修正的,流还可以继续使用。

如果到达文件结尾,eofbit和failbit都会被置位。

goodbit值为0,表示流未发生错误。

如果badbit、failbit和eofbit任一个被置位,则检测流状态的条件会失败。

good()函数在所有错误位均未置位的情况下返回true。

我们将流当做条件使用的代码等价于!fail()。

8.1.2 管理条件状态

// 记住 cin 的当前状态
auto old_state = cin.rdstate(); // 记住 cin 的当前状态
cin.clean();  // 使 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(插入换行)、ends(插入空字符)、flush(什么都不插入)显式刷新
  • 在每个输出操作之后,可以用操纵符unitbuf设置流的内部状态,来情况缓冲区。默认情况下,对cerr是设置unitbuf的,因此cerr的内容都是立即刷新的
  • 一个输出流可以关联到另一个流。当读写被关联的流时,关联到的流的缓冲区会被刷新。默认情况下,cin和cerr都关联到cout。因此读cin或者写cerr都会导致cout的缓冲区被刷新

8.1.4 unitbuf 操纵符

如果想在每次输出操作后都刷新缓冲区,可以使用unitbuf操纵符。它告诉流在接下来的每次写操作之后都执行一次flush刷新。nounitbuf操纵符则重置流,使其恢复使用正常的系统管理的缓冲区刷新机制:

cout << unitbuf;    // 所有输出操作后都会立即刷新缓冲区
// 任何输出都会立即刷新,无缓冲
cout << nounitbuf;    // 回到正常的缓冲方式

8.1.5 关联输入和输出流

tie()有两个重载的版本:

  • 不带参数的版本返回指向输出流的指针。如果本对象当前关联到一个输出流,则返回的就是指向这个流的指针,如果对象未关联到流,则返回空指针
  • 第二个版本接受一个指向ostream的指针,将自己关联到此ostream

每个流同时最多关联到一个流,但多个流可以同时关联到同一个ostream

8.2 文件输入输出

8.2.1 fstream 特有的操作

下表中的 fstream 是头文件 fstream 中定义的一个类型:

操作 含义
fstream fstrm; 创建一个未绑定的文件流
fstream fstrm(s); 创建一个 fstream,并打开名为 s 的文件。s 可以是 string 类型或者指向 C 风格字符串的指针。这些构造函数都是explicit的。默认的文件模式 mode 依赖于 fstream 的类型
fstream fstrm(s, mode); 按 mode 打开文件
fstrm.open(s) 打开名为 s 的文件并与 fstrm 绑定。s 可以是 string 类型或者指向 C 风格字符串的指针。默认的文件模式 mode 依赖于 fstream 的类型。返回void
fstrm.close() 关闭与 fstrm 绑定的文件。返回void
fstrm.is_open() 返回一个布尔值,指出与 fstrm 关联的文件是否打开成功且尚未关闭

如果调用open()失败,failbit会被置位,条件会为假:if(open(file))可用于判定。

对一个已经打开的文件流调用open()会失败,并且failbit会被置位。为了将文件流关联到另一个文件,必须先关闭已经关联的文件。

当一个fstream对象被销毁时,close会自动被调用。

8.2.2 文件模式

文件模式 意义
in 只读
out 只写(会清空已有数据)
app 每次写操作前均定位到文件末尾
ate 打开文件后立即定位到文件末尾
trunc 截断文件
binary 以二进制方式进行 IO

ifstream默认in模式;ofstream默认out模式;fstream默认in和out模式打开。

8.3 string 流

fstream 特有的操作

下表中的 sstream 是头文件 sstream 中定义的一个类型:

操作 含义
sstream strm; 创建一个未绑定的 stringstream 对象
sstream strm(s); strm 是一个 sstream 对象,保存 string s 的一个拷贝。此构造函数时explicit的
strm.str() 返回 strm 所保存的 string 的拷贝
strm.str(s) 将 string s 拷贝到 strm 中,返回 void

RELATED

  • C++ 中的类型转换
  • C++ Primer 第十七章 标准库特殊设施
  • C++ Primer 第十六章 模板与泛型编程
  • C++ Primer 第十五章 面向对象程序设计
  • C++ Primer 第十四章 重载运算与类型转换

OLDER

  • C++ Primer 第七章 类
  • C++ Primer 第六章 函数
  • 回车与换行的区别
  • C++ Primer 第五章 语句
  • 几个有趣的 Linux 命令

NEWER

  • 数据结构——树
  • 数据结构——向量
  • PyTroch 之 torch 包
  • eps 图像截切四周的空白
  • 原码, 反码, 补码

发布日期

2018-10-09 22:19:51

最后更新

2018-10-09 22:19:51

分类

C++

标签

  • C++ 18
  • Powered by Pelican. Theme: Elegant by Talha Mansoor