25

If you call the std::ofstream constructor without openmode flags, the default flag is ios_base::out. But does this imply ios_base::trunc or ios_base::app?

In other words, if you already have a non-empty file "past.txt" in your file system and you call

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

will "new content" be appended to the prior contents of "past.txt" or will it replace the prior contents?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
OldPeculier
  • 11,049
  • 13
  • 50
  • 76
  • 4
    I have a feeling this question is based on wrong choice of the reference. [This](http://en.cppreference.com/w/cpp/io/basic_filebuf/open) should be better. – LogicStuff Aug 31 '16 at 18:49
  • `ios_base::out` is the same as `ios_base::out | ios_base::trunc`. I can't find a good reference link, but a google search hit on a couple of [text books](https://books.google.com/books?id=eC-iLe_iET8C&pg=PA1124&dq=Same+as+ios_base::out+%7C+ios_base::trunc.&hl=en&sa=X&ved=0ahUKEwip8ZfRquzOAhVCGB4KHSJuD84Q6AEIHDAA#v=onepage&q=Same%20as%20ios_base%3A%3Aout%20%7C%20ios_base%3A%3Atrunc.&f=false), – CAB Aug 31 '16 at 19:01
  • As per LogicStuff's link, the ofstream ctor default is `out` which behaves the same in `basic_filebuf::open` as `out|trunc`, and therefore truncates. – Useless Aug 31 '16 at 19:02
  • 2
    I'm voting to close this question as off-topic because the answer can be easily found from the right reference material available. (Just testing out yourself will proof) – πάντα ῥεῖ Aug 31 '16 at 19:03
  • 1
    Sounds like this might be another case of [what's wrong with cplusplus.com](http://stackoverflow.com/questions/6520052/whats-wrong-with-cplusplus-com), though this time it's just an omission... – jaggedSpire Aug 31 '16 at 19:05

1 Answers1

53

The short version

It truncates by default.


The medium version

The standard is basically spaghetti on this, but it eventually boils down to saying that it's the equivalent of saying fopen(const char*, "w") (27.9.1.4 [filebuf.members]), which then points us towards the ISO C 7.9 standard.

Checking that out provides us with §7.19.5.3, "The fopen function", which specifies the behavior when "w" is passed:

w truncate to zero length or create text file for writing


The long version

If you'd like to follow the spaghetti trail yourself, start with 27.9.1.11 [ofstream.cons], which describes the constructor's behavior as

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).

Where rdbuf() returns basic_filebuf<charT,traits>* (27.9.1.13 [ofstream])

Which leads us to 27.9.1.1 [filebuf], or more specifically, 27.9.1.4 [filebuf.members] , which describes the open function:

basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);

as

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: Null-terminated byte-string

Table 132 describes equivalence rules between C++ ios_base::openmode and C-style stdio strings:

Table 132 — File open modes
|
|   'ios_base' flag combination   | 'stdio' equivalent |
| binary | in | out | trunc | app |                    |
|        |    |  +  |       |     |        "w"         |
|                     etc...                           |

Which leads us to a footnote on the same page that states:

...the function signatures fopen(const char*, const char*) and fseek(FILE*, long, int) are declared, in <cstdio> (27.9.2).

Which sends us, predictably, to 27.9.2 [c.files], which provides the nearly useless Table 134, but then references the C standard:

See also: ISO C 7.9, Amendment 1 4.6.2.

Which I talk about in the main portion of this answer.

AndyG
  • 39,700
  • 8
  • 109
  • 143