Reputation: 547
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
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