Neeraj Athalye
Neeraj Athalye

Reputation: 547

Reading objects from file in c++

I have created a class that stores the details of a user like account number, name balance etc. I am writing an object of this class to a file. When i read from the file i am not getting a proper output. If a have entered 2 people's details then i am getting the second person's details twice. Here's the code.

#include <fstream>
#include <string>
#include <ctime>
# include <conio.h>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
class User
{
    int acctype[2] = {0,0}; // acctype[0] = savings account & acctype[1] = current account
    string name = "NULL";
    string address = "NULL";
    string dob = "NULL";
    long int sbal = 0;
    long int cbal = 0;
    long int accno = 0;
    string password;
    int aod = 0; // account opening date
    int aom = 0; // account opening month
    int aoy = 0; // account opening year
    public:
        void input()
        {
            system("cls");
            cin.clear();
            char type,ch;
            cout << "Enter you name\n";
            getline(cin,name);
            cout << "Enter your address\n";
            getline(cin,address);
            cout << "Enter your date of birth(dd/mm/yyyy)\n";
            getline(cin,dob);
            cout << "Enter your account type(s = savings, c = current)\n";
            cin >> type;
            if(type == 's')
            {
                acctype[0] = 1;
                cout << "Enter your savings account balance\n";
                cin >> sbal;
            }
            else if(type == 'c')
            {
                acctype[1] = 1;
                cout << "Enter your current account balance\n";
                cin >> cbal;
            }
            pass:
            cout << "\nChoose a password(8-16 characters)\n";
            // to display * in place of the entered character for the password
            ch = _getch();
            while(ch != 13)// to check for return input
            {
                password.push_back(ch);
                cout << "*";
                ch = _getch();
            }
            if(password.size() < 8 || password.size() > 16)
                goto pass;
            //store the account opening date
            time_t now = time(0);
            tm *ltm = localtime(&now);
            aod = ltm->tm_mday;
            aom = 1 + ltm->tm_mon;
            aoy = 1900 + ltm->tm_year;
            cin.ignore(10000,'\n');

        }
        void datawrite()
        {
            //store the data in the file
            ofstream fout;
            fout.open("database.txt", ios_base::app);
            if(!fout.is_open())
            {
                cout << "\nCannot open file! Aborting";
                exit(0);
            }
            fout.write((char*) this, sizeof(this));
            fout.close();
        }
        int dataread()
        {
            ifstream fin;
            fin.open("database.txt", ios_base::in);
            if(!fin.is_open())
            {
                cout << "\nCannot open file! Aborting";
                exit(0);
            }
            fin.seekg(0);
            fin.read((char*)this, sizeof(this));
            while(fin)
            {
            //system("cls");
                fin.read((char*)this, sizeof(this));
                this->accsummary();
            }
            fin.close();
        }
        void accsummary()
        {
            //system("cls");
            cout << "\n\t\tACCOUNT SUMMARY\n";
            cout << "\nName : " << name;
            cout << "\nAccount NUmber : " << accno;
            cout << "\nDate of birth : " << dob;
            cout << "\nAddress : " << address;
            cout << "\nAccount opening date : " << aod << "/" << aom << "/" << aoy;
            if(acctype[0] == 1)
                cout << "\nSavings Account Balance : " << sbal;
            if(acctype[1] == 1)
                cout << "\nCurrent Account Balance : " << cbal;

        }
};

int main()
{
    User u;
    u.input();
    u.datawrite();
    u.dataread();

}

Upvotes: 0

Views: 73

Answers (1)

Bo Persson
Bo Persson

Reputation: 92361

This is a variation of Why is iostream::eof inside a loop condition considered wrong?, but with a slightly different test

        while(fin)
        {
            fin.read((char*)this, sizeof(this));
            this->accsummary();
        }

You don't test if the read is successful before adding the data to your summary. That will make the last+1 round in the loop add the last data a second time.

The while(fin) doesn't terminates the loop until you have had one unsuccessful read. That's one round too late.

Upvotes: 1

Related Questions