簡體   English   中英

為什么std :: ofstream截斷沒有std :: ios_base :: trunc?

[英]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]outout | 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+將失敗而不是創建文件。 相反,在這種情況下, ww+都會創建一個新文件。

(另見: fopen on cppreference)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM