Skip to main content

Section 6.6 The End-Of-File (EOF) for Systems that Implement eof()

So far, the assumption was that the programmer knew exactly how much data to read from an open file. However, it is common for a program to keep reading from a file without any idea how much data exists. Most versions of C++ incorporate an end-of-file (EOF) flag at the end of the file to let programs know when to stop. Otherwise, they could read data from a different file that happened to be right after it in the hard drive, which can be disastrous.
Many development environments have I/O libraries that define how the member function eof() works for ifstream variables to test if this flag is set to true or false. Typically, one would like to know when the EOF has not been reached, so a common way is a negative boolean value. An alternative implementation is to keep reading using the >> operator; if that operation was successful (i.e. there was something in the file that was read), this success is interpreted as a 1 (true).
Incidentally, that is why if you forget the second equals sign in a comparison between a variable and a value, you are assigning the value to the variable, which is a successful operation, which means the condition ends up evaluating to true.
The following two code fragments highlight the possibilities:
Using the eof() member function
while(!in_stream.eof()) {
    // statements to execute
    // while EOF has not been
    // reached
}
Using the >> operator
while(in_stream>>inputn) {
    // statements to execute
    // while reads are successful
}
Here is an example of a program that essentially uses the second technique mentioned above to read all the numbers in a file and output them in a neater format. The while loop to scan through a file is located in the make_neat(...) function.
// Illustrates output formatting instructions.
// Read all the numbers in the file rawdata.dat and write the numbers
// to the screen and to the file neat.dat in a neatly formatted way.

#include <cstdlib>  // for the exit function
#include <fstream>  // for I/O member functions
#include <iomanip>  // for the setw function
#include <iostream> // for cout
using namespace std;
void make_neat(
    ifstream &messy_file,
    ofstream &neat_file,
    int number_after_decimalpoint,
    int field_width);

int main() {
    ifstream fin;
    ofstream fout;

    fin.open("rawdata.txt");
    if (fin.fail()) { // oops the file did not exist for reading?
        cout << "Input file opening failed." << endl;
        exit(1);
    }

    fout.open("neat.txt");
    if (fout.fail()) { // oops the output file open failed!
        cout << "Output file opening failed.\n";
        exit(1);
    }
    make_neat(fin, fout, 5, 12);

    fin.close();
    fout.close();
    cout << "End of program." << endl;
    return 0;
}
// Uses iostreams, streams to the screen, and iomanip:
void make_neat(
    ifstream &messy_file,
    ofstream &neat_file,
    int number_after_decimalpoint,
    int field_width) {
    // set the format for the neater output file.
    neat_file.setf(ios::fixed);
    neat_file.setf(ios::showpoint);
    neat_file.setf(ios::showpos);
    neat_file.precision(number_after_decimalpoint);
    // set the format for the output to the screen too.
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.setf(ios::showpos);
    cout.precision(number_after_decimalpoint);
    double next;
    while (messy_file >> next) { // while there is still stuff to read
        cout << setw(field_width) << next << endl;
        neat_file << setw(field_width) << next << endl;
    }
}
// Code by Jan Pearce
This is the rawdata.txt inputed into the make_neat(...).
10 -20 30 -40
500 300 -100 1000
-20 2 1 2
10 -20 30 -40
And this is the expected output
  +10.00000
  -20.00000
  +30.00000
  -40.00000
 +500.00000
 +300.00000
 -100.00000
+1000.00000
  -20.00000
   +2.00000
   +1.00000
   +2.00000
  +10.00000
  -20.00000
  +30.00000
  -40.00000
The input file rawdata.txt must be in the same directory (folder) as the program in order for it to open successfully. The program will create a file called “neat.dat” to output the results.

Reading Questions Reading Question

1.

What are good use cases for EOFs in C++ programming?
  • To keep a program from writing into other files.
  • Yes, EOFs are intended to prevent the program from overwriting a file.
  • To keep a program from stopping.
  • Not quite, the point of EOFs is to do the opposite.
  • To make sure you do not overflow into temporary buffer.
  • Yes, EOFs prevent overflow into temporary buffer.
  • To stop an input files stream.
  • Yes, EOFs stop input file streams.
You have attempted 1 of 2 activities on this page.