Trying to manipulate files in c++ - c++

When using <fstream> library to open and add a stream to an existing file test.rtf and I use the following lines:
char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("test.rtf");
if (outfile.is_open()) { cout << "file is open" << endl; }
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
And when reading it by using ifstream, the lines input are displayed correctly. The problem is the output file is not modified and lines I have added are not saved. The question might sound very stupid but it's a problem I could not resolve.

When you << to your file you are just writing to a buffer, not actually "flushing" it to the file itself. If you just close your file you should be fine.
So:
outfile.close()
Also in the future you can flush (actually write from buffer to the file) when you want to write to a file but not close it. .close() flushes then closes for you automatically.

Related

Opening a C++ .txt file using user-input

I'm trying to open a C++ .txt file as shown in my code below. This is part of a larger program that I'm working on where I write the contents of one file into another so that it contains the same information as the original but I am required to provide user-input. If the user-provides a .txt file that is not the one we are using, I have to produce an error message and prompt them to re-enter an input until they input the correct one (test.txt):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
/* Refers to test.txt */
ofstream mainfile;
std::string filename;
std::cout << "Please enter the name of your data file: ";
std::cin >> filename;
mainfile.open(filename.c_str());
mainfile << "test.txt";
if(!mainfile) {
std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl;
std::cout << "Please enter another name: " <<
std::endl;
std::cin >> filename;
} else {
std::cout << "File '" << filename << "' opened successfully!" << std::endl;
}
return 0;
}
My current issue is that the program is terminating too early, even when I input incorrect inputs such as jaguar.txt or flowers.txt, anything that isn't "test.txt". In fact, when I input just about any .txt file name it will output saying that it opened successfully.
It seems that what you want to do is open up 2 different files, where one is used as the file to copy from (test.txt), and the other is the file to copy to (jaguar.txt). Instead of checking if test.txt exists with std::ofstream, you should instead use std::ifstream.
Using ifstream, if the file does not exist, your code will work properly. Instead, because you are currently using ofstream, the file will open correctly, because you're essentially telling it to make the file for you.
So basically, where you have used ofstream mainfile, instead it should be:
ifstream mainfile;
Later in the code, you can prompt the user for the file to copy to (i.e. jaguar.txt), and this will be the one where you output data using ofstream.
Use ifstream to read from a file, and ofstream to write to a file.
To check whether the source file exists, test the corresponding ifstream after trying to open it:
ifstream mainfile; // ifstream stands for "input file stream"
std::cout << "Please enter the name of your data file: ";
std::cin >> filename;
mainfile.open(filename);
while (!mainfile) { // asking endlessly, until the user inputs a good file
std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl;
std::cout << "Please enter another name: " <<
std::endl;
std::cin >> filename;
mainfile.open(filename);
}
std::cout << "File '" << filename << "' opened successfully!" << std::endl;
By the way, in the error message "open" is programmer's jargon. It's a general word which includes both reading and writing. If your application copies stuff from one file to the other, the user may get confused: is there a problem with input or output? You might want to say "read" instead of "open", even though technically you didn't read anything yet. That would make a clearer error message.
If you want to copy one file to another, use one of the methods described in a dedicated question.

C++ Write Run Output to File

I have a program with a small game which I created, I want to save a log at the end of the game which takes all of the 'Run' output to a text file. Its a pretty hefty game which uses multiple different classes and states so I wont be posting the code. However this is my save function:
void saveState(){
string inputFile;
std::cout << "Please enter a file to write to:" << std::endl;
std::cin >> inputFile;
std::ofstream myFile;
myFile.open(inputFile);
myFile << "Hello";
myFile.close();
std::cout << "Saving to file " << inputFile << std::endl;
}
Is there any possible way to fetch the output and put it into a text file?
This is my output for reference:
Also I am using CLion if that means anything?

ofstream, when will it fail instead of creating a new file?

i just started reading on how to open and edit files.
when working with ifstream, if the file doesnt exist, it wont be created.
in reference to the code below, when would the condition (!outfile) be false, as if the file doesn't exists it will simply be created by the constructor, hence always making the condition false.
int main()
{
ofstream outfile ("test1.txt");
if (!outfile)
{
cout << "cannot create file test1.txt" << endl;
return 1;
}
outfile << 10 << " " << 345.12 << endl;
outfile << "This is a short text file";
outfile.close();
system("PAUSE");
return 0;
}
One way opening an ofstream could fail is if the file in the given path exists, but you do not have the permission to write to it. Alternatively, if the file does not exist but you do not have permission to create a file in the given path, opening the ofstream should also fail.
Another failing situation could be if the files does not exist, and the underlying device does not have sufficient free space/inodes to create one.

C++: How can I switch between input and output from file?

I'm trying to write up a program that will display the contents of a text file to the screen for a user. Specifically, the text file will be a list of names that the program will read and display each name to the user individually. The user will then either like the name and keep it or dislike the name and remove it.
My dilemma is: if the user elects to keep the name, the program will need to go from reading the file to "writing" (deleting the name) the file and then back to reading the file again! I found the following relevant code on http://www.tutorialspoint.com/cplusplus/cpp_files_streams.htm. It shows that one must use .close() to switch from reading to writing, but this seems funky to a newbie like me. Is there a better way to do it or is the code below just fine?
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// again write inputted data into the file.
outfile << data << endl;
// close the opened file.
outfile.close();
This is where the file goes from write mode to read mode.
// open a file in read mode.
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// write the data at the screen.
cout << data << endl;
// again read the data from the file and display it.
infile >> data;
cout << data << endl;
// close the opened file.
infile.close();
return 0;
}
Also, I'm having a hard time finding how to read and modify individual characters in the file. I need to do this too, as the file needs to follow a specific pattern, with five names per line and one space between each name (newline at end of fifth name, obviously). Help with this would be appreciated.
Changing things mid-file is complicated.
What I would do is either create a temporary file, write the kept names to that file and replace the original file with this temporary file, (or just store the kept names in a vector and rewrite the file)
try
std::fstream ff("io.txt", std::fstream::in | std::fstream::out);
and fstream::read, fstream::write, fstream::seekg
If the file is small then load it into memory.
Otherwise use fopen with "a+" or "r+" mode and fseek.

C++ subsequent files fail to open after first file

After the program reads the file, gets characters from the file, and finishes, the user is asked if they want another file read or not. If the user say yes, then the program asks for the file name, but then automatically says the file could not be opened and exits the loop. Please help me.
Here is the code:
do //do while opening the source file fails
{
cout << "Enter filename of source file: ";
cin.getline (filename,51);
sourceFile.open(filename); //opens the file with given filename
if (sourceFile.fail())
cout << "File could not be opened" << endl; //error if can't open
sourceFile.clear();
}
while (sourceFile.fail()); //exits if source file doesn't fail
This test:
while (sourceFile.fail())
will never be true because just before you get there you call:
sourceFile.clear()
which will clear any problem bits in the iostate for the stream.
I think you just want to get rid of the call to clear().
The canonical way to check if opening the file failed is to use std::basic_ios::operator !():
do
{
cout << "Enter filename of source file: ";
std::getline(std::cin, filename);
sourceFile.open(filename.c_str());
if (!sourceFile)
{
cout << "File could not be opened" << endl;
}
}
while (!sourceFile);