std::ofstream 默认情况下是截断还是追加?

Does std::ofstream truncate or append by default?

如果调用 std::ofstream 构造函数而不带 openmode 标志,则 default flag is ios_base::out。但这是否意味着 ios_base::truncios_base::app

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

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

"new content" 会附加到 "past.txt" 之前的内容,还是会取代之前的内容?

短版

默认截断。


中型

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

检查出来为我们提供了 §7.19.5.3,"The fopen function",它指定了传递 "w" 时的行为:

w truncate to zero length or create text file for writing


长版

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

Effects: Constructs an object of class basic_ofstream<charT,traits>, initializing the base class with basic_ostream(&sb) and initializing sb with basic_filebuf<charT,traits>()) (27.7.3.2, 27.9.1.2), then calls rdbuf()->open(s, mode|ios_base::out). If that function returns a null pointer, calls setstate(failbit).

其中 rdbuf() returns basic_filebuf<charT,traits>* (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);

作为

Effects: If is_open() != false, returns a null pointer. Otherwise, initializes the filebuf as required. It then opens a file, if possible, whose name is the NTBS s (as if by calling std::fopen(s,modstr)). The NTBS modstr is determined from mode & ~ios_base::ate as indicated in Table 132. If mode is not some combination of flags shown in the table then the open fails.

NTBS:空终止字节串

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

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

这导致我们在同一页上有一个脚注,其中指出:

...the function signatures fopen(const char*, const char*) and fseek(FILE*, long, int) are declared, in <cstdio> (27.9.2).

不出所料,它将我们发送到 27.9.2 [c.files],它提供了几乎无用的 Table 134,但随后引用了 C 标准:

See also: ISO C 7.9, Amendment 1 4.6.2.

我在这个答案的主要部分中谈到了这一点。