0

Ok my question is I'm just confused as to what's going on. If you take a look at the whole while loop, I don't understand what's the purpose of the first read statement, when in the inner while loop there's a read statement as well. Doesn't the whole inner while loop take care of all the reading? What's the purpose of reading account, name, and balance before the inner while?

Oops, the program just processes a credit manager's request and displays according records for people whose balances match that of the request.

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

      enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE, DEBIT_BALANCE, END };
      int getRequest();
      bool shouldDisplay( int, double );
      void outputLine( int, const string &, double );

      int main()
      {
          // ifstream constructor 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);
          } // end if

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

          // get user's request(e.g., zero, credit or debit balance)
          int request = getRequest();

          // process user's request
          while ( request != END )
          {
            switch ( request )
            {
              case ZERO_BALANCE:
                 cout << "\nAccounts with zerobalances: \n";
                 break;
              case CREDIT_BALANCE:
                 cout << "\nAccounts with credit balances:\n"
                 break;
              case DEBIT_BALANCE:
                 cout << "\nAccounts with debit balances:\n";
                 break;
            } // end switch

            // read account, name a balance from file(also this is what
            // confused about, like this is the statement that seems moot to me)
            inClientFile >> account >> name >> balance;

            // display file contents
            while ( !inClientFile.eof() )
            {
               // display record
               if ( shouldDisplay( request, balance ) )
                  outputLine( account, name, balance );

               // read account, name and balance from file(again
               // i thought this was the only required reading statement
               // because it goes until EOF 
               inClientFile >> account >> name >> balance;
               } // end inner while

               inClientFile.clear(); // reset eof for next input
               inClientFile.seekg( 0 ); // reposition to beginning of file
               request = getRequest(); // get additional request from user
          } // end outer while

          cout << "End of run." << endl;
} // end main

// obtain request from user
int getRequest()
{
  int request; // request from user

  // display request options
  cout << "\nEnter request" << endl
       << " 1 - List accounts with zero balances" << endl
       << " 2 - List of accounts with credit balances: << endl
       << " 3 - List of accounts with debit balances" << endl
       << " 4 - End of run" << fixed << showpoint;


 do // input user request
 {
   cout << "\n?;
   cin >> request;
 } while ( request < ZERO_BALANCE && request > END );

 return request;
} // end function getRequest


// determine whether to display given record
bool shouldDisplay( int type, double balance )
{
  // determine whether to display zero balances
  if ( type == ZERO_BALANCE && balance == 0 )
     return true;

  // determine whether to display credit balances
  if ( type == CREDIT_BALANCE && balance < 0 )
     return true;

  // determine whether to display debit balances
  if ( type == DEBIT_BALANCE && balance > 0 )
     return true;

  return false;
  // SIDE QUESTION PLZ*-why do you think the book didn't use else if
  // like wouldn't it make sense, or...? just curious, thank you

} // end function shouldDisplay

// 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;
tshepang
  • 10,772
  • 21
  • 84
  • 127
Shinji-san
  • 893
  • 3
  • 11
  • 27

1 Answers1

0

The loop works by first reading the values from file and then checking if the last read operation resulted in eof or not. This is why the read code is both before the while loop and inside it.

I think this loop can be replaced by:

// display file contents
while ( inClientFile >> account >> name >> balance )
{
   // display record
   if ( shouldDisplay( request, balance ) )
      outputLine( account, name, balance );

 } // end inner while

EDIT:

Also note that this would be incorrect usage:

while ( !inClientFile.eof() )
{
   inClientFile >> account >> name >> balance;
   // display record
   if ( shouldDisplay( request, balance ) )
      outputLine( account, name, balance );
} // end inner while

This is because while reading the inputs end of file may have reached and then we would be working with invalid data. Hence we need to check for eof after every read operation.

Hence, it is usually recommended to avoid using eof.

Abhishek Bansal
  • 12,312
  • 4
  • 27
  • 43
  • Oh, well that makes much more sense LOL. Hm, it just seems like the loop was doing something else, like something preliminary. Thanks though! – Shinji-san Dec 19 '13 at 11:00
  • um couldn't you use the same argument if those two statements were reversed? Can't I just end up reading invalid data regardless of the order? Thanks – Shinji-san Dec 19 '13 at 11:18
  • @Shinji-san Check this link. http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Abhishek Bansal Dec 19 '13 at 11:24
  • ok forgive me..I have a stupid question >.< , so I don't understand how much is read for the first read statement. like for example the first read statement, is that reading all accounts, like the inner read does? – Shinji-san Dec 19 '13 at 11:38
  • Yes the extraction operator works till there is a valid input to be read. It stops when error or eof occurs. – Abhishek Bansal Dec 19 '13 at 11:40
  • so if the first read statement goes until EOF what's the purpose of the inner while loop if it's just going to evaluate to false? huh? – Shinji-san Dec 19 '13 at 12:12