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.