How to append text to a text file in C++? - c++

How to append text to a text file in C++? And create a new text file if it does not already exist and append text to it if it does exist.

You need to specify the append open mode like
#include <fstream>
int main() {
std::ofstream outfile;
outfile.open("test.txt", std::ios_base::app); // append instead of overwrite
outfile << "Data";
return 0;
}

I use this code. It makes sure that file gets created if it doesn't exist and also adds bit of error checks.
static void appendLineToFile(string filepath, string line)
{
std::ofstream file;
//can't enable exception now because of gcc bug that raises ios_base::failure with useless message
//file.exceptions(file.exceptions() | std::ios::failbit);
file.open(filepath, std::ios::out | std::ios::app);
if (file.fail())
throw std::ios_base::failure(std::strerror(errno));
//make sure write fails with exception if something is wrong
file.exceptions(file.exceptions() | std::ios::failbit | std::ifstream::badbit);
file << line << std::endl;
}

#include <fstream>
#include <iostream>
FILE * pFileTXT;
int counter
int main()
{
pFileTXT = fopen ("aTextFile.txt","a");// use "a" for append, "w" to overwrite, previous content will be deleted
for(counter=0;counter<9;counter++)
fprintf (pFileTXT, "%c", characterarray[counter] );// character array to file
fprintf(pFileTXT,"\n");// newline
for(counter=0;counter<9;counter++)
fprintf (pFileTXT, "%d", digitarray[counter] ); // numerical to file
fprintf(pFileTXT,"A Sentence"); // String to file
fprintf (pFileXML,"%.2x",character); // Printing hex value, 0x31 if character= 1
fclose (pFileTXT); // must close after opening
return 0;
}

You could use an fstream and open it with the std::ios::app flag. Have a look at the code below and it should clear your head.
...
fstream f("filename.ext", f.out | f.app);
f << "any";
f << "text";
f << "written";
f << "wll";
f << "be append";
...
You can find more information about the open modes here and about fstreams here.

You could also do it like this
#include <fstream>
int main(){
std::ofstream ost {outputfile, std::ios_base::app};
ost.open(outputfile);
ost << "something you want to add to your outputfile";
ost.close();
return 0;
}

Related

C++ fstream writes garbage to file

The code below creates a vector that contains a vector of chars. It opens a fstream to a file. and then write the first char from the first vector. I tried to methods to write the char. Finally, I tried open a new 'fstream' and from it to print what I wrote. Both the printing and a simple inspection of the file shows it contian nothing, or sometimes garbage (dependening on the order of the writes). No errors or any weried output appear. I'm really loosing my mind over this.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
std::vector<char> y(6, 0);
y[0] = 1;
std::vector<std::vector<char>> vy;
vy.push_back(y);
std::fstream dateir("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
dateir<<vy[0][0] << endl;
int temp = vy[0][0];
dateir.write((char *)&temp, sizeof(int));
dateir.close();
cout << "here" << endl;
std::ifstream dateir2("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
if (dateir2.is_open())
{
std::cout << dateir2.rdbuf();
}
else{
cout << "no";
}
dateir2.close();
cout << "end";
return 0;
}
You have...a number of problems here.
std::fstream dateir("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
Is there a reason you've specified std::ios::out | std::ios::out? It's harmless, but clearly redundant.
As a first stab at things, I'd simplify the code a bit:
std::ofstream out("ffff.dat", std::ios::binary);
int data = 1;
out.write((char *)&data, sizeof(data));
out.close();
std::ifstream in("ffff.dat", std::ios::binary);
int data2;
in.read((char *)&data2, sizeof(data2));
if (data == data2) {
// what we read matched what we wrote
} else {
// what we read didn't match what we wrote
}
When you write binary data to a file, you usually want to just read it back in the way you wrote it out. If you want to look at the individual characters, you can do that but to get something that's semi-readable, you probably want to print them out in hexadecimal, or something on that order (and for this sort of exercise to mean much, you'd probably want to print it out in hex both before writing it out, and after reading it back in, to show they match, and let the reader see a reasonable understandable representation of the file contents).

How to use a single fstream for creation, reading and writing a file

I would like to access a file through fstream with the following requirements:
If the files does not exists, it create it
The file can be read (from pos 0)
The file can be (over)written (from pos 0)
Without closing and re-opening the file
ios_base::in seems to disable file creation
ios_base::out seems to disable file reading
Is this possible? How?
#include <iostream>
#include <sstream>
#include <fstream>
#include <cassert>
using namespace std;
int main()
{
auto mode = ios_base::in|ios_base::out;
std::string filePath = "./test.txt";
std::string content1 = "Any content 1";
std::string content2 = "Any content 2";
{
std::remove(filePath.c_str());
}
{// Test creation
// make sure test.txt is missing / does not exists
fstream file(filePath, mode);
assert(file.is_open() && file.good());
file << content1;
}
{ // Test reading & writing
fstream file(filePath, mode);
// read
file.seekg(0);
std::stringstream buffer1;
buffer1 << file.rdbuf();
cout << buffer1.str() << endl;
assert(buffer1.str()==content1);
// write
file.seekp(0);
file << content2;
assert(file.is_open() && file.good());
// read
file.seekg(0);
std::stringstream buffer2;
buffer2 << file.rdbuf();
cout << buffer2.str() << endl;
assert(buffer2.str()==content2);
}
return 0;
}
Run it
Only with fstream I'd say no.
You might want to have something similar with the trunc mode but you'll lose everything if the file exists (which might be a problem, if not go for trunc + out)
The other way is to check if the file exists, if not you create it (whichever way). Then you open with In and Out and do your stuff.
It kind of doesn't make sense to be able to read inside an empty file you just created from the cpp point of view

Error copying text from one file to another c++ fstream

This is my code
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream file;
file.open("text.txt", std::fstream::in | std::fstream::out |
std::fstream::app);
if(!file.is_open())
{
std::cout << "Could not open file(test.txt)" << std::endl;
} else {
file << "These are words \nThese words are meant to show up in the new file \n" <<
"This is a new Line \nWhen the new fstream is created, all of these lines should be read and it should all copy over";
std::string text;
file >> text;
std::cout << text << std::endl;
file.close();
std::fstream newFile;
newFile.open("text2.txt", std::fstream::in | std::fstream::out |
std::fstream::app);
if(newFile.is_open())
{
newFile << text;
}
}
}
I'm trying to copy the contents of text.txt to text2.txt but for some reason the text string always ends up empty. I've checked the files and text gets populated but text2 is empty. What's going wrong here?
When you append a string to an fstream, the input / output position is set to the end of the file. This means that when you next read from the file, all you will see is an empty string.
You can check what the current input position is by using:
file.tellg()
And set the input / output position to the start by using:
file.seekg(0)
The full reference for std::fstream is here.
You're trying to read from the end of the file. The position is set to the end of the last thing you wrote to the file, so, if you want to read what you wrote, you have to reset it:
file.seekg(0);
This will set the position for the input back to the start of the file. Note however that reading from the file the way you do now will simply get you 1 word (up to the first whitespace). If you want to read it all, perhaps you should look at something like: Read whole ASCII file into C++ std::string.

Writing a string to the end of a file (C++)

I have a program already formed that has a string that I want to stream to the end of an existing text file. All of what little I have is this: (C++)
void main()
{
std::string str = "I am here";
fileOUT << str;
}
I realize there is much to be added to this and I do apologize if it seems I am asking people to code for me, but I am completely lost because I have never done this type of programming before.
I have attempted different methods that I have come across the internet, but this is the closest thing that works and is somewhat familiar.
Open your file using std::ios::app
#include <fstream>
std::ofstream out;
// std::ios::app is the open mode "append" meaning
// new data will be written to the end of the file.
out.open("myfile.txt", std::ios::app);
std::string str = "I am here.";
out << str;
To append contents to the end of files, simply open a file with ofstream (which stands for out file stream) in app mode (which stands for append).
#include <fstream>
using namespace std;
int main() {
ofstream fileOUT("filename.txt", ios::app); // open filename.txt in append mode
fileOUT << "some stuff" << endl; // append "some stuff" to the end of the file
fileOUT.close(); // close the file
return 0;
}
Open your stream as append, new text written to it will be written at the end of the file.
I hope that isn't your whole code because if it is, there's lots of things wrong with it.
The way you would write out to a file looks something like this:
#include <fstream>
#include <string>
// main is never void
int main()
{
std::string message = "Hello world!";
// std::ios::out gives us an output filestream
// and std::ios::app appends to the file.
std::fstream file("myfile.txt", std::ios::out | std::ios::app);
file << message << std::endl;
file.close();
return 0;
}

Why can't I read and append with std::fstream on Mac OS X?

Consider the following C++ program, which takes a file and prints each line. It's a slice of a larger program where I later append to the file, based on what I see.
#include <fstream>
using std::fstream;
#include <iostream>
#include <string>
using std::string;
int main()
{
fstream file("file.txt", fstream::in | fstream::out | fstream::app);
string line;
while (std::getline(file, line))
std::cerr << line << std::endl;
return 0;
}
Now apply this version of file.txt (One word on the first line, followed by a newline):
Rain
On my machine (Snow Leopard), this prints out nothing. On closer inspection, the first call to getline fails. Strangely, it also fails if I add a second line: still nothing is printed!
Can anyone solve this mystery?
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.
You should check if the file has actually been opened:
if (!file)
std::cerr << "Oh dear" << std::endl;
Update: in fact the file likely has been opened, but is in append mode - see Neii's answer.
Update 2: okay, wrong again. In Leopard's g++ at least, the file will not be opened because the app flag is incompatible with the in flag. So the above check will print Oh dear.
In MSVC++, it goes ahead and opens the file, apparently with the read position at the start, which explains why other people saw it work and I apologise for doubting their veracity!