Getting the user to enter a file C++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
" Your assignment is to prompt the user to enter the filename with the path on disk. If the file does not exist in the specified location, your program should exit with a suitable error message"
Hi everyone, so this is where I'm having an issue, I was able to get the user to enter a file name like this..
1. cout<< "enter the data file name you wish to open";
2. cin >>file;
3. indata.open(file.c_str());
4. outdata.open(file.c_str());
The second part of the question is if the file does not exist, the program should make an error, how would I go about doing so, say my file name is txt.source, but the user enters lil.pol how do I make it say there is an error, or other words how do I make the file name desired the only one the computer will accept?

What you can do is try to open the file and if it fails to open issue a message through std::cerr like this:
std::ifstream indata(file.c_str());
if(!indata) // failed to open
{
std::cerr << "Error: could not open file: " << file << std::endl;
return 1; // error code
}
// use indata here (its open)

Edit:
reading/writing data:
void createfile()
{
ofstream file_handle("test.txt");
if (!file_handle)
return;
//add record:
file_handle << "firstname1" << endl;
file_handle << "lastname1" << endl;
file_handle << "college1" << endl;
file_handle << "1001" << endl;
//add another record:
file_handle << "firstname2" << endl;
file_handle << "lastname2" << endl;
file_handle << "college2" << endl;
file_handle << "1002" << endl;
//remember each record is 4 lines, each field is single line
//this is the file format
}
int main()
{
createfile();
ifstream fin("test.txt");
if (!fin)
{
cout << "file not found" << endl;
return 0;
}
ofstream fout("out.txt");//note, it's a different name than input file
if (!fout)
{
cout << "cannot create new file" << endl;
return 0;
}
char buffer[1000];
while (fin)
{
cout << "attempting to read record:\n";
for (int i = 0; i < 4; i++)
{
fin.getline(buffer, 1000, '\n');
if (!fin) break;
cout << buffer << endl;//write to screen
fout << buffer << endl;//write to file
if (i == 3)
{
//buffer is expected to be a number!
int number = atoi(buffer);
//multiply by random number 2, just testing
cout << number * 2 << endl;
}
}
}
return 0;
}
Just make a loop and ask for new entry if the file name is wrong.
int main()
{
ifstream indata;
string fname;
for (;;)
{
cout << "enter fname, zero to exit\n";
cin >> fname;
if (fname == "0")
return 0;
indata.open(fname);
if (indata)
break;//file is valid and has been opened now
cout << "file not found, try again\n";
}
return 0;
}

Related

C++ File (Ifstream) will not open [duplicate]

This question already has answers here:
ifstream won't open file
(2 answers)
What happens if i open a file that is already open in C++
(1 answer)
Closed 2 months ago.
When file is checked if its open, it will not open.
The file doesn't open when ran, as it says "Unable to open file" based on my test cases. Is there anyway to fix this?
Is there something I need to fix with the file io function (which I created at the bottom) or something to do inside of the if statement (checking if its open)
#include "header.hpp"
int main() {
string infile, outfile;
print();
readFilenames(infile, outfile);
ifstream fin(infile.c_str());
// check if file can be opened
fin.open(infile);
if (fin.is_open())
{
string name, smallName = "", largeName = "";
int id, numPeople = 0, smallId, largeId;
double balance, totalBalance = 0, largeBalance, smallBalance;
cout << "\n\nReading records from input file " << infile << endl;
cout << "Output records to output file " << outfile << endl;
ofstream fout(outfile.c_str());
print(fout);
fout << "List of Entries : " << endl;
printHeading(fout);
// read till the end of file
while (!fin.eof())
{
numPeople++;
getline(fin, name); // read name
name = name.substr(0, name.length() - 1); // remove '\n' from the end of name
// read id and balance
fin >> id >> balance;
}
} else
cout << "Unable to open file : " << infile << endl;
cout << "\nThank you for using my program";
return 0;
}
void readFilenames(string &infile, string &outfile)
{
cout << "What input file would you like to use? ";
getline(cin, infile);
infile = infile.substr(0, infile.length() - 1);
cout << "What output file would you like to use? ";
getline(cin, outfile);
outfile = outfile.substr(0, outfile.length() - 1);
}

Cannot print a vector to a text file in C++

I'm working on the following problem:
I need to write a prgoram that reads an ASCII text file from the hard drive and allows the user to display and edit the contents of the file line-by-line.
It must have the following features:
It reads the file name from the standard output and opens the text file using a file stream.
When the file is loaded, the user enters the text line number.
If the line exists, it is displayed in the standard output.
If the line does not exist (the user has entered a line number
that is greater than the number of lines in the file), an error message is displayed,
for example: The line 82 does not exist. When the line is displayed the user is given
an option to enter a new string in the standard input that will become the contents of
the line. The string can contain blank spaces. Then the user is asked to enter another line number.
Finally, the user is asked whether he wants to save the changes in the file or not.
Technical requirements: The program must be composed by more than one function
This is my code so far:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
void printErrorMessage(int lineNumber)
{
cout << endl << " ERROR: The line " << lineNumber << " does not exist"
<< endl;
}
int main()
{
int line_number;
vector<string> TextVector;
int loop = 1;
fstream myfile;
myfile.open("test.txt", std::fstream::in | std::fstream::out);
while(loop == 1)
{
if (myfile.is_open())
{
// get end line of file.
cout << "File has opened successfully." << endl;
}
else
{
cout << "File hasn't opened successfully.";
return 0;
}
cout << "Enter the text line number:" << endl;
cin >> line_number;
size_t lines_count = 0;
string line;
while(getline(myfile, line))
{
TextVector.push_back(line); // push to text file
}
if(line_number > TextVector.size() + 1)
{
printErrorMessage(line_number);
return 0;
}
cout << TextVector[line_number] << endl;
cout << "If you'd like to change the line, please enter it, otherwise enter n to exit" << endl;
string changeLine;
getline(cin, changeLine);
if (changeLine == "n")
{
myfile.close();
return 0;
}
TextVector[line_number] = changeLine; // changes the line with the new string
cout << "Would you like to enter a new line to edit? (Y/n)" << endl;
string newLine;
cin >> newLine;
if (newLine != "y" && newLine != "Y")
{
cout << "Would you like to save all your changes to the file? (Y/n)" << endl;
string saveChanges;
cin >> saveChanges;
if (saveChanges != "y" && saveChanges != "Y")
{
myfile.close();
return 0;
}
for (int i = 0; i < TextVector.size() + 1; i++)
{
cout << TextVector[i] << endl;
myfile << TextVector[i] << endl;
myfile.flush();
}
myfile.close();
return 0;
}
}
return 0;
}
Technically I do save the changes to the vector, but for some reason I cannot get to overwrite the vector into the text file that already is full.
Also, any idea why the
getline(cin, changeLine);
Still acts as if it's a normal string? shouldn't it get the whole line entered togethe with the spaces?
Some guidance would really be appreciated!

.EOF Causing Seg Fault when reading file :FIXXED [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
When I run my program it works the first time, the correct input is read and output is written to my output file but once I run it a second time it doesn't write anything the file is just blank even though it reads everything correctly. I can't seem to understand where its messing up or how and I really want to know. The two images are my first and second runs just that after the second run my output file is blank.
first run
second run
#include<iostream>
#include<iostream>
#include<cstdlib>
#include<time.h>
#include<fstream>
#include<string>
using namespace std;
int main()
{
int i=0;
int number; // The correct number
int guess=0; // The user's guess
int numGuesses=0; // The number of times the user has guessed
string lines;
string player;
ifstream ifile;
ofstream ofile;
//ofstream myfile;
//
string names[10];
int scores[10];
ifile.open("high_score.txt");
string first_last_name;
string temp;
int score;
int index=0;
string title;
bool topten=false;
cout <<"Welcome to the number guessing game. The top 10 best scores so far are: "<<endl;
while(!ifile.eof())
{
//getline(ifile,lines);
ifile >>first_last_name;
//cout << first_last_name;
ifile >> temp;
first_last_name.append(" ");
first_last_name.append(temp);
ifile >> score;
names[index]=first_last_name;
scores[index++]=score;
}
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
for (int i=0; i < 10; i++)
{
cout << names[i] << " " << scores[i] <<endl;
}
// Seed the random generator.
srand(static_cast<int> (time(NULL)));
// Generate a random number between 1 and 100.
number = (rand() % 100) + 1;
cout << "Let's play the number guessing game! What is your name? " <<endl;
getline(cin,player);
cout << endl;
while(guess!=number)
{
cout << "guess the number the computer randomly picked between 1 - 100: ";
cin >> guess;
numGuesses++;
// Check if the user has guessed the correct number.
// If not, tell him if his guess is too low or too high
if(number > guess)
{
cout << "sorry, your guess is too low" << endl;
}
else if(number < guess)
{
cout << "sorry, your guess is too high" << endl;
}
else
{
cout << "You guessed right!!!!"<<endl;
cout << "You win!!!" << endl;
break;
}
}
cout << "It took you "<< numGuesses << " guesses "<< player<< endl;
////////////////////////////////////////////////////////////////////////
if (numGuesses<4)
{
cout << "Amazing! Or was it luck" << endl;
}
else if(numGuesses<6)
{
cout <<"That's a very good score..." <<endl;
}
else if (numGuesses<8)
{
cout << "That's pretty good but you can do better..." << endl;
}
else if ( numGuesses<10)
{
cout << "Not too shabby, but not too good either..."<< endl;
}
else
{
cout << "What a terrible score!..." << endl;
}
for(int i=0; i < 10; i++)
{
if(numGuesses <= scores[i])
{
for( int k=9;k>i;k--)
{
scores[k]=scores[k-1];
names[k]=names[k-1];
}
scores[i]=numGuesses;
names[i]=player;
topten=true;
break;
}
}
if(topten==true)
{
cout << "Hey, you made it to the top ten , Congratzzzzzzzz!!!!" <<endl;
}
ofile.open("high_score.txt");
for(int i=0;i<10;i++)
{
ofile <<"\t"<< names[i] << " " << scores[i] <<endl;
ofile << endl;
}
return 0;
}
You need to close the input file before you open the output file, since they are both referring to the same file.
The closing can be done explicitly by calling ifile.close() or implicitly by making ifile go out of scope before you open the output file.
The latter can be done like this:
{
ifstream ifile;
ifile.open("high_score.txt");
// do stuff with ifile
}
ofstream ofile;
ofile.open("high_score.txt");
// do stuff with ofile
Where is ifile.close() and ofile.close()
you should close else your stream will go into invalid state.

How to edit specific value in binary file?

I have a structure of flight, which is being writing into binary file and i want to edit flight destination and i have no idea how to do it.
This is my code for getting user input and writting to binary file.
struct Flight_Details {
char destination[99];
char departure[99];
char time_depart[80];
char time_arrive[80];
int flight_number;
};
switch (menu)
{
case MENU::NEW_FLIGHT: {
Flight_Details flight_d;
cout << "Enter Departure: ";
cin >> flight_d.destination;
cout << "Enter Destination: ";
cin >> flight_d.departure;
cout << "Enter Departure Time: ";
cin >> flight_d.time_depart;
cout << "Please enter arriving time: ";
cin >> flight_d.time_arrive;
cout << "Flight Number: ";
cin >> flight_d.flight_number;
ofstream file;
file.open("Flgiht_Details.data", ios::binary);
if (!file) cout << "Could create/open file";
else {
file.write((char*)&flight_d, sizeof(flight_d));
file.close();
}
break;
}
case MENU::OUTPUT_FILE: {
ifstream readFile;
readFile.open("Flgiht_Details.data");
if (!readFile) cout << "Couldn't open file";
else {
readFile.seekg(0, ios::end);
int fileSize = readFile.tellg();
int countOfFlights = fileSize / sizeof(Flight_Details);
readFile.seekg(0, ios::beg);
Flight_Details* flight = new Flight_Details[countOfFlights];
readFile.read((char*)flight, countOfFlights *sizeof(Flight_Details));
readFile.close();
for (int i = 0; i < countOfFlights; i++)
{
cout << flight[i].destination << "\n" << flight[i].departure << "\n" << flight[i].time_depart << "\n" << flight[i].time_arrive << "\n" << flight[i].flight_number << "\n\n";
}
break;
}
}
case MENU::EDIT: {
Flight_Details* flight_d;
ifstream readFile;
readFile.open("Flgiht_Details.data");
if (!readFile) cout << "Couldn't open file";
else {
readFile.seekg(0, ios::end);
int fileSize = readFile.tellg();
int countOfFlights = fileSize / sizeof(Flight_Details);
readFile.seekg(0, ios::beg);
Flight_Details* flight = new Flight_Details[countOfFlights];
readFile.read((char*)flight, countOfFlights * sizeof(Flight_Details));
readFile.close();
ofstream file;
char edit[50];
cout << "Edit: ";
cin.getline(edit, 50);
for (int i = 0; i < countOfFlights; i++)
{
if (strcmp(flight_d[i].destination, edit) == 0)
{
//edit file
}
}
}
}
}
Since your Flight_Details has a fixed size in bytes when written, it is easy to calculate where in the file each flight is. The general equation is flight_number * sizeof(Flight_Details)//where flight_number is 0..N. This will calculate a byte offset into the file to seek to. From there it is just a matter of reading exactly sizeof(Flight_Details) bytes from the file and converting that buffer into a Flight_Details which in this case could mean that you just fill each buffer in the Flight_Details with the bytes manually, or if you prefer you could just reinterpret_cast() the char* of data into the right type(this will only be a decent idea if your buffer is exactly sizeof(Flight_Details) long. It would be safer to just manually copy the bytes in via a constructor of some kind.
Here is what you will write under // edit file comment. This looks ugly but it works pretty fine
cout << "Yeah we are editing\n";
char newdestiny[99];
cout << "new dest: ";
cin.getline(newdestiny, 99);
strcpy(flight[i].destination, newdestiny);
file.write((char*)flight, sizeof(Flight_Details[countOfFlights]));
file.close();
return 0;
and you have got bugs in your program like when you ask for desparture you are getting destination and when you open file for writing that data you have to include ios::app flag so you can enter new flight information as well(?)
the file I am opening has only ios::out flag
and one more thing strcmp(flight_d[i].destination, edit) == 0 line should be strcmp(flight[i].destination, edit) == 0

why won't my program back up my file?

I'm working on a C++ project where I need to backup a data file after creating it within the same program. I have already created the data file and have successfully written text to it, however, when I've tried to backup the same file using the function I've written, it won't work.
Here is some context followed by the function:
The filename I created is named contactList.ext (.ext so it's created in the current directory). When prompted for the filename in this program I type in contactList and it opens successfully, however, the only problem I'm having is that it won't backup the file. I'm trying to back it up this way: newFileName = (fileName + ".bak");
I don't know what other way there is to backup a file using c++. Any help is greatly appreciated!
void backupDataFile() {
string fileName;
string newFileName;
string line;
int contactListSize = 10, i = 0;
string contacts[contactListSize];
char userResponse;
fstream inFile, outFile;
cout << "\nEnter the name of the file you want to backup: ";
cin >> fileName;
inFile.open(fileName.c_str()); //attempts to open file
//file fails to open
if (inFile.fail()) {
cout << "\nThe file " << fileName << " was not opened successfully."
<< "\n Please check that the file currently exists.\n";
exit(1);
}
//read and display contents of file & assign each line to an array
cout << "\nThe following is the contents of " << fileName << ":\n\n";
while(getline(inFile, line)) {
cout << line << endl;
contacts[i] = line; //assigns each line to an array position
i++;
}
inFile.close(); //closes existing file allowing the opening of a new file
//verify user wishes to backup file
cout << "\nWould you like to backup this file? <y/n>: ";
cin >> userResponse;
if (userResponse == 'y') {
newFileName = (fileName + ".bak"); //assigns name of backup file
outFile.open(newFileName.c_str()); //attempts to open backup file
//file fails to create
if (outFile.fail()) {
cout << "\nThe file " << fileName << " did not backup successfully.";
exit(1);
}
///fix hereafter
else { //writes contents from contactList.ext to contactList.bak
while (i < 10) {
cout << contacts[i] << endl; //writes each contact into new file
i++;
}
//for (int j = 0; j < 10; j++) {
// outFile << contacts[j] << endl;
}
outFile.close(); //closes file
cout << "\nThe file " << fileName << " has been backed-up successfully."
<< "\nThe backup file is named " << newFileName;
}//end outer-if
else
cout << "\nYou will be directed back to the Main Menu.";
}
Your problem lies within these two sections.
while (i < 10) {
cout << contacts[i] << endl; //writes each contact into new file
i++;
}
//for (int j = 0; j < 10; j++) {
// outFile << contacts[j] << endl;
That for loop should not be commented out, you're only writing to the console (with cout), when you need to be writing to the outfile.
You also need to specify ios::out when calling outFile.out().
outFile.open(newFileName.c_str(),ios::out)
As stated by the other poster, you aren't actually running the code that outputs to the file
//outFile << contacts[j] << endl;
However another problem I see is that you output in a loop so long as i is less than 10. This is fine, but you didn't set i back to 0 after counting the number of lines when reading the file! That means that your
while(i < 10) {
loop never runs :)