[英]Why does std::ofstream truncate without std::ios_base::trunc?
根據這個C ++參考: http ://www.cplusplus.com/reference/fstream/ofstream/ofstream/,std std::ofstream
的默認打開模式是ios_base::out
,它沒有提到其他模式。 因此,我希望如果我用一個小文件覆蓋一個大文件,大文件的“超出”部分應該保持不變,只有文件的第一部分應該用新的,更短的數據替換。
另一方面,Apache C ++標准庫用戶指南( http://stdcxx.apache.org/doc/stdlibug/30-3.html )在第30.3.1.2段的注釋中指出:“對於輸出文件流,打開mode out相當於out | trunc,也就是說,你可以省略trunc標志。但是,對於雙向文件流,必須始終明確指定trunc。“
我試過這段代碼:
#include <fstream>
int main()
{
std::ofstream aFileStream("a.out", std::ios_base::out);
aFileStream << "Hello world!";
aFileStream.close();
std::ofstream aFileStream2("a.out", std::ios::out);
aFileStream2 << "Bye!";
aFileStream2.close();
}
在Windows上使用g ++ 8.1和在Linux上使用g ++ 6.3時,Apache文檔似乎都是正確的。 大文件被截斷,在用第二個文件流寫入較短的字符串后沒有任何內容。
為什么會那樣? cplusplus.com錯了嗎? 或者這種行為取決於什么?
Per [ofstream.cons] / itemdecl:2 :
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
因此, ofstream
的默認模式是out
。 但是,按[tab:filebuf.open.modes] , out
和out | trunc
out | trunc
都對應於stdio等價的"w"
,所以它們是等價的。 根據C11 7.21.5.3 :
w
:截斷為零長度或創建用於寫入的文本文件
因此,正確地說默認模式是out
正確的,並且說默認模式等於out | trunc
也是正確的out | trunc
out | trunc
這是保證的行為。
另一方面,per [fstream.cons] / itemdecl:2 :
explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out);
因此, fstream
的默認模式是in | out
in | out
Per [tab:filebuf.open.modes] , in | out
in | out
對應於"r+"
,而in | out | trunc
in | out | trunc
in | out | trunc
對應於"w+"
,因此它們不相等。 根據C11 7.21.5.3 :
r+
:打開文本文件進行更新(讀寫)
w+
:截斷為零長度或創建文本文件以進行更新
因此,除非指定trunc
否則fstream
不會截斷。 請注意,如果所需文件不存在,則r+
將失敗而不是創建文件。 相反,在這種情況下, w
和w+
都會創建一個新文件。
(另見: fopen
on cppreference)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.