ofstream open modes: ate vs app

c++, fstream, visual-studio-2012

Solution

You need to combine `std::ios::in` with `std::ios::ate` then seek the end of the file and append the text:

Consider I have a file "data.txt" which contains this line:

"Hello there how are you today? Ok fine thanx. you?"

Now I open it:

1: std::ios::app:

std::ofstream out("data.txt", std::ios::app);

out.seekp(10); // I want to move the write pointer to position 10

out << "This line will be appended to the end of the file";

out.close();

The result is not what I wanted: No moving the write pointer but only the text is always appended to the end.

2: std::ios::ate:

std::ofstream out2("data.txt", std::ios::ate);

out2 << "This line will be ate to the end of the file";

out2.close();

The result above is not what I wanted no text appended but the content is truncated!

To solve it combine `ate` with `in`:

std::ofstream out2("data.txt", std::ios::ate | std::ios::in);

out2 << "This line will be ate to the end of the file";

out2.close();

Now the text is appended to the end but what is the difference:

As I said app doesn't allow moving the write pointer but ate does.

std::ofstream out2("data.txt", std::ios::ate | std::ios::in);

out2.seekp(5, std::ios::end); // add the content after the end with 5 positions.

out2 << "This line will be ate to the end of the file";

out2.close();

Above we can move the write pointer to the position we want while with app we cannot.

- Look at this example: https://www.youtube.com/watch?v=6cDcTp1gn4Q

Problem

This question asks the difference between `app` and `ate` and both the answers and cppreference imply that the only difference is that `app` means that the write cursor is put at the end of the file before each write operation, whereas `ate` means that the write cursor is put at the end of the file only when opening. What I'm actually seeing (in VS 2012) is that specifying `ate` discards the contents of an existing file, whereas `app` does not (it appends new content to the previously existing content). In other words, `ate` seems to imply `trunc`. The following statement appends "Hello" to an existing file: ``` ofstream("trace.log", ios_base::out|ios_base::app) << "Hello\n"; ``` But the following statement replaces the contents of the file with just "Hello": ``` ofstream("trace.log", ios_base::out|ios_base::ate) << "Hello\n"; ``` The MSDN documentation for VS 6.0 implies that shouldn't happen (but this sentence seems to have been withdrawn in later versions of Visual Studio): ios::trunc: If the file already exists, its contents are discarded. This mode is implied if ios::out is specified, and ios::ate, ios::app, and ios:in are not specified.

Original source

Related problems