【问题标题】:Does std::ofstream truncate or append by default?std::ofstream 是否默认截断或追加?
【发布时间】:2017-01-08 11:24:39
【问题描述】:

如果您在没有 openmode 标志的情况下调用 std::ofstream 构造函数,则 default flag is ios_base::out。但这是否意味着ios_base::truncios_base::app

换句话说,如果您的文件系统中已经有一个非空文件“past.txt”并且您调用

std::ofstream stream( "past.txt" );
stream << "new content";

将“新内容”附加到“past.txt”的先前内容还是会替换先前的内容?

【问题讨论】:

  • 我感觉这个问题是基于错误的参考选择。 This 应该更好。
  • ios_base::outios_base::out | ios_base::trunc 相同。我找不到一个好的参考链接,但谷歌搜索命中了几个text books
  • 根据 LogicStuff 的链接,ofstream ctor 默认为 out,在 basic_filebuf::open 中的行为与 out|trunc 相同,因此会被截断。
  • 我投票决定将此问题作为题外话结束,因为可以从可用的正确参考资料中轻松找到答案。 (只是测试自己会证明)
  • 听起来这可能是what's wrong with cplusplus.com的另一个例子,虽然这一次只是一个遗漏......

标签: c++ fstream


【解决方案1】:

短版

默认截断。


中等版本

标准基本上是意大利面条,但最终归结为说它相当于说fopen(const char*, "w") (27.9.1.4 [filebuf.members]),然后将我们指向 ISO C 7.9 标准。

检查出来为我们提供了第 7.19.5.3 节“fopen 函数”,它指定了传递“w”时的行为:

w 将长度截断为零或创建文本文件用于写入


长版

如果你想自己跟随意大利面条的轨迹,从 27.9.1.11 [ofstream.cons] 开始,它将构造函数的行为描述为

效果:构造class basic_ofstream&lt;charT,traits&gt;的对象,用初始化基类 basic_ostream(&amp;sb) 并使用 basic_filebuf&lt;charT,traits&gt;()) (27.7.3.2, 27.9.1.2) 初始化 sb, 然后调用rdbuf()-&gt;open(s, mode|ios_base::out)。如果该函数返回一个空指针,则调用 setstate(failbit).

其中rdbuf() 返回basic_filebuf&lt;charT,traits&gt;* (27.9.1.13 [ofstream])

这将我们引向 27.9.1.1 [filebuf],或者更具体地说,是 27.9.1.4 [filebuf.members],它描述了 open 函数:

basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);

作为

效果:如果is_open() != false,返回一个空指针。否则,根据需要初始化 filebuf。 然后,如果可能,它会打开一个名为 NTBS s 的文件(就像调用 std::fopen(s,modstr) 一样)。 NTBS modstrmode &amp; ~ios_base::ate 确定,如表 132 所示。如果模式为 不是表中显示的某些标志组合,则打开失败。

NTBS:以空结尾的字节串

表 132 描述了 C++ ios_base::openmode 和 C 风格的 stdio 字符串之间的等价规则:

Table 132 — File open modes
|
|   'ios_base' flag combination   | 'stdio' equivalent |
| binary | in | out | trunc | app |                    |
|        |    |  +  |       |     |        "w"         |
|                     etc...                           |

这导致我们在同一页面上的脚注指出:

...函数签名fopen(const char*, const char*)fseek(FILE*, long, int)&lt;cstdio&gt; (27.9.2) 中声明。

可以预见的是,它会将我们发送到 27.9.2 [c.files],它提供了几乎无用的表 134,但随后引用了 C 标准:

另请参阅:ISO C 7.9,修正案 1 4.6.2。

我在这个答案的主要部分谈到。

【讨论】:

  • 那么答案是什么?
  • @A.Smoliak 问题“std::ofstream 是否默认截断或追加?”的答案是“截断”
猜你喜欢
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多