【问题标题】:Why does ofstream("log.txt", ios::app|ios::trunc); always fail?为什么 ofstream("log.txt", ios::app|ios::trunc);总是失败?
【发布时间】:2013-02-11 14:27:24
【问题描述】:

以下代码是在 Windows 7 x64 上使用 VC++ Nov 2012 CTP 编译的。

#include <fstream>

using namespace std;

int main()
{
    ofstream fout("log.txt", ios::app|ios::trunc);
    if (!fout)
    {
        cout << "An error occurred!" << endl; // Always go here! Why?
    }
}

The cppreference.com website 并不是说​​ios::app 不能与ios::trunc 结合使用。

ios::appios::trunc确切语义是什么?

【问题讨论】:

  • 文档没有说ios::app不能和ios::trunc结合。
  • 你想做什么? std::ios::trunc 基本上丢弃所有内容,而 std::ios::app 追加。
  • @CLearner,仅用于记录。删除旧内容并添加新文本。
  • @LightnessRacesinOrbit C++确实有一个官方文档:ISO 14882。当纯粹询问有关 C++ 的问题时,链接到其他网站是没有意义的。语言由标准定义。 (当然,许多问题涉及一个或多个编译器的细节,而不仅仅是语言。)

标签: c++ iostream


【解决方案1】:

这些标志被传递到的filebuf 构造函数具有基于 C++11 中表 132 中定义的标志的行为:

+-----------------------------------+-------------------+
|     ios_base flag combination     |  stdio equivalent |
| binary  in    out    trunc    app |                   |
+-----------------------------------+-------------------+
|               +                   |  "w"              |
|               +               +   |  "a"              |
|                               +   |  "a"              |
|               +       +           |  "w"              |
|        +                          |  "r"              |
|        +      +                   |  "r+"             |
|        +      +       +           |  "w+"             |
|        +      +               +   |  "a+"             |
|        +                      +   |  "a+"             |
+-----------------------------------+-------------------+
|   +           +                   |  "wb"             |
|   +           +               +   |  "ab"             |
|   +                           +   |  "ab"             |
|   +           +       +           |  "wb"             |
|   +    +                          |  "rb"             |
|   +    +      +                   |  "r+b"            |
|   +    +      +       +           |  "w+b"            |
|   +    +      +               +   |  "a+b"            |
|   +    +                      +   |  "a+b"            |
+-----------------------------------+-------------------+

如您所见,您的标志组合在该表中没有

[C++11: 27.9.1.4/2]: [..] 如果mode 不是表中显示的某些标志组合,则打开失败。

这些是语义。

[C++11: 27.9.1.7/2] & [C++11: 27.9.1.11/2] 告诉我们模式是从流对象传递到缓冲区对象的。

【讨论】:

  • 这是一个很好的答案。但是,在这里我要感谢 Bo Persson,因为他是第一个给出正确答案的人。他的回答是评论而不是回答。
  • @xmllmx 该评论现已被版主的钝斧删除。
  • 忍不住放声大笑。 "wb" 比 fstream 约定更容易混淆。
【解决方案2】:
  • app (=append):在每次输出操作之前将流的位置指示器设置为流的末尾
  • trunc (=truncate) 任何当前内容都将被丢弃,假设打开时的长度为零。

如您所见,将两者放在一起是没有意义的。

【讨论】:

  • 请保持 cmets 提出澄清问题并回答。关于特定主题的扩展讨论应保留至Chat。此外,涉及谩骂的讨论也将被删除。
猜你喜欢
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多