web-dev-qa-db-ja.com

std :: ofstreamはデフォルトで切り捨てまたは追加しますか?

openmodeフラグなしでstd::ofstreamコンストラクターを呼び出すと、 デフォルトのフラグはios_base::out になります。しかし、これはios_base::truncまたはios_base::appを意味しますか?

つまり、ファイルシステムに空でないファイル「past.txt」がすでにあり、

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

「past.txt」の以前のコンテンツに「新しいコンテンツ」が追加されますか、それとも以前のコンテンツが置き換えられますか?

14
OldPeculier

ショートバージョン

デフォルトでは切り捨てられます。


ミディアムバージョン

標準は基本的にこれに関するスパゲッティですが、最終的にはfopen(const char*, "w")(27.9.1.4 [filebuf.members])と同等であると言うことになり、ISO C7.9標準に向けられます。

チェックアウトすると、§7.19.5.3「fopen関数」が提供されます。これは、「w」が渡されたときの動作を指定します。

w長さをゼロに切り捨てるか、書き込み用のテキストファイルを作成します


ロングバージョン

効果:_class basic_ofstream<charT,traits>_のオブジェクトを構築し、基本クラスを_basic_ostream(&sb_)で初期化し、sbbasic_filebuf<charT,traits>())で初期化します(27.7.3.2、27.9.1.2)。 rdbuf()->open(s, mode|ios_base::out)を呼び出します。その関数がnullポインターを返す場合は、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の場合、nullポインターを返します。それ以外の場合は、必要に応じてfilebufを初期化します。次に、可能であれば、名前がNTBS sであるファイルを開きます(std::fopen(s,modstr)を呼び出すかのように)。 NTBS modstrは、表132に示すように_mode & ~ios_base::ate_から決定されます。モードが表に示されているフラグの組み合わせでない場合、オープンは失敗します。

NTBS:ヌル終了バイト文字列

表132に、C++ _ios_base::openmode_とCスタイルのstdio文字列の間の等価規則を示します。

_Table 132 — 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、修正14.6.2。

これについては、この回答の主要部分で説明します。

30
AndyG