C++文件流打开模式不明确

C++ file stream open modes ambiguity

本文关键字:模式 不明确 文件 C++      更新时间:2023-10-16

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

  • ofstream:要在文件上写入的流类
  • ifstream:要从文件中读取的流类
  • fstream:从文件读取和向文件写入的流类

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

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

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

同样,为什么这种不明确的用法(ofstreamios::inifstreamios::out)在一种情况下有效,而在另一种情况中失败(尽管仅当文件不存在时)?

ofstreamifstreamfstream类是底层filebuf的高级接口,可以通过流的rdbuf()成员函数访问。

当您使用某种模式mode打开ofstream时,它会使用mode | ios_base::out打开底层流缓冲区。类似地,ifstream使用mode | ios_base::in。CCD_ 26将CCD_。

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

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+")打开文件一样,CCD_31为您提供读/写访问权限,不会截断文件,如果文件不存在,则会失败。

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

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

但这是有效的,因为尽管gifstream,但我们用ios_base::out:打开了它

g.rdbuf()->sputn("abc", 3); // we still have write access

因为模式不限于输入/输出。例如,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(截断)任何当前内容都将被丢弃,假设打开时长度为零