Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ofstream("log.txt", ios::app|ios::trunc); always fail?

Tags:

c++

iostream

The following code was compiled with VC++ Nov 2012 CTP on Windows 7 x64.

#include <fstream>

using namespace std;

int main()
{
    ofstream fout("log.txt", ios::app|ios::trunc);
    if (!fout)
    {
        cout << "An error occurred!" << endl; // Always go here! Why?
    }
}

The cppreference.com website doesn't say that ios::app cannot be combined with ios::trunc.

What are the exact semantics of ios::app and ios::trunc?

like image 414
xmllmx Avatar asked Feb 26 '13 07:02

xmllmx


2 Answers

The filebuf constructor to which these flags are passed has behaviours based on those flags defined in Table 132 in C++11:

+-----------------------------------+-------------------+
|     ios_base flag combination     |  stdio equivalent |
| binary  in    out    trunc    app |                   |
+-----------------------------------+-------------------+
|               +                   |  "w"              |
|               +               +   |  "a"              |
|                               +   |  "a"              |
|               +       +           |  "w"              |
|        +                          |  "r"              |
|        +      +                   |  "r+"             |
|        +      +       +           |  "w+"             |
|        +      +               +   |  "a+"             |
|        +                      +   |  "a+"             |
+-----------------------------------+-------------------+
|   +           +                   |  "wb"             |
|   +           +               +   |  "ab"             |
|   +                           +   |  "ab"             |
|   +           +       +           |  "wb"             |
|   +    +                          |  "rb"             |
|   +    +      +                   |  "r+b"            |
|   +    +      +       +           |  "w+b"            |
|   +    +      +               +   |  "a+b"            |
|   +    +                      +   |  "a+b"            |
+-----------------------------------+-------------------+

As you can see, your flag combination is not found in that table.

[C++11: 27.9.1.4/2]: [..] If mode is not some combination of flags shown in the table then the open fails.

Those are the semantics.

[C++11: 27.9.1.7/2] & [C++11: 27.9.1.11/2] show us that the mode is passed from the stream object to the buffer object.

like image 194
Lightness Races in Orbit Avatar answered Nov 17 '22 06:11

Lightness Races in Orbit


  • app (=append): set the stream's position indicator to the end of the stream before each output operation
  • trunc (=truncate) any current content is discarded, assuming a length of zero on opening.

As you can see, it doesn't make sense to put both together.

like image 26
Matthias Avatar answered Nov 17 '22 07:11

Matthias