Hello programmers!

I was working on a program that reads a sequential file with bank accounts.
The file has three sets of data per line: the account #, the account holder's name, and balance.
Then, I made a program to print the file- and it printed the last line of the file twice.

Here is the program:

//  Reading and printing a sequential file

#include <iostream>
#include <fstream> //file stream
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;

void outputLine(int, const string&, double); //prototype

int main()
{
    //ifstream construtor opens the file
    ifstream inClientFile("clients.txt",ios::in);

    //exit program if ifstream could not open file
    if (!inClientFile)
    {
        cerr << "File could not be opened" << endl;
        exit(EXIT_FAILURE);
    }

    int account; //account number
    string name; //the account owner's name
    double balance; //the account balance

    cout << left << setw(10) << "Account" << setw(13) << "Name" << "Balance" << endl << fixed << showpoint;

    //display each record in file
    while  (!inClientFile.eof())
    {
        inClientFile >> account >> name >> balance;
        outputLine(account,name,balance);
    }

    return 0;
}

//display single record from file
void outputLine(int account,const string& name, double balance)
{
    cout << left << setw(10) << account << setw(13) << name << setw(7) << setprecision(2) << right << balance << endl;
}

The file is called "clients.txt". Its content is:

200 nata 266
344 joey 2.44

After seeing this, it is pretty straightforward that the program read the last line twice.

However, I changed the last loop to this, and it worked!

    //display each record in file
    while  (inClientFile >> account >> name >> balance)
    {
        outputLine(account,name,balance);
    }

What was the difference between the old version of the loop and the new version of the loop? Why did the new one work, and the old one did not? Thanks.

The difference is that eof() doesn't recognize end-of-file until an actual read is performed. When at end-of-file line 31 doesn't know it yet until line 33 is executed. But line 34 is executed whether at eof or not. That's a common mistake that new programmers do -- IMO eof() is almost a useless function.

To add. The program did not read the last line twice, it failed to read anything in the last attempt and the previous values were used again.

Two ways to correct this. My preferred way is to use the input as the loop condition. If the input succeeds, there is a non-zero value. If it fails, there's a zero value.

    while  (inClientFile >> account >> name >> balance  )
    {
       outputLine(account,name,balance);
    }

If you are dead set on using .eof( ), then correct way is to first read outside the loop, sometimes called a priming read.
Then test .eof( ) in your loop condition, and have a read at the end of the loop body.

   inClientFile >> account >> name >> balance;
   while  (!inClientFile.eof())
    {
         outputLine(account,name,balance);
         inClientFile >> account >> name >> balance;
    }

Additionally, I would avoid doing chained input as you for any program that you cannot be absolutely sure the input will be correct. If any of the inputs in that sequence are bad, you have no way to recover.

This article has been dead for over six months. Start a new discussion instead.