How to Append to a File with Fstream Fstream::App Flag Seems Not to Work

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]

file io

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



Leave a reply



Submit