How to append to a file with fstream fstream::app flag seems not to work
fstream::app|fstream::out
instead of fstream::app
. app
doesn't make sense without specifying out
(one could think it should have implied out
, but it doesn't).
How to append file in c++ using fstream?
This works.. std::fstream::in | std::fstream::out | std::fstream::app
.
#include <fstream>
#include <iostream>
using namespace std;
int main(void)
{
char filename[ ] = "Text1.txt";
fstream uidlFile(filename, std::fstream::in | std::fstream::out | std::fstream::app);
if (uidlFile.is_open())
{
uidlFile << filename<<"\n---\n";
uidlFile.close();
}
else
{
cout << "Cannot open file";
}
return 0;
}
How to append to a std::fstream after you got to the end (std::fstream::eof() is true)
First, there is no need to state std::ios::in
and std::ios::out
when using a fstream
because they are there the default value in the constructor. (it is actually std::ios_base::in/out
to be more exact. std::ios
(std::basic_ios<char>
) inherits from std::ios_base
)
So std::fstream file(filename)
works the same.
The problem here is how C++ streams work.
When the file is read completely, the eofbit
is set. After that, another reading happens which will trigger the failbit
because there is nothing to read and the stream's bool conversion operator returns false and it exits the loop.
The bits will stay on until they are cleared. And while they are on, the stream doesn't do anything.
So to clear them:
file.clear();
Will do the work. You can use the stream after that.
appending to a file with ofstream
I use a very handy function (similar to PHP file_put_contents)
// Usage example: filePutContents("./yourfile.txt", "content", true);
void filePutContents(const std::string& name, const std::string& content, bool append = false) {
std::ofstream outfile;
if (append)
outfile.open(name, std::ios_base::app);
else
outfile.open(name);
outfile << content;
}
When you need to append something just do:
filePutContents("./yourfile.txt","content",true);
Using this function you don't need to take care of opening/closing. Altho it should not be used in big loops
Reading file with fstream then closing and reading again wont work on Android
Get rid of the std::ios_base::trunc
flag when re-opening the file:
discard the contents of the stream when opening
After you write to the file, close it, and reopen it, you are wiping out everything you had previously written.
Why can't I read and append with std::fstream on Mac OS X?
When you say:
fstream file("file.txt", fstream::in | fstream::out | fstream::app);
you open the file in append mode - i.e. at the end. Just open it in read mode:
fstream file("file.txt", fstream::in );
or use an ifstream:
ifstream file("file.txt" );
And of course as Earwicker suggests, you should always test that the open succeeded.
If you are determined to open in append mode, you can move the read pointer explicitly:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
fstream file( "afile.txt", ios::in | ios::out | ios::app );
if ( ! file.is_open() ) {
cerr << "open failed" << endl;
return 1;
}
else {
file.seekg( 0, ios::beg ); // move read pointer
string line;
while( getline( file, line ) ) {
cout << line << endl;
}
}
}
Edit: It seems that the combination of flags used in the opening of the file leads to implementation specific behaviour. The above code works with g++ on Windows, but not with g++ on Linux.
std::ofstream with std::ate not opening at end
As you can see from the following chart in N4296 [filebuf.members]
The combination binary | out
will open the file in the stdio
equivalent of "wb"
, which will truncate to zero length or create binary file for writing
(N1570 7.21.5.2).
As counterintuitive as it sounds for an ofstream
, you will need to add the in
flag if you don't want your file to be truncated, or app
if you want to avoid truncation and seek to the end of the file on each write.
Bonus tip: Unlike fstream
, ifstream
and ofstream
will automatically or std::ios_base::in
and std::ios_base::out
respectively with any flags you provide to the constructor or to open
. You can also use the object itself to access the flags:
std::ofstream check("test", check.in | check.binary | check.ate);
The checks for good
can also be shortened to if (!initial)
etc.
Related Topics
After Sending a Lot, My Send() Call Causes My Program to Stall Completely. How Is This Possible
Cost of Using Std::Map with Std::String Keys VS Int Keys
Building Qt 4.5 with Visual C++ 2010
Boost Spirit X3: Parse into Structs
How to Create a N Way Cartesian Product of Type Lists in C++
Optimal Buffer Size for Write(2)
Boost Graph Copy and Removing Vertex
How to Check That I Didn't Break Anything When Refactoring
Use Static_Assert to Check Types Passed to MACro
Is Returning Local Static Object Thread Safe for Pre-C++11 Compilers
How to Invoke Pointer to Member Function When It's a Class Data Member
Best C++ Matrix Library for Sparse Unitary Matrices
Is Static Object Guaranteed to Be Initialized
Openmp and Reduction on Std::Vector
Using Boost Tokenizer Escaped_List_Separator with Different Parameters