16

为了在 C++ 中执行文件 IO,我们使用了 ofstream、ifstream 和 fstream 类。

  • ofstream:写入文件的流类
  • ifstream:从文件中读取的流类
  • fstream:流类以读取和写入文件

将文件与流对象关联的过程称为“打开文件”。打开文件时,我们可以指定打开文件的模式。我的查询与ios::outios:in模式有关。

当我创建一个ofstream对象并使用模式打开文件时ios::in,我可以写入文件,但前提是它已经创建(ios::out如果它不存在,也会创建模式文件)。
但是当我创建ifstream对象并使用模式打开文件时ios::out,我可以从文件中读取。

我的问题是,当流( / )的类型本身指定正在执行哪种类型的操作(输入/输出)时,为什么这些模式(ios::in/ ios::out)由语言提供?ifstreamofstream

另外,为什么这种模棱两可的用法(ofstreamwithios::inifstreamwith ios::out)在一种情况下有效而在另一种情况下失败(尽管仅当文件不存在时)?

4

2 回答 2

12

ofstream和类是底层的高级接口,ifstream可以通过流的成员函数获得。fstreamfilebufrdbuf()

根据标准,当您打开ofstreamwith 某种模式mode时,它会像 with 一样打开下划线流缓冲区mode | ios_base::out。类似地ifstream使用mode | ios_base::in. fstreammode参数逐字传递给下划线流缓冲区。

上面的意思是,以下代码使用完全相同的打开标志打开文件:

fstream f("a.txt", ios_base::in | ios_base::out);
ifstream g("a.txt", ios_base::out);
ofstream h("a.txt", ios_base::in);

f.rdbuf()在这些行之后,您可以使用,g.rdbuf()和执行完全相同的操作h.rdbuf(),所有这三个操作就像您使用 C 调用打开文件一样fopen("a.txt", "r+"),这为您提供读/写访问权限,不会截断文件,如果文件执行则失败不存在。

那么,为什么我们有三个不同的类呢?正如我已经说过的,这些是在较低级别的流缓冲区上提供高级接口的高级类。这个想法是ifstream具有用于输入的成员函数(如read()),ofstream具有用于输出的成员函数(如write()),而fstream两者都有。例如,您不能这样做:

g.write("abc", 3); // error: g does not have a write function

但这行得通,因为虽然g是一个ifstream,但我们已经打开它ios_base::out

g.rdbuf()->sputn("abc", 3); // we still have write access
于 2012-09-11T08:47:46.020 回答
0

因为模式不限于输入/输出。例如的构造函数ifstream如下所示:

explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );

请注意,默认值为ios_base::in,因此您不必自己指定。但是,mode设置的流标志不仅限于in/ out,还包括:

  • app(append) 在每次输出操作之前将流的位置指示符设置到流的末尾。
  • ate(结束时)将流的位置指示器设置为打开时流的末尾。
  • binary (二进制)将流视为二进制而不是文本。
  • in (input) 允许对流进行输入操作。
  • out(输出)允许对流进行输出操作。
  • trunc (截断)任何当前内容都被丢弃,假设打开时长度为零。
于 2012-09-11T08:12:06.160 回答