std::ofstream 默认情况下是截断还是追加?
Does std::ofstream truncate or append by default?
如果调用 std::ofstream
构造函数而不带 openmode
标志,则 default flag is ios_base::out
。但这是否意味着 ios_base::trunc
或 ios_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.
我在这个答案的主要部分中谈到了这一点。
如果调用 std::ofstream
构造函数而不带 openmode
标志,则 default flag is ios_base::out
。但这是否意味着 ios_base::trunc
或 ios_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 withbasic_ostream(&sb
) and initializingsb
withbasic_filebuf<charT,traits>())
(27.7.3.2, 27.9.1.2), then callsrdbuf()->open(s, mode|ios_base::out)
. If that function returns a null pointer, callssetstate(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 NTBSs
(as if by callingstd::fopen(s,modstr)
). The NTBSmodstr
is determined frommode & ~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*)
andfseek(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.
我在这个答案的主要部分中谈到了这一点。