File not saving, or not - c++

I cannot seem to figure out why, during the while loop at the bottom,
std::cout << line;
does not print anything.
I believe that the test.txt file is not actually being written to because when I open test.txt in my folder, its empty. Any thoughts?
void Ticket::WriteTicket()
{
std::string ticketInput;
std::ofstream ticketFile("test.txt");
ticketFile.open("test.txt");
std::cout << "Please Enter Ticket Information: " << std::endl;
getline(std::cin, ticketInput);
std::cout << ticketInput << std::endl; //does print out the line
ticketFile << ticketInput;
ticketFile.close();
//here for testing only
std::string line;
std::ifstream ticketRead("test.txt");
while(getline(ticketRead, line));
{
std::cout << "something here?: " << line; // there is nothing here when it outputs
}
}
EDIT (SOLUTION):
After using some of the information that was given above, mainly from Basile Starynkevitch (I put this here because I cannot upvote yet), I was able to get the code to work!
I also did some research in my book and copied a similar program's style. Aka where to put what part of the code, and then the input worked. I continued on with the output and the key part was the std::ifstream::in in the opening of the file for output.
void Ticket::WriteTicket()
{
std::string ticketInput;
std::cout << "Please Enter Ticket Information: " << std::endl;
getline(std::cin, ticketInput);
std::ofstream ticketFile("Ticket.txt");
ticketFile << ticketInput << std::endl;
ticketFile.close();
//here for testing
std::ifstream ticketRead;
ticketRead.open("Ticket.txt", std::ifstream::in);
std::string line;
while(getline(ticketRead, line))
{
std::cout << line << std::endl;
}
}
Thank you for the help everyone!

You need to flush the output buffer.
ticketFile << ticketInput;
should be
ticketFile << ticketInput << std::endl;
std::endl flushes the output buffer.See std::flush if you don't want the new line.

C++ I/O is buffered. At least code
std::cout << "something here?: " << line << std::flush;
but in your case
std::cout << "something here?: " << line << std::endl;
would be better.
Also
std::ofstream ticketFile("test.txt")
should probably be
std::ofstream ticketFile("test.txt", std::ios_base::out);
I strongly suggest taking some hours to read more about C++ libraries before coding. Check every function or class that you are using. Of course, you also need to std::flush on ticketFile.

Maybe the file need to be openned in write mode.
Try this
std::ofstream ticketFile("test.txt","w");

Related

Appending data to csv file, before last entry instead of after last entry. C++

Not easy to formulate that question, so I am sorry for any grief there..
I am writing to a csv file like this at the moment:
double indicators::SMACurrentWrite() {
if ( !boost::filesystem::exists( "./CalculatedOutput/SMAcurrent.csv" ) ) // std::cout << "Can't find my file!" << std::endl;
{
std::ofstream SMAfile;
SMAfile.open("./CalculatedOutput/SMAcurrent.csv");
SMAfile << "SMA" << endl << SMA[0] << endl; // .. or with '\n' at the end.
SMAfile.close();
}
else {
std::ofstream SMAfile;
SMAfile.open ("./CalculatedOutput/SMAcurrent.csv", ios::app); // Append mode
SMAfile << SMA[0] << endl; // Writing data to file
SMAfile.close();
}
return 0;
}
Each time the application runs, a new value is appended to the output file at the end:
SMA
32.325
I guess there is no way of just squeezing that new vector entry in there under the header( and over the number), but that is what I want to accomplish anyway.
So I guess I would have to read the existing output file back in,put it in a vector, and then replace the old file ? I started with smth like this:
double indicators::SMACurrentWrite() {
if ( !boost::filesystem::exists( "./CalculatedOutput/SMAcurrent.csv" ) ) // std::cout << "Can't find my file!" << std::endl;
{
std::ofstream SMAfile;
SMAfile.open("./CalculatedOutput/SMAcurrent.csv", ios::app);
SMAfile << "SMA" << endl << SMA[0] << endl; // .. or with '\n' at the end.
SMAfile.close();
}
else {
std::ofstream SMARfile("./CalculatedOutput/SMAReplacecurrent.csv");
std::ifstream SMAfile("./CalculatedOutput/SMAcurrent.csv");
SMARfile << SMA[0] << endl; // Writing data to file
SMARfile << SMAfile.rdbuf();
SMAfile.close();
SMARfile.close();
std::remove("./CalculatedOutput/SMAcurrent.csv");
std::rename("./CalculatedOutput/SMAReplacecurrent.csv","./CalculatedOutput/SMAcurrent.csv");
}
return 0;
}
...., but of course that just puts the new data in above the header like this :
32.247
SMA
32.325
..rather than this
SMA
32.247
32.325
I would rather this didn't become such a time- consuming exercise, but I appreciate any help on how I could get this done.
If you read in the first line from the input file you can use that to start the new file and it will leave the file pointer at the second line where the old data starts. Then you can write the new stuff like this:
if(!boost::filesystem::exists("./CalculatedOutput/SMAcurrent.csv"))
{
std::ofstream SMAfile;
SMAfile.open("./CalculatedOutput/SMAcurrent.csv", ios::app);
SMAfile << "SMA" << '\n' << SMA[0] << '\n';
SMAfile.close();
}
else
{
std::ofstream SMARfile("./CalculatedOutput/SMAReplacecurrent.csv");
std::ifstream SMAfile("./CalculatedOutput/SMAcurrent.csv");
// first read header from input file
std::string header;
std::getline(SMAfile, header);
// Next write out the header followed by the new data
// then everything else
SMARfile << header << '\n'; // Writing header
SMARfile << SMA[0] << '\n'; // Write new data after header
SMARfile << SMAfile.rdbuf(); // Write rest of data
SMAfile.close();
SMARfile.close();
std::remove("./CalculatedOutput/SMAcurrent.csv");
std::rename("./CalculatedOutput/SMAReplacecurrent.csv",
"./CalculatedOutput/SMAcurrent.csv");
}

ofstream/fstream simply will not work, no matter what solution is tried

Okay guys, I've tried everything I can think of. I'm passing in a file name into this function. A little context: hash_table is an already initialized and filled vector with key pairs, and the 'value' part of the pair is a Linked List that has the field "bucket_size". When I use cout to check if these fields are actually being accessed, they are; even the debugger lists them as being filed into the output stream. I have flush() and close() in there, but it doesn't write anything to the file. Returns true, indicating no errors in the stream. Anyone have nay ideas?
string line;
std::ofstream ofs;
if(ofs.is_open())
ofs.close();
ofs.open(filename);
if (ofs.is_open())
{
cout << "File Opened" << endl;
for (double i = 0; i < hash_table.capacity(); ++i)
{
ofs << "Bucket Number " << i;
if (hash_table[i].value != NULL)
ofs << " Bucket Size: " << hash_table[i].value->bucket_size << endl;
else
ofs << " Bucket Size: 0" << endl;
ofs.flush();
}
cout << "closing file stream" << endl;
ofs.flush();
ofs.close();
if (ofs.good())
return true;
else
return false;
}
else
{
cout << "File not opened" << endl;
return false;
}
}
You're almost certainly examining the wrong file. Remember that relative paths are relative to the working directory of the process, which is not necessarily the same as where the executable lives on disk.
I compiled and ran it by the console and now it works, with no edits made. It seems my IDE doesn't like something in the code. Regardless, thank you everyone for the response.s

Nicolai Josuttis says in his book that the open member function doesn't clear the state flags. That's not what I found in VS2010. Is this a MS issue?

Nicolai Josuttis in page 547 of his book "The C++ Standard Library" says the following in relation to the code below :
Note that after the processing of a file, clear() must be called to clear the state flags that are set at end-of-file. This is required because the stream object is used for multiple files. The member function open() does not clear the state flags. open() never clears any state flags. Thus, if a stream was not in a good state, after closing and reopening it you still have to call clear() to get to a good state. This is also the case, if you open a different file.
// header files for file I/O
#include <fstream>
#include <iostream>
using namespace std;
/* for all file names passed as command-line arguments
* - open, print contents, and close file
*/
int main (int argc, char* argv[])
{
ifstream file;
// for all command-line arguments
for (int i=1; i<argc; ++i) {
// open file
file.open(argv[i]);
// write file contents to cout
char c;
while (file.get(c)) {
cout.put(c);
}
// clear eofbit and failbit set due to end-of-file
file.clear();
// close file
file.close();
}
}
My code below works without a problem in VS2010. Note that after the file "data.txt" is created, it's read twice without clearing the input stream flags.
#include <iostream>
#include <fstream>
#include <string>
int main()
{
// Create file "data.txt" for writing, write 4 lines into the file and close the file.
std::ofstream out("data.txt");
out << "Line 1" << '\n' << "Line 2" << '\n' << "Line 3" << '\n' << "Line 4" << '\n';
out.close();
// Open the file "data.txt" for reading and write file contents to cout
std::ifstream in("data.txt");
std::string s;
while( std::getline(in, s) ) std::cout << s << '\n';
std::cout << '\n';
std::cout << std::boolalpha << "ifstream.eof() before close - " << in.eof() << '\n';
// Close the file without clearing its flags
in.close();
std::cout << std::boolalpha << "ifstream.eof() after close - " << in.eof() << '\n';
// Open the file "data.txt" again for reading
in.open("data.txt");
std::cout << std::boolalpha << "ifstream.good() after open - " << in.good() << '\n';
std::cout << '\n';
// Read and print the file contents
while( std::getline(in, s) ) std::cout << s << '\n';
std::cout << '\n';
}
Ouput
That was changed for C++11. The C++98 rule (as correctly described by Josuttis) was clearly wrong, so I wouldn't be surprised if implementations didn't honor it.

How to read and write input file and output file

I am trying to run the following program:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
ofstream outFile;
double first=1.49, second=2.59, third=3.69, fourth=4.79;
inFile.open("prices.txt");
char response;
if(!inFile.fail())
{
cout << "A file by the name prices.txt exists.\n" << "Do you want to continue and overwrite it\n" << " with the new data (y or n);"; cin >> response;
if(tolower(response) == 'n')
{
cout << "The existing file will not be overwritten." << endl;
return -1;
}
}
outFile.open("prices.txt");
if (inFile.fail())
{
cout << "\n The file does not exist and can not be opened" << endl;
cout << "The file has been successfully opened for output." << endl;
outFile << first << "\n" << second << "\n" << fourth << "\n" << endl;
outFile.close();
exit(1);
cout << "The file has been successfully opened for output. " << endl;
outFile << first << "\n" << second << "\n" << third << "\n" << fourth << endl;
outFile.close();
return 0;
}
}
Yet this program will not write the values to the prices.txt file. If you run the program once it says the file does not exist. Running it a second time says the file is already there and if you want to overwrite it. The thing is searching my Mac I cannot find this file anywhere.
Any ideas what I am doing wrong with running it in Xcode? A friend runs the exact same code in Visual Studio 2008 and it works. Any help is appreciated.
You need to set the working directory for the executable since you are assuming that your data files are in the current working directory. In Xcode 3.x you set this in the first tab of Get Info for the executable. In Xcode 4.x it has been moved, but the principle is the same.
Alternatively you can change your data file paths (e.g. make them absolute) so that you do not make assumptions about the current working directory.
You may not have permission to write into the directory that you are trying to save the file too.
Also, there is an error in your program and I am sure if it is there for debugging reasons. You have
outFile.close();
exit(1);
But then shortly there after you try to write to the file, then close it again.

Reading and appending from/to a file with std::fstream

I'm wondering why the following piece of code doesn't work, looks pretty straight-forward, am I making a mistake?
The result of this is: file created but empty, if I manually add lines those lines are showed with this code, but nothing else happens.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(){
fstream mfile("text.txt", ios_base::in | ios_base::out | ios_base::app);
mfile.seekg(ios_base::beg);
string line;
while( getline(mfile,line) ){
std::cout << line << "\n";
}
mfile.seekg(ios_base::end);
mfile << "Line 1\n";
mfile << "Line 2\n";
mfile << "---------------------------------\n";
mfile.seekg(ios_base::beg);
while( getline(mfile,line) ){
std::cout << line << "\n";
}
mfile.seekg(ios_base::end);
}
Couple of things:
When you are ready to write, you need to seekp() rather than seekg(), i.e.
mfile.seekp(ios_base::end);
Now, the problem here is that the getline() calls will set the stream flags (specifically eof), and as a result the stream is not ready for further operations, you need to clear the flags first!
try this:
string line;
mfile.seekg(ios_base::beg);
while( getline(mfile,line) ){
std::cout << line << endl;
}
mfile.seekp(ios_base::end); // seekp
mfile.clear(); // clear any flags
mfile << "Line 1" << endl; // now we're good
mfile << "Line 2" << endl;
mfile << "---------------------------------" << endl;
mfile.seekg(ios_base::beg);
while( getline(mfile,line) ){
std::cout << line << endl;
}
Also, use std::endl rather than "\n", this will trigger a flush of the buffers to the file at the OS's convinience...