0

I have a program that creates three Person objects (name and address as data members) and then creates three Account objects (person object, account number, and account balance as data members). It then writes the data members from the accounts objects to a file and then clears the account objects. The program is then supposed to create new account objects and read in their data members from the same file and push them to a vector. That vector is used to display the data members.

The problem I am having is with reading in the account objects. Specifically reading in the person objects inside the account objects. I know that person objects should be the only ones accessing its data members. I just can't seem to get it to work. Everything compiles fine but it throws an exception when the object reads itself in.

Here is the associated code. I'll include just the readData methods for both classes and the entire driver.cpp code. Let me know if you need to see more.

Thank you!

Account.cpp

void Account::readData(ifstream &ifile)
{
    if (ifile.fail() || ifile.bad())
    {
        throw readFileException("Could not read file [account]");
    }
    else 
    {
        ifile >> accountNumber;
        ifile >> accountBalance;
        accountPerson.readData(ifile);
    }
}

Person.cpp

void Person::readData(ifstream &ifile)
{
    if (ifile.fail() || ifile.bad())
    {
        throw readFileException("Could not read file [person]");
    }
    else
    {
        getline(ifile, name);
        getline(ifile, address);
    }
}

Driver.cpp

#include "Driver.h"

using namespace std;

int main()
{

    vector<Account> a;

    Person john("John Stockton", "1 Jazz lane");
    Person karl("Karl Malone", "2 Jazz Ave");
    Person jerry("Jerry Sloan", "3 Jazz Street");

    Account a1(john, 1, 500.00);
    Account a2(karl, 2, 1000.00);
    Account a3(jerry, 3, 1200.00);

    a.push_back(a1);
    a.push_back(a2);
    a.push_back(a3);

    ofstream outFile("accounts.txt");

    for (int i = 0; i < a.size(); i++) //to write account info to accounts.txt
    {
        a[i].writeData(outFile);
    } //end for loop

    outFile.close();  // to close accounts.txt

    a.clear(); // clear vecter of accounts -- size now 0

    ifstream inFile("accounts.txt");

    while (!inFile.eof()) //Loop to read in accounts and push them to vector
    {
        Account b;
        try
        {
            b.readData(inFile);
            a.push_back(b);
        }
        catch (readFileException &e)
        {
            cout << "Error: " << e.getMessage() << endl;
            system("pause");
            exit(1);
        }
    } // end of while loop

    for (int i = 0; i < a.size(); i++)
    {
        a[i].deposit(DEPOSIT_AMNT);
    }//end for loop
    for (int i = 0; i < a.size(); i++)
    {
        a[i].withdraw(WITHDRAW_AMNT);
    }//end for loop

    displayAccounts(a);

    system("pause");
    return 0;
}

void displayAccounts(const vector<Account>& v)
{
    //To display column headings
    cout << fixed << setprecision(PRECISION);
    cout << setw(COLUMN_WIDTH_SHORT) << "Acct #" << setw(COLUMN_WIDTH_LONG)
        << "Name" << setw(COLUMN_WIDTH_LONG) << "Address"
        << setw(COLUMN_WIDTH_LONG) << "Balance" << endl;

    for (int i = 0; i < v.size(); i++)
    {
        Person p; 
        p = v[i].getPerson();

        cout << setw(COLUMN_WIDTH_SHORT) << v[i].getAccountNumber() << setw(COLUMN_WIDTH_LONG)
            << p.getName() << setw(COLUMN_WIDTH_LONG) << p.getAddress()
            << setw(COLUMN_WIDTH_LONG) << v[i].getAccountBalance() << endl;
    }//end for loop
}

The accounts.txt file is written like this:

1
500
John Stockton
1 Jazz lane
2
1000
Karl Malone
2 Jazz Ave
3
1200
Jerry Sloan
3 Jazz Street
Jason Carrick
  • 105
  • 1
  • 7
  • What exception? Where? By the way when you do input operations like `ifile >> accountNumber` you must check the return value to see if they succeeded. For example, do `if (!(ifile >> accountNumber)) throw runtime_error`. – John Zwinck Sep 28 '15 at 01:07
  • @JohnZwinck the exception I get is the one thrown inside the person class' readData method in person.cpp. – Jason Carrick Sep 28 '15 at 01:10
  • Well, one of your input operations is failing, that's for sure. Use my suggestion above to find out which one. Also please paste into the question the contents of the output file as written by your program currently. – John Zwinck Sep 28 '15 at 01:23
  • @JohnZwinck I have added the accounts.txt file to show how the data is written. – Jason Carrick Sep 28 '15 at 01:33

1 Answers1

1

Your code doesn't work because you are checking the input file for "failure" in the wrong way. You should never use while (!infile.eof), instead you should check each input operation as you go. For example:

if (!(ifile >> accountNumber))

if (!(getline(ifile, name)))

This way you also do not need to check for bad() and fail(). Instead, just run until an input operation fails.

For more detail on why your while loop doesn't work, see here: https://stackoverflow.com/a/4533102/4323

Community
  • 1
  • 1
John Zwinck
  • 207,363
  • 31
  • 261
  • 371
  • So did as you suggested and got rid of the while loop and changed how I check the state of the file to match your code above. It didn't throw an exception this time. It did, however, only read in one account of the three. Which is why I had the while loop so that it would run until it hit eof. Is there something else I'm missing? – Jason Carrick Sep 28 '15 at 02:04
  • What are you doing when input fails? You need a while loop still--try making it be `while(ifile)` instead. This will check if the input file has had an error of any kind yet. – John Zwinck Sep 28 '15 at 03:14
  • Okay, I tried that. It spits out an error when reading the account number which is the very first thing. I also, just for kicks, tried a for loop that ran three times and it worked perfectly. I do want it to be able to handle any number of accounts though. I just can't figure out why it doesn't like the while loop. – Jason Carrick Sep 28 '15 at 03:26
  • Update: I added a counter to check which loop through was throwing the exception. I found out that it is looping through all of the information as it should and then trying to go one more time, and throws an exception because there is no data there. Can you think of why it would do this? if I have while(!file.eof()) shouldn't it stop once the eof flag is set? – Jason Carrick Sep 28 '15 at 04:38
  • No! As I told you in my answer, `while(eof)` is not going to work. See the link in my answer for why. – John Zwinck Sep 28 '15 at 11:23
  • Sorry for not getting back sooner. I ended up doing a while(file.good()) and then an if(eof) and that worked. My problem was that it was trying to read in one extra line and throwing an exception. I ignored that last line and my program worked perfectly. Thanks for your help John. – Jason Carrick Oct 02 '15 at 19:29