《C++Primer》第八章 IO库

2020-11-19  本文已影响0人  TOMOCAT

IO类

前面提到的IO类型和对象都是操纵char数据的,并且都是关联到用户的控制台窗口的。我们还有其他IO需求:

为了支持上述操作,在istreamostream,标准库还定义了一些其他IO类型。分别定义在三个独立的头文件中:

标准库通过继承机制inheritance是我们可以忽略不同类型的流之间的差异。比如ifstreamistringstream都继承自istream,因此我们可以像使用istream对象一样来使用ifstreamistringstream对象。我们是如何使用cin的也可以同样地使用这些类型的对象。比如可以对一个ifstreamistringstream对象调用getline,也可以使用>>从一个ifstreamistringstream对象中读取数据。

1. IO对象无拷贝或者赋值

我们不能拷贝或对IO对象赋值,因此我们也不能将形参或返回类型设置为流类型。进行IO操作时通常是以引用方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用是非const的。

2. 条件状态

IO操作与生俱来的问题是可能发生错误,一些错误是可修复的,而其他错误则可能发生在系统深处超出了应用程序可以修正的范围。下面列出来IO类所定义的一些函数和标记:

一个流一旦发生错误,其后续的IO操作都会失败,因此代码通常需要在使用一个流之前检查它是否处于良好状态,确定一个流对象的最简单方法是将它作为一个条件使用:

while (cin >> word)
    // ok: 读操作成功...

将流作为条件使用,只能告诉我们流是否有效而无法告诉我们具体发生了什么,我们有时候需要知道错误的具体原因以及是否能恢复。IO库定义了一个与机器无法的iostate类型:

使用fail()good()是确定流总体状态的正确方法,而eofbad操作用于确定具体的错误。

3. 管理输出缓冲

每一个输出流都管理一个缓冲区,比如执行输出代码时文本串可以被立即打印出来,也可能被操作系统保存在缓冲区中用于将多个输出操作组合为单一的系统级写操作。

这主要是因为设备的写操作可能很耗时,操作系统将多个输出操作组合成单一的设备写操作可以极大提升性能。

缓冲刷新,即数据真正写到输出设备或文件的原因有如下:

控制缓冲的操纵符:

需要注意的是,如果程序崩溃,输出缓冲区不会被刷新,调试一个已经崩溃的程序时,需要确认输出数据是不是因为被挂在缓冲区而没有打印

交互式系统都应该关联输入流和输出流,这意味着所有输出包括用户提示信息都会在读操作之前被打印出来。

文件输入输出

1. 类型及操作

头文件fstream定义了三个类型来支持文件IO

上面提到的类型继承了cincout操作(比如>><<getline等),fstream还包括其他特有的操作:

2. 使用文件流对象

ifstream in(ifile); // 构造一个ifstream并打开给定文件
ofstream out;       // 构造输出文件流,并未关联到任何文件

在要求使用基类型对象的地方,我们可以用继承类型的对象代替,这意味着接受一个iostream类型引用(或指针)参数的函数可以用一个对应的fstreamsstream类型来调用。

如果我们定义了一个空文件流对象,随后可以用open来将它与文件关联起来:

ifstream in(ifile);   // 构造一个ifstream并打开文件
ofstream out;         // 输出文件流未与任何文件相关联
out.open(ifile + ".copy"); // 打开指定文件

// 如果调用open失败的话,`failbit`会被置位
if (out) // 检查open是否成功,成功的话我们就可以写入文件

一旦一个文件流已经打开,他就会保持与对应文件的关联,如果对一个恶已经打开的文件流调用open会失败,并会导致failbit被置位,因此文件流关联到另外一个文件时需要先关闭已关联的文件。

3. 自动构造和析构

4. 文件模式

ifstream关联的文件默认以in模式打开,与ofstream关联的文件默认以out模式打开,与fstream关联的文件默认以inout模式打开。

如果我们以out模式打开文件时文件的内容会被全部丢弃,阻止一个ofstream清空给定文件内容的方法是同时制定app模式:

// 下面几条语句中,file1都会被截断
ofstream out("file1");      // 默认以out模式打开
ofstream out("file1", ofstream::out);  // 隐含地截断文件
ofstream out("file1", ofstream::out | ofstream::trunc);
// 为了保留文件内容,必须显式指定app模式
ofstream app("file2", ofstream::app);  // 隐含为输出模式
ofstream app("file2", ofstream::out | ofstream::app);

保留被ofstream打开的文件中已有数据的唯一方法是显式制定appin模式。

string流

stringstream特有的操作包括:

上一篇下一篇

猜你喜欢

热点阅读