如果您调用std::ofstream
构造函数而没有使用openmode
标志,那么默认标志是ios_base::out
。但这是否意味着ios_base::trunc
或ios_base::app
?
换句话说,如果您的文件系统中已经有一个非空文件 "past.txt",然后您调用:
std::ofstream stream( "past.txt" );
stream << "new content";
"新内容"会被添加到"past.txt"之前的内容中还是会替换之前的内容?
如果您调用std::ofstream
构造函数而没有使用openmode
标志,那么默认标志是ios_base::out
。但这是否意味着ios_base::trunc
或ios_base::app
?
换句话说,如果您的文件系统中已经有一个非空文件 "past.txt",然后您调用:
std::ofstream stream( "past.txt" );
stream << "new content";
"新内容"会被添加到"past.txt"之前的内容中还是会替换之前的内容?
默认情况下会截断。
标准规定有些含糊,但最终可以归结为相当于 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] 开始,其中描述了构造函数的行为为
效果:构造一个 basic_ofstream<charT,traits> 类型的对象,使用
basic_ostream(&sb))
初始化基类并使用basic_filebuf<charT,traits>()
初始化sb
(27.7.3.2, 27.9.1.2),然后调用rdbuf()->open(s, mode|ios_base::out)
。如果该函数返回空指针,则调用setstate(failbit)
。
其中 rdbuf()
返回 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);
作用:如果is_open() != false
,则返回空指针。否则,按照要求初始化filebuf。
然后,如果可能,打开一个名为NTBS s
的文件(就像调用std :: fopen(s,modstr)
一样)。
NTBS modstr
由mode&~ios_base :: ate
确定,如表132所示。 如果模式不是表中显示的标志组合,则打开失败。
NTBS:以空字符结尾的字节字符串
表132描述了C ++ ios_base :: openmode
和C-style stdio字符串之间的等价规则:
<b>Table 132</b> — 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)
,这些声明在<cstdio>
(27.9.2)中。可预测地将我们带到27.9.2[c.files],该部分提供了几乎无用的表格134,但随后引用了C标准:另见:ISO C 7.9,Amendment 1 4.6.2。
ios_base::out
与ios_base::out | ios_base::trunc
相同。我找不到一个好的参考链接,但是谷歌搜索命中了一些教科书。 - CAB