How to save and also read c++ fstream file without closing it - c++

I opened a file both read and write mode
using the following statement
file.open(fileName, ios::in | ios::out | ios::trunc);
my main purpose for opening the file in both mode is, read and write the file at the same time.
But In my code scenario,
when I am reading the file after writing it, the ouput showing blank that means,
it is not saving my writing contents because I am not closing it.
And I want to close the file after finishing both write and read the operation
I found a solution in Stack Overflow,
to use flush() function to save the file without closing
file.flush();
but, the problem is it's not working for my case
So, how can I save c++ fstream file without closing?
Here's my full code for better understanding
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
string fileName = "text.txt";
fstream file;
file.open(fileName, ios::in | ios::out | ios::trunc);
if (file.is_open())
{
file << "I am a Programmer" << endl;
file << "I love to play" << endl;
file << "I love to work game and software development" << endl;
file << "My id is: " << 1510176113 << endl;
file.flush(); // not working
}
else
{
cout << "can not open the file: " << fileName << endl;
}
if (file.is_open())
{
string line;
while(file)
{
getline(file, line);
cout << line << endl;
}
}
else
{
cout << "can not read file: " << fileName << endl;
}
file.close();
return 0;
}

Actually, if you want to save any file immediately without closing the file, then you can simply use
file.flush();
But if you are want to read the file without closing just after writing it, you can simply use
file.seekg(0);
actually seekg() function resets the file pointer at the beginning, for this, it is not mandatory to save the file. so, this has nothing to with flush() function
but you can do both if you want to

Before reading from that file you need to make sure to place the pointer to that file to the beginning of the file. After writing to the file it'll point to the end. Therefore you won't be able to read anything.
You need to use file.seekg(0); somewhere after the file.flush() but before starting to read to place the file pointer to the very beginning.
Update
This should work without the flush. However this will depend on the implementation of the std library. Although I'd consider this as bug if it doesn't work without calling flush() imho it does not hurt to call it explicitly.

Related

In C/C++, How to inplace edit a file?

In general I read and edit a file in C++ with following code
#include <iostream>
#include <fstream>
using namespace std;
int main(){
char text[200];
fstream file;
file.open ("example.txt", ios::out | ios::in );
cout << "Write text to be written on file." << endl;
// Reding from file
file >> text;
cout << text << endl;
// Writing on file
cin.getline(text, sizeof(text));
file << text << endl;
//closing the file
file.close();
return 0;
}
but if the text file is very huge; say 2GB, and i just want to change a single word and save it, how to write a file so that only the sector with the edit is effected on the disc instead of rewriting whole file. How to inplace edit a file?
I have seen app called subler on macos to just add subtitles to a huge movie file and save it without rewriting entire movie file in just few seconds! so I knew inplace editing a file is possible.

Why does ofstream work here, but not fstream?

I am trying to understand a difference between std::ofstream and std::fstream. I have this code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
//create an output stream to write to the file
//append the new lines to the end of the file
ofstream myfileI ("input.txt", ios::app);
if (myfileI.is_open())
{
myfileI << "\nI am adding a line.\n";
cout << myfileI.fail() << "\n";
myfileI << "I am adding another line.\n";
cout << myfileI.fail() << "\n";
myfileI.close();
}
else cout << "Unable to open file for writing";
The fail bits return 0, so it is writing.
But the fail bits return 1 when I use the exact same code but instead use fstream instead of ofstream.
input.txt is just this:
Read and write to this file.
What am I doing here?
This is not a good example of a file
I see no practical difference between the two cases you describe.
The ONLY technical difference is that ofstream always has the ios::out flag enabled, which will be added to any flags you specify. Whereas fstream has the ios::in and ios::out flags enabled by default, but will be overriden by any flags you specify.
So, in the ofstream case you are opening the file in ios::out | ios::app mode, whereas in the fstream case you are opening the file in just ios::app mode.
But, both streams delegate to std::filebuf, and according to this reference for std::filebuf::open(), both out|app and app modes act the exact same way - as if fopen(filename, "a") were used, thus they will both "Append to file" if the file exists, and "Create new" if the file does not exist.

How to write and read a file with `fstream` simultaneously in c++?

I'm trying to write some text to a file and then read it using only 1 fstream object.
My question is very similar to this question except for the order of the read/write. He is trying to read first and then write, while I'm trying to write first and then read. His code was able to read but did not write, while my code is able to write but not read.
I've tried the solution from his question but it only works for read-write not write-read.
Here is my code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream fileObj("file.txt", ios::out|ios::in|ios::app);
// write
fileObj << "some text" << endl;
// read
string line;
while (getline(fileObj, line))
cout << line << endl;
}
The code writes some text to file.txt successfully but it doesn't output any text from the file. However, if I don't write text to the file (remove fileObj << "some text" << endl;), the code will output all text of the file. How to write first and then read the file?
This is because your file stream object has already reached the end of the file after the write operation. When you use getline(fileObj, line) to read a line, you are at the end of the file and so you don't read anything.
Before beginning to read the file, you can use fileObj.seekg(0, ios::beg) to move the file stream object to the beginning of the file and your read operation will work fine.
int main()
{
fstream fileObj("file.txt", ios::out | ios::in | ios::app);
// write
fileObj << "some text" << endl;
// Move stream object to beginning of the file
fileObj.seekg(0, ios::beg);
// read
string line;
while (getline(fileObj, line))
cout << line << endl;
}
Although this answer doesn't qualify for your requirement of "reading and writing a file simultaneously", keep in mind that the file will most likely be locked while being written to.
Here the simple example to write and read the file.
Hope it will help you.
#include<fstream>
using namespace std;
int main ()
{
ofstream fout ("text.txt"); //write
ifstream fin ("text.txt"); // read
fout<<"some text";
string line;
while (fin>> line) {
cout<<line;
}
return 0;
}

Writing file doesn't work properly

I'm trying to save some of my input to a file, but it doesn't seem to work. I don't know if its the file extension or whatever, but I've tried to modify it for an hour now, however it doesn't pop-up some file in my folder.
This is how my code works (not posting everything, would be too long)
This is my function:
void mobiltelefon::savePhoneOnFile() const
{
ofstream out;
out.open("C:\\temp\\phones.txt", ios::in);
out << this->numberofphones << endl;
for (int i = 0; i < this->numberofphones; i++) {
out << this->phones[i]->getPhonename() << endl;
out << this->phones[i]->getPrice() << endl;
}
out.close();
}
This is how I call it in main:
case 7:
cout << "Save the phones on file" << endl;
fb.savePhoneOnFile();
break;
I can't see my mistake. Why doesn't the file show up a file in my folder when I try to save it?
If you are trying to open the file for writing, you should be using ios::out as the second argument
ofstream out("C:\\temp\\phones.txt", ios::out);
The various open modes are
app seek to the end of stream before each write
binary open in binary mode
in open for reading
out open for writing
trunc discard the contents of the stream when opening
ate seek to the end of stream immediately after open
Here:
ofstream out;
out.open("C:\\temp\\phones.txt", ios::in);
You don't want to have the std::ios::in flag. Why would you? You're writing to a file, not reading from it.
Explained: std::ofstream bitwise-ORs the flag argument with std::ios_base::out in its constructor and passes it to std::basic_filebuf::open. Look up out | in in that link and you have the answer. The file would need to exist to be open properly. It won't be created.
Just leave out that parameter completely and it will be defaulted to std::ios_base::out (that's what you should have had):
out.open("C:\\temp\\phones.txt");
You might as well do it at once at construction:
std::ofstream out("C:\\temp\\phones.txt");

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.