Writing file doesn't work properly - c++

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");

Related

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 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.

What is the difference among ios::app, out, and trunc in c++?

I know that the default file open mode is out. And I think out will overwrite the data in the file, but in the following code, it age data doesn’t overwrite name data.
#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();
// 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;
Then I’m confused about the three open mode for file – app, out, trunc.
If for name I enter “Zara” and age “9”, the output should be “9ara”. However, it is not. It is “Zara 9”.
ios::out is the default mode for std::ofstream, it means that output operations can be used (i.e. you can write to the file).
ios::app (short for append) means that instead of overwriting the file from the beginning, all output operations are done at the end of the file. This is only meaningful if the file is also open for output.
ios::trunc (short for truncate) means that when the file is opened, the old contents are immediately removed. Again, this is only meaningful if the file is also open for output.
Your code just uses the default ios::out mode. So it starts writing from the beginning of the file, but doesn't remove the old contents. So the new contents will overlay what's already there -- if the file is originally 10 bytes long, and you write 3 bytes, the result will be the 3 bytes you write followed by the remaining 7 bytes of the original contents. More concretely, if the file originally contains:
Firstname Lastname
30
and you write FN LN and then 20 (with newlines after each), the resulting file will look like:
FN LN
20
Lastname
30
because you only overwrite the first 9 bytes of the file (assuming Unix-style newlines).
Once you've opened the file, all outputs to the file are written sequentially after each other, unless you use outfile.seekp() to go to a different location. It doesn't go back to the beginning of the file for each thing you write. seekp() has no effect if the ios::app is used; then every write goes at the end of the file.
Just a little correction to Barmar's answer. I think that the type ofstream implies not only the ios::out, but also the ios::trunc (and I'm not sure, but the ios::out could also imply the ios::trunc).
Here's the concrete example:
ofstream fich;
fich.open("archivo.txt");
for (unsigned i = 0; i < ag.n_pers && !fich.fail(); ++i) {
escribir_persona(fich, ag.pers[i]);
}
if (fich.fail()) {
ok = ERROR;
}
else {
ok = OK;
}
fich.close();
When I call this function, the data of the file is completely overwrited (even if the data to write is less than that which was writen previously), and if the data to write is empty, this just deletes everything in the file.

std::ofstream appending files

So I want to input something in a file but it doesn't seem to work. My code is this:
ofstream f("reservedTables.DAT");
cin >> table;
f.open("reservedTables.DAT", ios::out | ios::app);
f << table;
f.close();
What am I doing wrong? I write the number for the variable table but it doesn't appear in the file that I put it in
Quick walk through:
ofstream f("reservedTables.DAT");
Allocates stream and opens the file.
cin >> table;
Reads in input from user.
f.open("reservedTables.DAT", ios::out | ios::app);
Attempts to re-open the file. Will fail.
f << table;
Stream is in failed state after failed open and cannot be written.
f.close();
closes file.
Solution
Only open the file once and check for errors.
ofstream f("reservedTables.DAT", ios::app); // no need for ios::out.
// Implied by o in ofstream
cin >> table;
if (f.is_open()) // make sure file opened before writing
{
if (!f << table) // make sure file wrote
{
std::cerr << "Oh snap. Failed write".
}
f.close(); // may not be needed. f will automatically close when it
// goes out of scope
}
else
{
std::cerr << "Oh snap. Failed open".
}
That's because you are opening the file twice.
If you call open, you are actually calling rdbuf()->open(filename, mode | ios_base::out). Note that (ref):
If the associated file was already open, returns a null pointer right away.
Because a null pointer has been returned, it is assigned to the internal file buffer, and no file is opened anymore. This means that any attempts to write to it fail.
The constructor already opens the file if you specify a filename, so you don't need to call open:
std::ofstream f("reservedTables.DAT");
std::cin >> table;
f << table;
f.close();

Writing/reading in to binary/text files

wFile.open(fileName, ios::out | ios::trunc);
if (!(wFile.is_open()))
{
cout << "Error in opening the file" << endl;
return false;
}
else
{
for (unsigned int i = 0; i < Widgets.size(); i++)
{
Widgets.at(i)->copyToBinary(fileName);
}
wFile.close();
return true;
}
I'm trying to copy different objects types from a vector. My problem is that when this code runs for the copy, it only copies the last object. It seems like the code just overrides the existing text.
Also, I have this code in each class (this is the copyToBinary function):
ofstream file(fName);
file << *this;
file << endl;
What am I missing here?
Problem:
You pass the finename to copyToBinary(), reopening a stream and overwriting it.
Solution:
Pass the wFile stream as reference and write to it without reopening each time
void copyToBinary(ostream& file) {
file << *this;
file << endl;
}
You should not reopen the file in copyToBinary. Pass wFile as argument not filename :
...copyToBinary(ostream &file) {
file << *this;
file << endl;
}
and call ...copyToBinary(wFile).
First, when you are opening the file
wFile.open(fileName, ios::out | ios::trunc);
Everytime it is called the existing content get lost as you are using trunc mode. It will be better if you use ios::app mode. So that whenever the above code runs, it opens the file in append mode.
Second, You are passing the filename in the copyToBinary function. And By using the default constructor
ofstream file(fName);
your file is getting opened everytime in default ios::out mode but not in ios::app mode. It will be better either you pass the refernece of opened file or open the file in function as append mode.