Why does ofstream work here, but not fstream? - c++

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.

Related

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;
}

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

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.

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++ write to a file, but file is empty

I have this code for turning decimal into binary and write it to a file:
#include <iostream>
#include <fstream>
using namespace std;
int d,num,s,r,k,sum=0;;
void main()
{
ofstream myfile;
myfile.open("binary.txt",ios::in);
cin >> d;
while(d>0)
{
r=d%2;
sum=sum + (k*r);
d=d/2;
k=k*10;
myfile << sum;
}
cout << "Encryption Succesfull"<<endl;
myfile.close();
}
The program runs successfully, but the file is empty.
The file name is right, no syntax errors, etc.
What to do?
You use the wrong flags for opening the file:
myfile.open("binary.txt",ios::in);
It should be
myfile.open("binary.txt",ios::out | ios::binary);
myfile.open("binary.txt",ios::in);
opens the file for reading. If you want to output something, use ios::out or leave the param empty (since the default value is ios_base::out anyhow):
myFile.open("binary.txt");
I've found this line on cplusplus.com, but it doesn't seem to be true (tested on devC++ 4.9.9.2, uses some MinGW version):
out is always set for ofstream objects (even if explicitly not set in argument mode).
Removing the second parameter or changing it to ios::out does fix the problem.

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!