Loop to check existence of file and process it - c++

I am starting the first part of a school assignment and I must prompt the user to enter a filename, check for the existence of the file, and if it exists, open it for processing; otherwise I am to have the user enter another filename.
When I compile and run my program below, I get the error message "No file exists. Please enter another filename." When I type in names of files that don't exist it just runs the first part of my do while loop again. I'm a beginner at C++ but I've done this before and I feel as if it should be running properly. Any help would be appreciated.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct customerData
{
int _customerID;
string _firstName, _lastName;
double _payment1, _payment2, _payment3;
};
void processFile();
int main()
{
processFile();
system ("pause");
return 0;
}
void processFile()
{
string filename;
ifstream recordFile;
do
{
cout << "Please enter a filename\n";
cin >> filename;
recordFile.open(filename);
if (recordFile.good())
// {
// enter code for if file exists here
// }
;
}
while(recordFile.fail());
{
cout << "No file by that name. Please enter another filename\n";
cin >> filename;
recordFile.open(filename);
}
}

To check whether a file was successfully opened you must use the std::fstream::is_open() function, like so:
void processfile ()
{
string filename;
cout << "Please enter filename: ";
if (! (cin >> filename))
return;
ifstream file(filename.c_str());
if (!file.is_open())
{
cerr << "Cannot open file: " << filename << endl;
return;
}
// do something with open file
}
The member functions .good() and .fail() check for something else not whether the file was opened successfully.

I'm not 100% sure what your intent is here, but do you understand that you've only got one loop here? After your do/while loop, you've got some code in braces, but that's not connected to any loop construct... it's simply a new scope (which doesn't serve a purpose here).
So, your program does this:
1) Ask for filename. Try to open it. If file stream can be read, do the "enter code here" part.
2) Check if filestream is "bad". if so, go back to step 1. Otherwise, continue.
3) Print out "no file by that name", prompt for a new file, try to open it
That's almost certainly not what you want.

You can use c code.
FILE *fp = fopen("file" "r");
if(fp){
//do stuff
}
else{
//it doesnt exist
}
on a side note, when using namespace std try to make it not global
you can put it inside of your functions instead when necessary
int main(){
using namespace std;
//other std stuff
}

Related

File stream with repeating input

I'm attempting to create a repeating menu that will allow a user to re-enter a file name if the program is unable to open the file.
Right now it works correctly if I enter the name of an existing file, but if the file doesn't exist it prints the "File not found" then executes the rest of the program. I'm new to file streams and most of the code here was found through references. I'm a bit lost on what exactly is going on and what the best way to handle the situation is. Any guidance would be appreciated.
typedef istream_iterator<char> istream_iterator;
string fileName;
ifstream file;
do {
cout << "Please enter the name of the input file:" << endl;
cin >> fileName;
ifstream file(fileName.c_str());
if (!file) {
cout << "File not found" << endl;
}
} while (!file);
std::copy(istream_iterator(file), istream_iterator(), back_inserter(codeInput));
After constructing the object file will always exist, so your loop condition always fails. Change the condition to whether the file didn't open properly.
do {
...
}
while (!file.is_open())
this code will work.
do {
std::cout << "Please enter the name of the input file:" << std::endl;
std::cin >> fileName;
file = std::ifstream(fileName.c_str());
if (!file) {
std::cout << "File not found" << std::endl;
}
} while (!file);
your error was that you have 2 definition of the file variable.
the variable in while (!file) that is used is the one defined outside the do-while loop, and it is valid state is set to true by default.
In addition to #acraig5075 answer:
Writing a type then a variable name (ifstream file) is to create a new variable. Obviously you know this, but if you use the same name again in, for example, a loop, it makes a new and distinct variable.
ifstream file; // a unique variable
...
do {
...
ifstream file(fileName.c_str()); // another unique variable
...so change the usage inside the loop to:
file.open(fileName.c_str());

Open a file with C++ and output the text that is in the file

I am trying to open a file with C++ and output the text that is in the file. I cannot seem to figure out what I am doing wrong. Here is what I have so far.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
char fileName[50];
ifstream infile;
cout << "Enter the name of the file you would like to open: ";
cin.getline(fileName, 50);
infile.open(fileName);
if(!infile.is_open())
{
exit(EXIT_FAILURE);
}
char line[75];
infile >> line;
while (infile.good())
{
cout << line << " ";
infile >> line;
}
system("pause");
return 0;
}
After I input the file name and press enter the CMD prompt just closes. I know that the file exist, but I cannot figure out why it is exiting. Obviously it is because of the exit command, but it should be open. What am I doing wrong?
You don't need to read/write the file line by line; C++ already supports to copy the file in one step. You also should use string instead of char[] for your strings; on one hand it means that you don't need to restrict the maximal length of your strings to some arbitrary length (what if your file's pathname has more than 50 characters, or the file has lines with more than 75 characters?
Note also that your file copying code is erroneous: It will remove all whitespace from the file, as infile >> line does not read a line (use readline for that), but a word, discarding whitespace.
Also, your code should give an error message if it couldn't open the file, instead of just silently returning (you do provide an error return, which is very good, but unless you call it from something that actually gives you feedback on the error return, you'll never learn about it.
Finally, the system("pause") should probably be done in an RAII class, so it is guaranteed to be exited on return (however, exit will not call destructors, so unless you want to use atexit, you should use return in `main`` instead). A better idea would, however, be to not put this into the code, but instead run it in a terminal that doesn't immediately close after the program finishes.
Here's a program that implements those suggestions:
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
// make sure that system("pause") is called on all exit paths
struct cleanup
{
~cleanup() { std::system("pause"); }
} do_cleanup;
// get the file name
std::string filename;
std::cout << "Enter the name of the file you would like to open: ";
std::getline(std::cin,filename);
if (!std::cin)
{
std::cerr << "Failed to read the file name.\n";
return EXIT_FAILURE;
}
// open the file
std::ifstream infile(filename.c_str());
if (!infile)
{
std::cerr << "Could not open file: " << filename << "\n";
return EXIT_FAILURE;
}
// print the file
std::cout << infile.rdbuf();
// close the file
infile.close();
if (!infile)
{
std::cerr << "Could not properly close file: " << filename << "\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
There is no need to use a char[]. You've even #included string so just use that.
string fileName;
cout << "Enter the name of the file you would like to open: ";
cin >> fileName;
// or
// getline(cin, fileName);
ifstream infile(fileName);
if (infile.fail()) {
exit(EXIT_FAILURE);
}
string line;
while (infile >> line) {
cout << line << " ";
}
system("pause");
return 0;
I also modified a few things to make it a bit cleaner.
Thanks for the help. Yes the file was in the wrong folder. It was a newb oversight!

Odd behavior in C++ program

I am writing a program that I allow the user to specify an input file to open and when I test with incorrect file names, the program is behaving very weird and it seems to have something to do with the input buffer, but I don't know where to begin other than using getline() instead of cin >> but I have already tried that.
here is the code that I think may be the problem:
bool openfile(ifstream&);
string userInput();
int main()
{
// ...
while (!openfile(inputFile))
openfile(inputFile);
string input = userInput();
// ...
}
bool openfile(ifstream &inputFile)
{
string filename;
cout << "Please enter the name of the file or type quit to exit the program: ";
cin >> filename;
cout << endl;
if (filename == "quit")
exit(4);
else
inputFile.open(filename);
if (!inputFile)
{
cout << "The file \"" << filename << "\" could not be opened or does not exist.\n";
return false;
}
return true;
}
string userInput()
{
string englishSentence;
cout << "Please enter a sentence or type quit to exit the program: \n";
getline(cin, englishSentence);
if (englishSentence == "quit")
exit(4);
return englishSentence;
}
Those are the two functions that read any input. openfile() is called first as you can see. Any help is greatly appreciated. Let me know if you suspect something else in my code and I will paste it.
while (!openfile(inputFile))
openfile(inputFile);
What this does is attempt to open the file twice each iteration, as long as the first attempt fails. Also, you need to make sure that inputFile is closed before attempting to open it again since it appears that you're reusing the same file object repeatedly.
Certainly first try something like:
while (!openfile(inputFile))
;
You can just do:
while (!openfile(inputFile));
Since the way you have it it would request an input filename twice if it fails the first time.
Basically to outline the problem:
Begin Loop
Request Filename
Invalid Filename
Request Replacement Filename
Return to start of the loop (Checks again)
Some problems I see from your code:
int main(); { ... } does not define the main function. You need to drop the semicolon, or it won't even compile.
while (!openfile(inputFile)) openfile(inputFile); repeats openfile(inputFile) unnecessarily. If the first one (in the condition) fails and the second one (in the body) succeeds, a third call will be made (in the condition) to check if the loop should continue. What you probably want is just while (!openfile(inputFile)) { }.
You open a file in openfile and never use it in the subsequent userInput.

Save system not opening fstream files?

I am working on a save file system for a game, and trying to make sure I can get the file open in a small test program, determine whether it is empty, if it is empty prompt the user to create a character, and if its not empty load the character's information into variables to be used for the game. So far in my testing I've created the files in notepad (leaving them empty), saved them with appropriate extensions, and attempted to open the file and test if they are empty.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main ( int argc, char* argv[])
{
struct charFile
{
int chapterNum;
int savePoint;
string firstName;
char gender, hairColor, hairType, hairLength, eyeColor, profession, magic, martialSkills;
bool hasPet;
} character;
fstream save;
char saveFileChoice;
string saveFile;
cout << "Select a File (1, 2, 3, 4, 5, or 6): ";
cin >> saveFileChoice;
saveFile = saveFileChoice + ".charsav";
save.open(saveFile.c_str());
if (!save.good())
{
cout << "Save file cannot be opened.\n";
}
char tempStr[12];
save.getline (tempStr, 256);
if ( tempStr == "EMPTY" )
{
cout << "There is no save data in the file. Starting a new game...\n\n";
cout << "What is your character's name? ";
cin >> character.firstName;
save << character.firstName;
}
return 0;
}
I was wondering why the file was never dropping into the if statement even though it was empty, and then even when I added EMPTY ascii characters to the file and changed the condition. Then I put in:
if (!save.good())
{
cout << "Save file cannot be opened.\n";
}
and on running it constantly displays the message so for some reason the file isn't opening. =/ I can't figure out why though.
I've checked the files and they are not being formatted as .charsav.txt or anything, they are still just 1.charsav, 2.charsav, etc. I feel like I'm missing something easy and obvious. Can anybody point it out for me?
if (!strcmp(tempStr, "EMPTY" )) is how you compare strings

C++ Opening file stream

So i basically need my program to open a file and do something. When the program asks for the user to input the file name, and the user inputs the name of file correctly the first time, the operation works. But if the user typed the name wrong, the program says "invalid name try again" but then it is never able to open the file even if the user types the name correctly. Here's the code:
ifstream read_file(file.c_str());
while(true)
{
if(!(read_file.fail()))
{
...
}
else
{
cout << "Either the file doesn't exist or the formatting of the file is incorrect. Try again.\n>";
}
cin >> file;
ifstream read_file(file.c_str());
}
What is the problem, any thoughts? Thank you
You are redeclaring read_file inside the loop, but the code at the top of the loop always use the read_file outside the loop.
This is what you want instead:
ifstream read_file(file.c_str());
while(true)
{
if(!(read_file.fail()))
{
...
}
else
{
cout << "Either the file doesn't exist or the formatting of the file is incorrect. Try again.\n>";
}
cin >> file;
read_file.open(file.c_str()); /// <<< this has changed
}