Try-Catch Block For C++ File-IO Errors Not Working

37,357

Solution 1

In C++ iostreams do not throw exeptions by default. What you need is

ifstream myfile("test.txt");

if(myfile) {
   // We have one
}
else {
   // we dont
}

Solution 2

By default the fstream objects do not throw. You need to use void exceptions ( iostate except ); to set the exception behavior. You can fetch the current settings using iostate exceptions ( ) const;. Change your code just a bit:

#include <fstream>
#include <iostream>
#include <stdexcept>
using namespace std;

int main () 
{
  try{
      char buffer[256];
      ifstream myfile ("test.txt");
      myfile.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
      while (myfile)
      {
        myfile.getline (buffer,100);
        cout << buffer << endl;
      }
      myfile.close();

  }catch(std::exception const& e){
     cout << "There was an error: " << e.what() << endl;
  }
  return 0;
}

Solution 3

First of all, for the try block to do any good, you need to enable exceptions for the stream.

Second, a loop like:

  while (! myfile.eof() )

Will lead to nothing but trouble, and you're seeing that here. The problem (in this case) is that when the file failed to open, eof will never be signaled -- you can't/don't reach the end of the file because there is no file. Therefore, your loop runs forever, on an existentialist search for the end of a nonexistent file. Fix the loop, and things get better in a hurry:

 char buffer[256];
 ifstream myfile ("test.txt");

 while (myfile.getline(buffer,100))
 {
   cout << buffer << endl;
 }

While you're at it, a bit more fixing wouldn't hurt (unless you really meant to use less than half of the space you allocated for your buffer):

 char buffer[256];
 ifstream myfile ("test.txt");

 while (myfile.getline(buffer,sizeof(buffer)))
 {
   cout << buffer << endl;
 }

Or, of course, eliminate the problem entirely:

std::string buffer;
ifstream myfile("test.txt");
while (getline(myfile, buffer))
    cout << buffer << "\n";

Edit: note that none of these (at least currently) depends on exceptions at all. They're all set up to write a line to the output if we succeeded in our attempt at reading a line from the input. If the file didn't open, the body of the loop simply won't execute, because we won't be able to read from a file that didn't open. If we want to print an error message telling the user that the file didn't open, we'd have to handle that separately from what's above. For example:

ifstream myfile("test.txt");

if (!myfile) {
    std::cerr << "File failed to open";
    return FAIL;
}

while (std::getline(myfile // ...
Share:
37,357
Jason R. Mick
Author by

Jason R. Mick

I currently work at Ford Motor Company (FMC) on the Human Machine Interface (HMI) development team. We are coding upcoming versions of SYNC and working to improve the reliability and functionality of SYNC3 for both Ford and Lincoln vehicles. In general, coding-wise I enjoy : Scripting Playing with data Optimization Here's some of my work: http://pubs.acs.org/doi/abs/10.1021/acs.jced.5b01002 http://scitation.aip.org/content/aip/journal/jcp/143/11/10.1063/1.4930138 http://www.sciencedirect.com/science/article/pii/S0010465513002270 Other hats I wore, prior to working at FMC: Tech Blogger : former executive editor/CEO of DailyTech, a Google News syndicated science and technology blog Ph.D. Script Wizard/Open Source Developer : graduate of the Potoff Lab at Wayne State University in Detroit, Michigan. Outside of coding I enjoy: Music Retro culture Pop culture Science fiction Running spending time with my wife and little dude

Updated on July 09, 2022

Comments

  • Jason R. Mick
    Jason R. Mick almost 2 years

    I'm very new to the world of C++ error handling, but I was told here:
    Checking for file existence in C++

    ...that the best way to checks for file existence was with a try-catch block. From my limited knowledge on the topic, this sounds like sound advice. I located this snippet of code:
    http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/Readafileintrycatchblock.htm

    #include <fstream>
    #include <iostream>
    using namespace std;
    
    int main () 
    {
      try{
          char buffer[256];
          ifstream myfile ("test.txt");
    
          while (! myfile.eof() )
          {
            myfile.getline (buffer,100);
            cout << buffer << endl;
          }
      }catch(...){
         cout << "There was an error !\n";
      }
      return 0;
    }
    

    ...but when I compile it using

    g++ -Wall -pedantic -o test_prog main.cc
    

    And run the program in a directory where test.txt does not exist, the prog keeps spitting out empty lines to the terminal. Can anyone figure out why?

    Also is this a good way to check for file existence for a file you actually want to open and read from (versus just something where your indexing a bunch of files and checking them over)?

    Thanks!

  • Jason R. Mick
    Jason R. Mick over 13 years
    So which is better (and why) -- this or enabling exceptions as dirkgently illustrates?
  • Martin York
    Martin York over 13 years
    @Jason: Don't use exceptions. Just test the file stream object.