Handling end-of-file (eof) correctly

The eof() function, as in   infile.eof()  , is a bool function which is true if the EOF character has been read, false otherwise. When you have read the last item in a file, the eof function may not be true yet. Often you have to read past the last item in the file to read the EOF character so the eof function will be true.

Unix/Linux vs. Windows/Mac

On unix/linux, every line in a file has an End-Of-Line (EOL) character and the EOF character is after the last line. On windows, each line has an EOL characters except the last line. So unix/linux file's last line is
      stuff, EOL, EOF
whereas windows file's last line, if the cursor is on the line, is
      stuff, EOF

So set up data files on windows/mac to be the same as on unix/linux. This way, you will correctly determine eof under both unix/linux and windows/mac. In general, you must exit all loops and all functions immediately when you are attempting to read an item that would be past the eof.

Here is a typical set up that will work correctly. Suppose in a data file, there are multiple lines of data. In some function is the loop where you are reading and handling this data. This loop will look similar to the following.
     // infinite loop to read and handle a line of data
     for (;;) {
        infile >> firstThingOnTheLine;
        if (infile.eof()) break;

        // read the rest of the line
        // do whatever with data
     }
If you dislike infinite loops, you can accomplish this same thing using a while loop by priming the loop and reading again at the end:
     infile >> firstThingOnTheLine;
     while (!infile.eof()) {
        // read the rest of the line
        // do whatever with data

        infile >> firstThingOnTheLine;
     }
You MUST do it one of these ways. Do not adjust your code. Adjust the data file on windows/mac to work with this code. To do that, when the cursor is at the end of the last line of data, press return. (Don't do this on linux.) The best way to create the datafile on linux is by using pico, e.g., pico data3.txt, then copy and paste into data3.txt.

Often reading is done in a routine. In that case, exit both when eof. This loop is similar to that situation.

     ObjClass obj;

     // wherever reading datafile is done
     for (;;) {
        obj.setData(infile);      // method does reading
        if (infile.eof()) break;

        // do whatever with obj
     }

     void ObjClass::setData(istream& infile) {
          infile >> firstThingOnTheLine;   // so EOF char is read
          if (infile.eof()) return;        // determine no more data

          // probably read more data to fill rest of object
     }