How to save data, user specified - c++

this is a programme that needs to save the outputs to a user specified data file however it doesn't seem to save and Im not sure why, Im relatively new to C++ so any help is appreciated
cout << "Press 's' then 'Enter' to save the file or any other key then 'Enter' to display";
cin >> save;
if (save != 's')
{
cout << "Ix = " << Ix << "A\n";
cout << "Iy = " << Iy << "A\n";
cout << "Vz = " << Vz << "V\n";
}
else
{
cout << "Please enter a name for your file: \n";
cin >> filename;
cout << " Please enter a directory to save your file in: \n";
cin >> filepath;
ofstream file((filepath + "/" + filename).c_str());
//input is being writen to the file
file << "Ix = " << Ix << "A\n";
file << "Iy = " << Iy << "A\n";
file << "Vz = " << Vz << "V\n";
file << flush;
file.close();
}
}

welcome to SO.
When opening a file stream you first have to check whatever the opening operation has succeeded.
You could do it like this:
if(!file) { /* file isn't "good", open seems to have failed */}
/* or */
if(!file.good()) { /* file isn't good */ }
I guess, because its not writing anything to the file (nor creating the file?) the directory probably does not exists.
The std::ofstream class will not automatically create the required directories.
How you could create the required directories is well explained here: https://en.cppreference.com/w/cpp/filesystem/create_directory

Related

How to add multiple lines to a file in C++?

I am new to C++ and write a little todo list on the console.
I am only able to add one line to a text file but when I try to add more it just won't appear on my text file.
Please take a look what I am doing wrong
//output-file stream
ofstream file;
file.open("output.txt", std::ios_base::app); //append
bool isRunning = true;
while (isRunning) {
cout << "Please select an action:" << endl;
cout << "add - adding tasks to the list" << endl;
cout << "del - deleting tasks to the list" << endl;
cout << "list - show the list" << endl;
cout << "x - to exit program" << endl;
string input;
cin >> input;
string addedTask;
if (input == "add") {
cout << "Please enter a task you like to add: " << endl;
cin.ignore();
if (std::getline(std::cin, addedTask)) {
file << addedTask << "\n";
}
else {
cout << "Failed to read line" << endl;
}
}
Why can I only add one string line? I still can't figure out the problem or am I missing something?
Did you try replacing your
file << addedTask << "\n";
by
file << addedTask << endl;
I think it should work (for me it's working)

Reading/ Writing from/to a file

I am working on an OOP project and I need to write into a file and I faced a problem that each time I do it the file is over written with only one object. How can I make it to write data of all the objects? I tried this but didnt work.
virtual void save(ofstream outfile) = 0;`// the base class
void AND2::save(ofstream outf) //derived
{
outf.open("test.txt");
outf << Component::getype() << " ";
outf<< Component::getid() << " ";
outf << Component:: graphicsinfomration().x1 << " ";
outf<< Component::graphicsinfomration().x2 << " ";
outf << graphicsinfomration().y1 << " ";
outf << graphicsinfomration().y2 << " ";
outf << endl;
outf.close();
}
else
{
ofstream outf;
for (int i = 0; i < (pApp->getcompcount()); i++)
{
//ask user to enter text name
c[i]->save( outf);
}
pOut->ClearStatusBar();
}
Because you're opening the file again and again you overwrite the contents again and again.
You probably want to open the stream outside the for loop once and pass it by reference.

Selecting random words from an generating a sentence from an input file

I need to create a program that has 4 columns of words from an input file.
then randomly selects a word from each column and generates a sentence. The ultimate goal is to have a conversation that gets saved to the output file.
I've already created the code that reads the input file, and opens the output file to write on but i'm not sure how to select a word from a column and create the sentence, i'm guessing using an array would work but i'm not certain how to connect it with the file?
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
using namespace std;
int main()
{
string ifilename, ofilename, line;
ifstream inFile, checkOutFile;
ofstream outFile;
char response;
// Input file
cout << "Please enter the name of the file you wish to open : ";
cin >> ifilename;
inFile.open(ifilename.c_str());
if (inFile.fail())
{
cout << "The file " << ifilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Output file
cout << "Please enter the name of the file you wish to write : ";
cin >> ofilename;
checkOutFile.open(ofilename.c_str());
if (!checkOutFile.fail())
{
cout << "A file " << ofilename << " exists.\nDo you want to continue and overwrite it? (y/n) : ";
cin >> response;
if (tolower(response) == 'n')
{
cout << "The existing file will not be overwritten. " << endl;
exit(1);
}
}
outFile.open(ofilename.c_str());
if (outFile.fail())
{
cout << "The file " << ofilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Copy file contents from inFile to outFile
cout << "Hi, what's up? " << endl; // Pre-set opener
while (getline(inFile, line))
{
cout << line << endl;
outFile << line << endl;
}
// Close files
inFile.close();
outFile.close();
} // main
You can use a 2D vector of strings to store the words of the sentences and use a random number generator like rand to pick a particular row element from every column. Something like the following
vector<vector<string>> myConversationVector;
while (choice != "no")
{
std::cout << myConversationVector[rand() % 5][0] <<" "
<< myConversationVector[rand() % 5][1] <<" "
<< myConversationVector[rand() % 5][2] <<" "
<< myConversationVector[rand() % 5][3];
}

Using fstream in VIsual C++

I am trying to use fstream but am running into problems when trying to open a file from within Visual Studio 2013. In Visual Studio, I have two resources that I have enabled to be used in the project titeld input1.txt and input2.txt . If I directly run the application from the Debug folder using File Explorer, I am able to use the ifles. If I try to run it from within Visual Studio with ctrl, neither files can be found. I believe my code is correct, but I'm not sure what changes to make to the project to have it run correctly.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const bool VERBOSE(true);
int main(){
ifstream input;
ofstream output;
string inFileName;
string outFileName;
string tempString;
// Get input file name into a string
cout << "Input file name: " << flush;
cin >> inFileName;
if (VERBOSE)
{
cout << "Input file name is " << inFileName << endl;
}
// Convert filenames to C strings and use stream.open()
input.open(inFileName.c_str());
if (input.fail())
{
cout << "File " << inFileName << " cannot be opened" << endl;
return -1;
}
// Get output file name into a string
cout << "Output file name: " << flush;
cin >> outFileName;
if (VERBOSE)
{
cout << "Output file name is " << outFileName << endl;
}
// Convert filenames to C strings and use stream.open()
// When opening output file, it will create the file if it
// does not exist, and will clobber it if it does.
output.open(outFileName.c_str());
if (output.fail())
{
cout << "File " << outFileName << " cannot be opened" << endl;
return -2;
}
// While there is more to the input file, get a word
// and copy it to the output file on its own line.
while (!input.eof())
{
input >> tempString;
if (VERBOSE)
{
cout << " Length is " << tempString.length() << " for " << flush;
}
if (tempString.length() > 0)
{
if (VERBOSE)
{
cout << tempString << endl;
}
output << tempString << endl;
}
else
{
if (VERBOSE)
{
cout << "No more input" << endl;
}
}
// This is needed to keep the last non-whitespace word
// read in from being printed twice if the file ends in
// whitespace, including a newline.
tempString.clear();
}
cout << endl;
return 0;
}
Specify the full path to the files when you cin them.

ifstream still reading after eof

I am writing a program that is going to have to import data from a file into various containers. I have it importing everything properly, but it is continuing to read after what is supposed to be the eof. I have a feeling I am not properly telling the loop when to end, but the code is below for everyone to look at.
bool InitLoad(vector<string>&num, vector<string>&name, vector<double>&price, vector<char>&tax)
{
ifstream invFile;
int intTemp;
string strTemp;
double dubTemp;
char chTemp;
string fileLoc = "C:/Users/owner/Documents/Visual Studio 2010/Projects/CISS 350/Week 1 Grocery Register/Week 1 Grocery Register/Invent.dat";
//Open Invent.dat file. Location below is the location used on creators computer. Other may need to modify file location
invFile.open(fileLoc.c_str(), ios::in);
//If Invent.dat file fails to open display error message and return false
if(invFile.fail())
{
cout << "Could not open inventory file" << endl;
return false;
}
if(invFile)
{
//Read first line of the file
getline(invFile, strTemp, ' ');
while(invFile) //while invFile contains data display import the list
{
cout << strTemp << " ";
num.push_back(strTemp);
getline(invFile, strTemp, ' ');
cout << strTemp << " ";
name.push_back(strTemp);
getline(invFile, strTemp, ' ');
dubTemp = atof(strTemp.c_str());
cout << dubTemp << " ";
price.push_back(dubTemp);
invFile.get(chTemp);
cout << chTemp;
tax.push_back(chTemp);
getline(invFile, strTemp, ' ');
}
}
invFile.close();
cout << endl;
//Verify Proper input...REMOVE WHEN COMPLETE
cout << "Verifying input data correct..." << endl;
int vecSize = num.size();
cout << vecSize << endl;
for(int i = 0; i < vecSize; i++)
{
cout << num[i] << " " << name[i] << " " << price[i] << " " << tax[i] << endl;
}
}
Your check does not check eof flag
http://www.cplusplus.com/reference/ios/ios/operator_bool/
use invFile.eof() instead
And also eof flag would be setted after reading past EOF
PS: OMG!! do not use atof, just do invFile << dubTemp
Since your data is space separated you can uses formatted input instead of getline() on every string.
Something along the lines of this.
string lineTemp;
while(getline(invFile, lineTemp)) //while invFile contains data display import the list
{
string strTemp1, strTemp1, dubTemp, chTemp;
istringstream lstr(lineTemp);
if(lstr >> strTemp1 >> strTemp2 >> dubTemp >> chTemp) {
num.push_back(strTemp1);
name.push_back(strTemp2);
price.push_back(dubTemp);
tax.push_back(chTemp);
cout << strTemp1 << " "
<< strTemp2 << " "
<< dubTemp << " "
<< chTemp << endl;
}
else {
// Something is wrong with the line format.
}
}
This will read the data in a formated way and to the proper type. Plus you don't have to worry about empty lines or extra characters in lines.