ifstream won't open file after selecting menu choice - c++

So my main code is a menu.
BankAccount BA;
ifstream fin;
int UserAction = -1;
while (UserAction != 0) {
cout << "menu here";
cin >> UserAction;
if (UserAction == 1)
BA.getInstance(BA); //Input by keyboard. Works fine.
if (UserAction == 2)
BA.getInstance(BA, fin); //Input by file.
}
If I were to choose option #2, it would execute this code:
void BankAccount::getInstance(BankAccount &BA, ifstream &fin) {
string actN, fname, lname, InputFileName;
double bal;
fin.sync();
cout << "Please enter input file path: ";
getline(cin, InputFileName);
if (fin.fail())
cout << "failed";
else {
fin.open(InputFileName.c_str());
BA.getInstance(BA, fin);
}
fin >> actN;
fin >> lname;
fin >> fname;
fin >> bal;
BA = BankAccount(actN, lname, fname, bal);
}
After entering the file path, and pressing enter, it would say failed and kick me to menu. If I put cin.sync(); where fin.sync is, it would just keep looping me to enter in the file path. Note that it works outside the menu though. How would I fix it so that it would open the file path correctly without issues so it could process the information?

1 - change your main code to do-while, idk why people opt for while loops in such scenarios.
do{
cout << "menu here";
cin >> UserAction;
if (UserAction == 1)
BA.getInstance(BA); //Input by keyboard. Works fine.
if (UserAction == 2)
BA.getInstance(BA, fin); //Input by file.
} while(UserAction!=0);
2 - fin.fails because it isn't initialized, remove that line and it will work fine. try to use fin.fail() after fin.open();

Related

How can i open multiple files in one run in C++?

Hey I have several Files that I want to read. The user would input what file they want to open on console. And if they want they can change and read another file, they would do so.
This is how i went by doing (this is just rough copy, the code i have is too big will take too long to understand)
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <iomanip>
#include<algorithm>
using namespace std;
int main()
{
string FileName;
string Line;
cout << "Input File Directory To Open :" << endl;
cin >> FileName;
ifstream File;
File.open(FileName);
string Input;
do {
cout << "Enter R to Read Display Data In File Or C to Read Another File Or X To Exit" << endl;
cin >> Input;
if (Input == "R")
{
while (getline(File, Line))
{
cout << Line;
}
}
else if (Input == "C")
{
string FileName2;
cout << "Enter New File Directory To Open: " << endl;
cin >> FileName2;
//? ? ? ?
}
} while (Input != "X");
}
Since it's in do while loop, when user input C and input directory to read another file, so that they can cout new file when they input R next.
My question is how should i overwrite the FileName2 with FileName?
Hope It makes sense Thank you
First close the file that is already open:
File.close();
Then open the new one:
File.open(FileName2);
Both answers keep your idea of an open file handle. However, a better approach is to use RAII. In that case you only register the file name and only open the file when you need it.
int main()
{
std::cout << "Input File Directory To Open :\n";
std::string fileName;
std::cin >> fileName;
while (true) {
std::cout << "Enter R to Read Display Data In File Or C to Read Another File Or X To Exit\n";
std::string input;
std::cin >> input;
if (input == "X") break;
if (input == "R") {
std::ifstream file(filename);
std::string line;
while (std::getline(file, line)) {
std::cout << line;
}
// due to RAII the file will close when the object goes out of scope
} else if (input == "C") {
std::cout << "Enter New File Directory To Open: \n";
std::cin >> fileName;
}
}
}
You don't need a new variable. Simply assign the value to the existing one, close the currently opened file, and then open the new file inside the loop:
...
else if (Input == "C")
{
cout << "Enter New File Directory To Open: " << endl;
cin >> FileName;
File.close();
File.open(FileName);
}
...

Why can't I open a text file with this code?

I'm writing a code to open a file entered by the user and to display the file.
However, no matter how many times I read over my book I can't seem to
tell why my file is still not opening. I even copied someone else's code
that worked and mine still won't open. Someone please help me I've tried
everything.
Here is part of my code, the void function works perfectly fine and so
does the input validation, but when I open the file nothing is displayed
void readFile(int list[], int size)
{
//Identify variables
ifstream inFile;
string fileName;
cout<<"Please enter filename: ";
cin>>fileName;
inFile.open(fileName.c_str());
while(!inFile)
{
cout<<"Invalid file name. ";
inFile.clear();
inFile.ignore(200,'\n');
cout<<"Please enter filename: ";
cin>>fileName;
inFile.open(fileName.c_str());
}
For some reason everything else seems to work fine but the file will not display anything when it is opened, instead the program closes.
That's strange: this code works fine for me.
#include <cstdio>
#include <cstring>
#include <fstream>
#include<iostream>
using namespace std;
int main ()
{
// Identify variables
ifstream inFile;
string fileName, str;
cout << "Please enter filename: ";
cin >> fileName;
inFile.open(fileName.c_str());
while(!inFile) {
cout << "Invalid file name. ";
inFile.clear();
inFile.ignore(200,'\n');
cout << "Please enter filename: ";
cin >> fileName;
inFile.open(fileName.c_str());
}
while (std::getline(inFile, str)) {
cout << str;
}
cout << endl;
return 0;
}
The problem is probably with what you do with inFile after opening it.

C++ writing a string to a line in a text file; New line issue \n not working

I am writing a database program with many features (Read, write, delete, search, login ect. ) and my writing feature just stopped working (It was working 3 days ago) and I have no idea what changed. My writing function (void savescore) is supposed to write my input (cin username and password) and then move to the next line so I can input some more info the next time I decide to go and write to the file. Right now it's just writing over what I last put in.
test2.txt -
Username, Password
Then I go to edit and enter "User, Pass" and this is what happens
test2.txt - User, Pass
I want it to enter that on the next line and I did "\n" Can someone give me some help? Thanks
CODE:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <fstream>
#include <conio.h>
#include <string>
#include <math.h>
using namespace std;
// Variables
string username;
string password;
//alphabet order functions
// Functions
void SaveScore()
{
ofstream Database;
Database.open("test2.txt");
Database << username << " " << password << "\n";
Database.seekp(0,std::ios::end); //to ensure the put pointer is at the end
Database.close();
}
int main()
{
int db;
char ans;
string save;
string file;
ifstream fin;
ofstream fout;
string searchpar;
char repeat;
bool loop = true;
while (loop == true)
{
cout << "WELCOME TO MY DATABASE\n\n";
cout << "To view the database, press 1\nTo edit the database, press 2\nTo search the database, press 3\nTo log in, press 4\n";
cin >> db;
system("CLS");
if (db == 1)
{
cout << "Here is the database: \n\n";
string line;
ifstream myfile("test2.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{
cout << line << '\n';
}
}
//open while bracket
cout << "\n\nWould you like to return to the menu(y/n)?";
cin >> repeat;
if (repeat == 'y')
{
loop = true;
}
else if (repeat == 'n')
{
loop = false;
}
system("CLS");
}
else if (db == 2)
{
cout << "Please enter your username : ";
cin >> username;
cout << "\nPlease enter your password: ";
cin >> password;
SaveScore();
cout << "\n\nWould you like to return to the menu(y/n)?";
cin >> repeat;
if (repeat == 'y')
{
loop = true;
}
else if (repeat == 'n')
{
loop = false;
}
system("CLS");
}
}
}
You say your program is
replacing the first line of the text file everytime I try to write something new into it
As it turns out, that's exactly what you have asked it to do. Consider:
Database << username << " " << password << "\n";
Database.seekp(0,std::ios::end); //to ensure the put pointer is at the end
You are opening the file (when the write pointer starts at the start of the file, writing some data, and then seeking to the end. Seeking to the end does not change the fact that you've already written the text. Swap the order of the above lines to get what you want.
Alternatively, you can open the file in "append" mode using:
Database.open("test2.txt", std::ios::app);
In this situation, you can omit the call to seekp entirely, since all data will automatically be written to the end of the file. See http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream for full documentation on this.

Having trouble validating a file over and over again

One of the things my program needs to do is validate a file using the isValid function entered by user and it will keep doing this until exit is entered and if I enter nothing but valid file names there are no problems. But when I enter an invalid file name followed by a valid file name it still says the file is invalid and I cannot figure out why and I have tried debugging it and what not and still cannot find the problem. Any help would be greatly appreciated!
# include <iostream>
#include <string>
#include<fstream>
#include<vector>
using namespace std;
void Open_file(string name)
{
ifstream my_file;
my_file.open(name.c_str());
}
bool isValid(ifstream& file, string name)
{
if ((name.substr(name.length() - 4)) != (".htm"))
{
return false;
}
cout << file << endl;
if (file.good())
{
return true;
}
else
{
return false;
}
}
string File_title(ifstream& my_file)
{
string title;
string line;
size_t first_title;
size_t second_title;
string str;
while((getline(my_file,line)))
{
str = str + line;
}
first_title = str.find("<title>");
second_title = str.find("</title>");
title = str.substr(first_title + 7, (second_title) - (first_title + 7));
return title;
}
void Output_function(ifstream& my_file)
{
string line;
ifstream MyFile("titles.txt");
string g = File_title(my_file);
while(getline(MyFile, line))
{
if((g == line))
{
return;
}
}
ofstream out_title("titles.txt", fstream::app);
out_title << g << endl ;
}
void Clear_file()
{
ofstream out_title("titles.txt");
out_title << "" << endl;
}
int main()
{
string file_name;
while (file_name != "exit")
{
cout <<"please enter a HTML file name or hit 'exit' to quit and " << endl;
cout << "if you want to clear file please enter 'clear': ";
getline(cin,file_name);
ifstream my_file(file_name.c_str());
cin.ignore(256, '\n');
if(file_name == "clear")
{
Clear_file();
break;
}
while ((isValid(my_file, file_name) == false))
{
cin.clear();
cout <<"Invalid file name, please enter a valid file name: ";
getline(cin,file_name);
ifstream my_file(file_name.c_str());
}
Open_file(file_name);
Output_function(my_file);
my_file.close();
}
}
ifstream my_file(file_name.c_str());
This doesn't replace the my_file you'd already created in an outer scope. It just makes a new local variable that lives for like a nanosecond.
You'll have to close then re-open the existing my_file, being sure to reset its error flags too.
The logic you are using to exit the loop is flawed.
You need to check the value of file_name right after it is entered, not after it is processed in the while loop once.
You need to use something along the lines of:
while ((file_name = get_file_name()) != "exit")
{
...
}
where
std::string get_file_name()
{
std::string file_name;
cout <<"please enter a HTML file name or hit 'exit' to quit and " << endl;
cout << "if you want to clear file please enter 'clear': ";
getline(cin,file_name);
return file_name;
}
Other improvements:
The call to cin.ignore() is going to be a problem line since std::getline does not leave the newline character in the input stream. You'll have to type Enter one more time. You should remove it.
You don't need the cin.clear() line. You need cin.clear() only if an error was detected in reading from the stream -- such as when using cin >> var; when the input stream did not have the right data suitable for var.
You don't need to open the file if the file is not valid.
You don't need multiple lines ifstream my_file(file_name.c_str());. You only need it once, just before the call to Output_function(my_file).
You don't need to explicitly call my_file.close(). The file will be closed and the end of the scope.
Here's a simplified version of main.
int main()
{
string file_name;
while ((file_name = get_file_name()) != "exit")
{
if(file_name == "clear")
{
Clear_file();
break;
}
while ( isValid(my_file, file_name) == false )
{
cout <<"Invalid file name, please enter a valid file name: ";
getline(cin,file_name);
}
Open_file(file_name);
ifstream my_file(file_name.c_str());
Output_function(my_file);
}
}

Writing function output to a text file?

I'm making a program that reads a set of names and numbers from one file, expresses the numbers as a ratio, then prints them out to the terminal. I would like to know how I could redirect the output of my functions to a separate file. I have an output file ready, but am unsure of how to redirect my functions' outputs to it.
I didn't include the functions themselves here, which work fine - just the calls.
int main(){
ifstream input;
ofstream output;
string inputname, outputname, name;
int num1, num2;
cout<<"Input file?\n";
cin>>inputname;
cout<<"Output file?\n";
inFile.open(inputname.c_str());
cin>>outputfile;
outFile.open(outputname.c_str());
while(!input.eof()&&!output.eof()){
input>>name>>num1>>num2;
lists (name);
value (num1, num2);
}
input.close()
output.close()
return 0;
}
Have a look at Input/Output with files
Example:
ofstream myfile;
myfile.open ("example.txt");
myfile << "Writing this to a file.\n";
myfile.close();
As you see, it's very similar to how you're getting the data from fileA.
You have multiple undefined variables (Always test your program before posting!). And you're not checking for eof on the input file correctly. You need to test for eof right after a read operation to see if it succeeded.
int main(){
cout << "Input file?\n";
string inputname;
cin >> inputname;
ifstream input(inputname.c_str());
if (!input) return 1; // handle error however you wish
cout << "Output file?\n";
string outputname;
cin >> outputname;
ofstream output(outputname.c_str());
if (!output) return 2;
while (1) {
string name;
int num1, num2;
input >> name >> num1 >> num2;
if (!input) break;
lists(name);
value(num1, num2);
}
return 0;
}