【问题标题】:C++ file stream open modes ambiguityC ++文件流打开模式歧义
【发布时间】:2012-09-04 02:50:20
【问题描述】:

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

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

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

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

我的问题是为什么当流的类型(ifstream/ofstream)本身指定哪种类型的操作(输入/输出) 正在执行吗?

还有为什么这种模棱两可的用法(ofstreamios::inifstreamios::out)在一种情况下有效而在另一种情况下失败(尽管只有文件不存在时)?

【问题讨论】:

    标签: c++ file-io stream


    【解决方案1】:

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

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

    注意默认值是ios_base::in,所以你不必自己指定。但是,mode 设置的流标志限于in/out,但包括:

    • app(附加)在每次输出操作之前将流的位置指示器设置为流的末尾。
    • ate(结束时)将流的位置指示器设置为打开时流的末尾。
    • binary(二进制)将流视为二进制而不是文本。
    • in(输入)允许对流进行输入操作。
    • out(输出)允许对流进行输出操作。
    • trunc(截断)任何当前内容都将被丢弃,假设打开时长度为零。

    【讨论】:

      【解决方案2】:

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

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

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

      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
      

      但这很有效,因为虽然gifstream,但我们用ios_base::out 打开它:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        • 2021-10-01
        相关资源
        最近更新 更多