How to save .txt file in C++? [duplicate] - c++

This question already has answers here:
How to append text to a text file in C++?
(5 answers)
Closed 7 years ago.
I have created a code writing stuff in a .txt file and read from it. But if I close the program and start to write again, it deletes the old text and overwrites it with the new one.
Is there a way to not overwrite existed data?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void check() {
string text;
ifstream file;
file.open("test.txt");
getline(file, text);
if (text == "") {
cout << "There's no data in file" << endl;
} else {
cout << "File contains:" << endl;
cout << text << endl;
}
}
int main() {
check();
string text;
ofstream file;
file.open("test.txt");
cout << "Type some text" << endl;
getline(cin, text);
file << text;
return 0;
}

You need to open the file in 'append' mode like in the following example
#include <fstream>
int main() {
std::ofstream outfile;
outfile.open("yourfile.txt", std::ios_base::app);//std::ios_base::app
outfile << "your data";
return 0;
}
You can read here about fstream flagshttp://www.cplusplus.com/reference/fstream/fstream/open/

Keep in mind that in c++ there are several ways to open, save, and read text data to and from a file. It sounds like you opened with with a function (and its options) to always create a new file. One thing you could do is run your program and then close the program and use a text editor to open the file to verify whether the text you wrote to the file is actually there. Also take a look at the code that was provided by Evyatar. That example uses ofstream which allows options for read, write, and append. The "app" parameter tells the program to keep what is already in the file and append any new data that you add in the next run. When testing files where you are appending, be careful you don't end up with a huge file you did not intend to have so large.

In the code that you posted in your revised question, be sure to close the file in your check function and at the end of the program. It is possible to get things hung up if you don't. As a precaution, I usually close a file prior to opening it, just to be sure it is closed with no problems. This practice comes form my days programming in BASIC where it was an essential. If the program crashed, you couldn't open it again until you got it closed. Also, of course, close the file after you're done with it and before the end of the program. Then, when you open it in main, open with the append option.

Please, insert code for next time. If you open file in write mode, than is normal that every time you write to file, the content of file is changed. You need to use append mode.

Related

I can't get the ofstream function to work

Hello and sorry if the answer is clear to those out there. I am still fairly new to programming and ask for some guidance.
This function should write just one of the three string parameters it takes in to the txt file I have already generated. When I run the program the function seems to work fine and the cout statement shows the info is in the string and does get passes successfully. The issue is after running the program I go to check the txt file and find it is still blank.
I am using C++17 on visual studio professional 2015.
void AddNewMagicItem(const std::string & ItemKey,
const std::string & ItemDescription,
const std::string &filename)
{
const char* ItemKeyName = ItemKey.c_str();
const char* ItemDescriptionBody = ItemDescription.c_str();
const char* FileToAddItemTo = filename.c_str();
std::ofstream AddingItem(FileToAddItemTo);
std::ifstream FileCheck(FileToAddItemTo);
AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
if (_access(FileToAddItemTo, 0) == 0)
{
if (FileCheck.is_open())
{
AddingItem << ItemKey;
std::cout << ItemKey << std::endl;
}
}
AddingItem.close(); // not sure these are necessary
FileCheck.close(); //not sure these are necessary
}
This should print out a message onto a .txt file when you pass a string into the ItemKey parameter.
Thank you very much for your help and again please forgive me as I am also new to stackoverflow and might have made some mistakes in formatting this question or not being clear enough.
ADD ON: Thank you everyone who has answered this question and for all your help. I appreciate the help and would like to personally thank you all for your help, comments, and input on this topic. May your code compile every time and may your code reviews always be commented.
As mentioned by previous commenters/answerers, your code can be simplified by letting the destructor of the ofstream object close the file for you, and by refraining from using the c_str() conversion function.
This code seems to do what you wanted, on GCC v8 at least:
#include <string>
#include <fstream>
#include <iostream>
void AddNewMagicItem(const std::string& ItemKey,
const std::string& ItemDescription,
const std::string& fileName)
{
std::ofstream AddingItem{fileName, std::ios::app};
if (AddingItem) { // if file successfully opened
AddingItem << ItemKey;
std::cout << ItemKey << std::endl;
}
else {
std::cerr << "Could not open file " << fileName << std::endl;
}
// implicit close of AddingItem file handle here
}
int main(int argc, char* argv[])
{
std::string outputFileName{"foobar.txt"};
std::string desc{"Description"};
// use implicit conversion of "key*" C strings to std::string objects:
AddNewMagicItem("key1", desc, outputFileName);
AddNewMagicItem("key2", desc, outputFileName);
AddNewMagicItem("key3", desc, outputFileName);
return 0;
}
Main Problem
std::ofstream AddingItem(FileToAddItemTo);
opened the file. Opening it again with
AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
caused the stream to fail.
Solution
Move the open modes into the constructor (std::ofstream AddingItem(FileToAddItemTo, std::ios::app);) and remove the manual open.
Note that only the app open mode is needed. ofstream implies the out mode is already set.
Note: If the user does not have access to the file, the file cannot be opened. There is no need to test for this separately. I find testing for an open file followed by a call to perror or a similar target-specific call to provide details on the cause of the failure to be a useful feature.
Note that there are several different states the stream could be in and is_open is sort of off to the side. You want to check all of them to make sure an IO transaction succeeded. In this case the file is open, so if is_open is all you check, you miss the failbit. A common related bug when reading is only testing for EOF and winding up in a loop of failed reads that will never reach the end of the file (or reading past the end of the file by checking too soon).
AddingItem << ItemKey;
becomes
if (!(AddingItem << ItemKey))
{
//handle failure
}
Sometimes you will need better granularity to determine exactly what happened in order to properly handle the error. Check the state bits and possibly perror and target-specific
diagnostics as above.
Side Problem
Opening a file for simultaneous read and write with multiple fstreams is not recommended. The different streams will provide different buffered views of the same file resulting in instability.
Attempting to read and write the same file through a single ostream can be done, but it is exceptionally difficult to get right. The standard rule of thumb is read the file into memory and close the file, edit the memory, and the open the file, write the memory, close the file. Keep the in-memory copy of the file if possible so that you do not have to reread the file.
If you need to be certain a file was written correctly, write the file and then read it back, parse it, and verify that the information is correct. While verifying, do not allow the file to be written again. Don't try to multithread this.
Details
Here's a little example to show what went wrong and where.
#include <iostream>
#include <fstream>
int main()
{
std::ofstream AddingItem("test");
if (AddingItem.is_open()) // test file is open
{
std::cout << "open";
}
if (AddingItem) // test stream is writable
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
AddingItem.open("test", std::ios::app);
if (AddingItem.is_open())
{
std::cout << "open";
}
if (AddingItem)
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
}
Assuming the working directory is valid and the user has permissions to write to test, we will see that the program output is
open and writable
open and NOT writable
This shows that
std::ofstream AddingItem("test");
opened the file and that
AddingItem.open("test", std::ios::app);
left the file open, but put the stream in a non-writable error state to force you to deal with the potential logic error of trying to have two files open in the same stream at the same time. Basically it's saying, "I'm sorry Dave, I'm afraid I can't do that." without Undefined Behaviour or the full Hal 9000 bloodbath.
Unfortunately to get this message, you have to look at the correct error bits. In this case I looked at all of them with if (AddingItem).
As a complement of the already given question comments:
If you want to write data into a file, I do not understand why you have used a std::ifstream. Only std::ofstream is needed.
You can write data into a file this way:
const std::string file_path("../tmp_test/file_test.txt"); // path to the file
std::string content_to_write("Something\n"); // content to be written in the file
std::ofstream file_s(file_path, std::ios::app); // construct and open the ostream in appending mode
if(file_s) // if the stream is successfully open
{
file_s << content_to_write; // write data
file_s.close(); // close the file (or you can also let the file_s destructor do it for you at the end of the block)
}
else
std::cout << "Fail to open: " << file_path << std::endl; // write an error message
As you said being quite new to programming, I have explicitly commented each line to make it more understandable.
I hope it helps.
EDIT:
For more explanation, you tried to open the file 3 times (twice in writing mode and once in reading mode). This is the cause of your problems. You only need to open the file once in writing mode.
Morever, checking that the input stream is open will not tell you if the output stream is open too. Keep in mind that you open a file stream. If you want to check if it is properly open, you have to check it over the related object, not over another one.

Settings in c++ with file .txt

I would like to make a read and write file in c++. I would also like the information i write be a string. so then i can read that string from the file and see the value. Im gonna use this sort of like a settings file where the program can read your settings that you've used and apply them without having to reconfigure the program everytime. In small here's what i got:
int main()
{
std::string tortilla = "tacos";
std::string godast = "pizza";
std::ofstream MyFile;
MyFile.open("1.txt");
MyFile << tortilla;
MyFile.close();
std::ifstream ReadFile("1.txt");
while (std::getline(ReadFile, tortilla))
As you see the code is not done yet by far but i just want to learn this element for now. Thank you in before.
EDIT: Here i want the output of reading "tortilla" to be tacos. So the string is intact troughout
To output the content of tortilla add:
{
std::cout << "tortilla is " << tortilla << std::endl;
}
And iostream must be included for std::cout. HTH.

C++ (Visual Studio): Recieving nothing when trying to read input from a .txt file

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line = "test";
ifstream myfile("example.txt");
myfile.open("example.txt");
if (myfile.is_open())
{
cout << line << "\n";
cout << "File Opened\n";
getline(myfile, line);
cout << line;
while (getline(myfile, line))
{
cout << line << '\n';
cout << "test";
}
myfile.close();
}
else cout << "Unable to open file";
//return 0;
//getchar();
}
Apologies in advance if this has been answered, but while I've found several answers that are very close to what I need, I can't find an answer to this specific problem.
I'm new to Visual Studio, but have dabbled in c++ in the past. I'm trying to read in data from a text file and (for now) simply print that back out with cout. But, I'm not seeing any results.
At first I figured I just had my txt file in the wrong place - and I did. Initially I would receive the line "Unable to open file", indicating that the file could not be opened. So I moved it around and found out where Visual Studio wanted me to put the file.
So now I successfully see the "File Opened\n" line get printed to the screen, followed by nothing. I thought I might be using getline wrong, but if I replace the file input "myfile" with a "cin" instead, getline will happily read in keyboard input all day, so that's not it either.
So I've put in some test cout statements that print out the value of my string, line. The first one prints out "test" as it should. Then I read in a line of the txt file to that string variable, and when I cout it again I get nothing. It's a blank string.
Also, the line " cout << "test"; " From within the loop does NOT print either. So the loop's not even happening, it seems.
So, as near as I can tell, the program is able to find my textfile, example.txt. But it's not actually seeing the contents within.
The contents of the textfile (and what I'd like the program to print out) are as follows:
"This is the first line
This is the second line
Third
Fourth
Fifth"
Any and all help is much appreciated.
Figured it out.
What went wrong is this line:
ifstream myfile("example.txt");
I don't know exactly why, but since I specify the file to open in the next line down ( myfile.open("example.txt"); ), specifying the filepath in the ifstream declaration caused the issue.
I don't entirely get it, as others have said that the code runs fine for them. But this seems to work, anyway.
If there's any reason why I shouldn't use this solution, please let me know.
you might want to take a look at your file open
"myfile.open("example.txt");" i found if you don't give a file path weird things happen.
myfile.open("c:\test\example.txt");
is the adjustment I made to the code and it work like a dream.

ofstream creating file but not writing to it in C++

I am writing an MFC program that has a dialog with an "Export" button that will take all of the data that has been entered into the file and export it to a .txt (at some point I want to change this to a .msg file...but that's a question for another day).
However, when I click the button, it creates the file but doesn't write anything inside the file. For testing, I removed everything except just a simple literal string and even that isn't printing. Here is the current code for that event: The myfile.flush() statement is leftover from when I had a loop that I was trying to print to the file.
void CEHDAHTTimerDlg::OnBnClickedExport()
{
// in this function, we want to export the items to a text file
std::ofstream myfile("TodayTime.txt");
myfile.open("TodayTime.txt");
if (myfile.is_open())
{
myfile << "The average call time is ";
myfile.flush();
myfile.close();
}
else
{
SetDlgItemText(IDC_EXPORT, L"Export Unsuccessful! -- No File");
}
}
Is there anything you all can think of that could be causing this? I've been at it for a few hours trying different things, like utilizing a myfile.write() function instead. I've searched a lot around here, reddit, and google in general trying to find out why this isn't writing.
I appreciate your help.
EDIT:
Okay, calling the myfile constructor the way that I did, by including the file name, went ahead and did what open file would have done
Thanks for your help!
commenting out the redundant "open" solves it.
#include <iostream>
#include <fstream>
int main()
{
// in this function, we want to export the items to a text file
std::ofstream myfile("TodayTime.txt");
// myfile.open("TodayTime.txt");
if (myfile.is_open())
{
myfile << "The average call time is ";
myfile.flush();
myfile.close();
}
else
{
std::cerr << "didn't write" << std::endl;
}
}
I strongly suspect that you're invoking undefined behaviour by opening and already-open stream.
Here is the explanation:
The call to myfile.open("TodayTime.txt"); will fail because the stream is already associated with the file, setting the failbit.
The call to is_open() will succeed, as the file is open.
Then the call to streaming operator << will fail (because of the failbit).
this is because myfile << "The average call time is "; not working
to fix that
std::ofstream myfile;
myfile.open("TodayTime.txt",std::ios:app) //app for appending you can use trunc for
//truncating file
//for flushing content's of existing file use myfile.flush();
if (!data_pack.is_open())
{
std::cerr << "unable to open the file for writing";
}
myfile << "some stuff tho write you can replace the string with variable"
<<std::endl; //for next line
//at last close file
myfile.close();

Reading File in C++

I am unable to figure out why my code is not able to open and read a file. What am i missing?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char * const argv[])
{
string line;
ifstream myfile ("input_file_1.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
}
else
{
cout << "Was unable to open the file" << endl;
}
return 0;
}
The file "input_file_1.txt" is int he same directory as my .cpp file and it has read permissions. I even gave gave it 777 permissions and i was unable to read it.
Can anyone tell me what i am doing wrong? I really cannot figure it out....
Try to use full path for the file
The default location to look for the file is where the executable is , not where the source is.
How and where do you execute your program? From a IDE?
Can you run the program from the same directory where you have your text file.
Another possibility is to use an absolute path to the file.
If you don't specify a path, the library will attempt to load the file from the current directory. You need to make sure that this is where the file is.
Also, you might not be able to open the file if it is opened in an exclusive manner by another program. Ensure that it is not still open in another program such as your editor.
Other Problems:
Explicitly testing for EOF is usually wrong.
The last valid read (getline() here) reads up-to but no past the EOF. You then print the line. Then restart the loop. These test for eof() does not fail (as it has not read past the EOF). You then enter the loop body and attempt to read the next line (with getline()) this fails as there are 0 bytes left to read (thus leaving the value of line in an undefined state). You then print out line (undefined value) and a newline character.
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
A correct version of a loop reading a file is:
while (getline (myfile,line))
{
cout << line << endl;
}
This works because the getline() returns a reference to a stream. A stream used in a boolean context (like a while condition) tests to see if the stream is in a bad state (ie it test for EOF and other bad situations) and returns an object that can be used correctyl in the context. If the state of the stream is OK then a successful read has happened and the loop is entered (thus allowing you to print the line).
The binary created from your code (including your cpp) is executed somewhere different from your code is, probably a "bin"-folder. You schould put the file into the same folder as your executable.