28

I am new to C++ and want to add error checking to my code plus I want to make sure I'm using good coding practices. I read a line from an ASCII file into a string using:

ifstream paramFile;
string tmp;

//open input file

tmp.clear();

paramFile >> tmp;

//parse tmp
  1. How can I error check to make sure the input file read was successful?

  2. I'm seeing much more complicated ways of reading from an ASCII file out there. Is the way I'm doing it "safe/robust"?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
slowmotionfred
  • 293
  • 1
  • 3
  • 8

1 Answers1

24

paramFile >> tmp; If the line contains spaces, this will not read the whole line. If you want that use std::getline(paramFile, tmp); which reads up until the newline. Basic error checking is done by examining the return values. For example:

if(paramFile>>tmp) // or if(std::getline(paramFile, tmp))
{
    std::cout << "Successful!";
}
else
{
    std::cout << "fail";
}

operator>> and std::getline both return a reference to the stream. The stream evaluates to a boolean value which you can check after the read operation. The above example will only evaluate to true if the read was successful.

Here is an example of how I might make your code:

ifstream paramFile("somefile.txt"); // Use the constructor rather than `open`
if (paramFile) // Verify that the file was open successfully
{
    string tmp; // Construct a string to hold the line
    while(std::getline(paramFile, tmp)) // Read file line by line
    {
         // Read was successful so do something with the line
    }
}
else
{
     cerr << "File could not be opened!\n"; // Report error
     cerr << "Error code: " << strerror(errno); // Get some info as to why
}
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • Thanks Jesse. I didn't know you could evaluate a stream as boolean. Very helpful! – slowmotionfred Nov 19 '12 at 02:05
  • 1
    Yes, all streams have this, as they inherit it from `std::basic_ios`. Here is a [reference](http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool). – Jesse Good Nov 19 '12 at 02:15
  • Great reference Jesse! I hadn't found that one yet. Thanks! – slowmotionfred Nov 19 '12 at 02:29
  • HAY! you don't check for IO errors whe file already open(!) how to do that correctly ? – socketpair Apr 27 '14 at 06:53
  • @socketpair: Could you explain more? I'm not sure what you are asking. – Jesse Good Apr 27 '14 at 21:59
  • 3
    Suppose file is already open (successfully). Next, I read some data successfuly. But unfortunatelly someone removes floppy drive with my file. I'mt trying to read and receive IOerror from OS syscall. So, How I can detect such situation? In other words, We should distinguish between EOF and IOError. std::getline returns stream. operator bool on the stream returns "!stream->fail()". but on eof failbit is also set... so logic become nightmare. (see table at http://www.cplusplus.com/reference/ios/ios/fail) and also, note that trying to read stream which is at EOF also set failbit. AAAAAAA :( – socketpair May 01 '14 at 19:35
  • @socketpair: `I'm trying to read and receive IOerror from OS syscall.`. That's what `errno` is for, I use it on the last line `strerror(errno)`. – Jesse Good May 02 '14 at 03:26
  • @socketpair: io error is indicated by `badbit`. So you can check for `stream->bad()` for this matter, I believe. This should tell that the problem is in i/o, but still without any details. `errno` should work but there's no guarantee that it will be set or it worn't be corrupted by the stream itself. – Arks Feb 11 '15 at 12:41