File Input Example
CS-150, Fall ’02, Dr. C. S. Tritt

Source File (reading.cpp)

/*

Some comments removed…

Description:

   This program demonstrations opening and reading
   from text files.

More comments removed…

Error Control

  Returned values

  0   No error.
  1   File open error.
  2   File read error.

*/

// Included files.

#include <iostream>
#include <fstream> // Needed for file i/o.

// These macros mimic the ANSI C++ logical operations.

#define and &&
#define or ||
#define not !

using namespace std;

int main()
{

   double a;

// Reading with open check and .fail() and .eof() control.
// Best approach.

   cout << "About to open input file.\n";

// Open file and check for errors.

   ifstream fin("read.dat"); /* Create a ifstream object and associate
it read.dat. */

if (not fin) // Deal with file open failure.
   {
      cout << "Couldn't open input file. Aborting.\n";
      return 1;
   }

   cout << "Reading values with eof control.\n";

   while (fin >> a) cout << a << " was read.\n";

   if (not fin.eof())
   {
      cout << "Error while reading.  Aborting.\n";
      fin.close(); // Close the stream/file.
      return 2;
   }

   fin.close(); // Close always close files when you're done.

// Correct use of a sentinel value. Note use of .fail().

   const double SENTINEL = -1.0; // Set sentinel value.

   fin.clear(); // Closing stream doesn't clear errors, use .clear().
   fin.open("read2.dat"); // Open read2.dat using pre-existing stream.
   if (not fin) // Deal with file open failure.
   {
      cout << "Couldn't open input file. Aborting.\n";
      return 1;
   }

   cout << "Reading values with a sentinel value.\n";

   fin >> a; // Initial read needed due to "loop-and-a-half" problem.
   while (not fin.fail() and a != SENTINEL)
   {
      cout << a << " was read.\n";
      fin >> a;
   }

   if (fin.fail())
   {
      cout << "Error reading. Aborting.\n";
      fin.close(); // Close the stream/file.
      return 2;
   }

   fin.close(); // Close the stream/file.

// Incorrect use of a sentinel value can lead to infinite loop.
// Member function .fail() not used. This approach is common in
// older programs and programs written by sloppy programmers.

   fin.clear(); // Closing stream doesn't clear errors, use .clear().
   fin.open("read3.dat"); // 0pen read3.dat without error control. Bad!

   cout << "Using only a sentinel value. A bad idea.\n";

   fin >> a;
   while (a != SENTINEL) // No test for failure!
   {
      cout << a << " was read.\n";
      fin >> a;
   }

   fin.close(); // Close the stream/file.

   // We assume everything worked.

   cout << "We assume everything worked.\n";
	return 0;
}

Data Files (read.dat, read2.dat and read3.dat)

12.34 3.56 67.89

12.34
34.56
67.89
-1.0

12.34
34.56
67.89
-1.0