0

Saving the vector to a file works fine. But I'm looking for a simple way to load the saved data back into the vector.

This is a follow up question to two I asked previously.

1) C++ Trouble Inputting Data into Private Vector (invalid use)

2) Outputting Vector of Type Class

What's a simple way to iterate through the file and push_back() each element?

This is the class:

class Account
{
    private:
        string firstName;
        string lastName;
        string accountPass;
        int accountID;
        float accountBalance;

    public:
        static Account createAccount( int, float, string, string, string ); //creates new account
        int getAccountID() const { return accountID; }
        string getPass() const { return accountPass; }
        string getFirstName() const { return firstName; }
        string getLastName() const { return lastName; }
        float getBalance() const { return accountBalance; }
        friend std::ostream& operator << (std::ostream&, const Account&);
        friend class BankingSystem;

}; //end of class Account


Account Account::createAccount( int ID, float balance, string pass, string first, string last )
{    
    Account a;
    a.accountID = ID;
    a.accountPass = pass;
    a.firstName = first;
    a.lastName = last;
    a.accountBalance = balance;

    return a;

}

std::ostream & operator << (std::ostream & os, const Account & acc)
{
    os << setw(6) << acc.getAccountID();
    os << setw(4) << acc.getPass();
    os << setw(9) << acc.getFirstName();
    os << setw(9) << acc.getLastName();
    os << setw(9) << setprecision(2) << fixed << acc.getBalance();
    return os;
}
Community
  • 1
  • 1
frankV
  • 5,353
  • 8
  • 33
  • 46
  • Swap `ostream` with `istream` and `<<` with `>>`, basically. By the way, what vector are you talking about? I don't see it anywhere. – David Aug 11 '12 at 02:33
  • its a private member to another class – frankV Aug 11 '12 at 02:37
  • Do I replace `os` with `is` ? – frankV Aug 11 '12 at 02:39
  • The name of the variable? Yes, but... come on man, don't ask something you can easily figure out. Variable names don't matter, except for readability. – David Aug 11 '12 at 02:41
  • no not the name of the variable. Everything is `os <<`, so do I need to change that to `is >>`? Cause I tried that and it's not working. – frankV Aug 11 '12 at 02:45
  • That is the name of the variable. I think you misunderstood though (or rather I assumed you know more than you do) - you shouldn't be replacing your `operator<<`, you should be writing a new `operator>>`. `<<` is writing, `>>` is reading. – David Aug 11 '12 at 02:48
  • I wrote a new one `std::istream & operator >> ( std::istream & is, const Account & acc )` but using `is >> acc.getAccountID();` throws a "invalid operands to binary expression" error. – frankV Aug 11 '12 at 02:53
  • Start simpler. You need to understand the basic elements of the language first to pull this off. That said, you're close - but I'm done helping. – David Aug 11 '12 at 02:56
  • 1
    In your signature above, change Account to a non-const parameter; you can't input into it if it's const. – Tony Delroy Aug 11 '12 at 04:44

3 Answers3

1

If Accounts are the only thing written in your file you can read them all into your vector (or any push_back-able container) with this 1-liner:

std::copy(std::istream_iterator<Account>(file), std::istream_iterator<Account>(), std::back_inserter(vec));

You'll also need an operator>> analogous to the operator<< you already have.

David
  • 27,652
  • 18
  • 89
  • 138
0

Found the answer in this Question Using vector of user defined class type objects

for me it was solved by using:

while(!inBankSysFile.eof()) 
{
    Account a;
    inBankSysFile >> a.accountID;
    inBankSysFile >> a.accountPass;
    inBankSysFile >> a.firstName;
    inBankSysFile >> a.lastName;
    inBankSysFile >> a.accountBalance;
    accounts_.push_back(a);

}
Community
  • 1
  • 1
frankV
  • 5,353
  • 8
  • 33
  • 46
  • 1
    That answer is broken... eof() if set after an attempt to input fails due to encountering end of file. It's almost always wrong to have a while loop test for eof() (unless it happens to have already inputted some elements above the loop). Pursue operator>> and then use while (somefile >> a) accounts.push_back(a). – Tony Delroy Aug 11 '12 at 04:43
  • 1
    Yeah, second that. The mistake you had earlier, which I'm not sure you ever corrected, was that you had `istream& operator>>(istream& is, const Account& acc)` but it should be `istream& operator>>(istream& is, Account& acc)`. Const measn you don't want to change that variable inside the function, that's true of writing, but obviously not true of reading where the whole point is to change the variable. Once you've got operator>> right you can just put the code above into operator>> and then write `while (inBankSysFile >> a) accounts_.push_back(a);`. This also corrects the end of file mistake. – jahhaj Aug 11 '12 at 11:56
0

If you don't have any dynamic memory, you can read and write it to binary pretty easily using ifstream::read and ofstream::write and vector::data. Here's an example:

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

class Time
{
public:
Time(): hh(0),mm(0),ss(0) {}
Time(int h,int m,int s):hh(h),mm(m),ss(s) {}
int hh,mm,ss;
};

int main()
{
    Time time1(11,22,33);
    Time time2(44,55,66);

    vector<Time> timeList;
    timeList.push_back(time1);
    timeList.push_back(time2);

    vector<Time> timeList2;
    timeList2.resize(2,Time());

    ofstream fout;
    fout.open("test.txt");
    if(fout.is_open())
    {
        // vector.data returns a pointer to the beginning of its stored data
        // 1st param: the location to read data from
        // 2nd param: the amount of bytes to write to the file
        fout.write((const char*)timeList.data(),sizeof(Time)*timeList.size());

        fout.close();
    }

    ifstream fin;
    fin.open("test.txt");
    if(fin.is_open())
    {
        // 1st param: the location to write data to
        // 2nd param: the amount of bytes to read from the file
        // NOTE: make sure you've sized the vector appropriately before writing to it.
        fin.read((char*)timeList2.data(),sizeof(Time)*timeList2.size());

        for(int i=0;i<timeList2.size();++i) {
            cout << timeList2[i].hh << ":" << timeList2[i].mm << ":" << timeList2[i].ss << "\n";
        }

        fin.close();
    }


    return 0;
}

NOTE: Reading/writing objects that use dynamic memory (including objects containing classes that contain dynamic memory, such as std::string), will require additional processing logic to handle reading and writing that data.

NOTE: Beware of variances in structural alignment padding when using the sizes of any objects.

derpface
  • 1,611
  • 1
  • 10
  • 20