This function is supposed to take care of updating the file after calling the respective functions for depositing or withdrawing from a user account. But it fails to do just that. I've checked as much as I can and all the other functions seem to be doing their jobs properly. I've traced it down to the specific lines where the program seems to fail.
int pos = (-1) * static_cast<int>(sizeof(ac));
File.seekp(pos, ios::cur);
//File.write((char *)&ac, sizeof(BankAccount));
File.write(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
Yes, these are two versions of the line because I don't fully understand how either of them work. (First version is mine, second line is from a sample program we were given)
void makeDepositOrWithdraw(int option)
{
int num;
cout << "\nEnter account number: ";
cin >> num;
int amt;
bool found = false;
BankAccount ac;
SavingsAccount save;
fstream File;
File.open("Account.dat", ios::binary | ios::in | ios::out);
if (!File)
{
cout << "Cannot retrieve database right now. Try again later";
return;
}
while (!File.eof() && found == false)
{
File.read(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
if (ac.getAccountNo() == num)
{
ac.displayAcc();
if (option == 1)
save.makeDeposit();
if (option == 2)
save.makeWithdrawal();
int pos = (-1) * static_cast<int>(sizeof(ac));
File.seekp(pos, ios::cur);
//File.write((char *)&ac, sizeof(BankAccount));
File.write(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
cout << "__________________________________"
<< "\nRecord updated ";
found = true;
}
}
File.close();
if (!found)
cout << "Record not found";
}
EDIT: I'm sorry for being really bad at explaining this. The initial creation of a new account works. But trying to make additional deposit doesn't run into any error, the variables are being properly updated all the way up to the main BankAccount
class. But nothing gets updated in the already existing account in the .dat file. Program still executes without any error.
I'm assuming if I understand the problem with the depositing part, I'll be able to solve the problem with withdrawing too, as both are handled in the same function.
#include <iostream>
#include <fstream>
#include <cctype>
#include <iomanip>
using namespace std;
class BankAccount
{
private:
float Balance, ServChargePerMonth, AnnualInterestRt, DepoAmt, WithdrwAmt;
int NoOfDepositPerMonth, NoOfWithdrawalPerMonth, AccountNo;
char Name[50], type;
public:
virtual void makeDeposit()
{
Balance += DepoAmt; //adding argument to acc bal
NoOfDepositPerMonth++; //incrementing noOfDeposit
};
virtual void makeWithdrawal()
{
Balance -= WithdrwAmt; //subtracting argument from acc bal
NoOfWithdrawalPerMonth++; //incrementing noOfWithdrawal
};
virtual void createAcc()
{
cout << "\nEnter your account number: ";
cin >> AccountNo;
cout << "\nEnter your full name: ";
cin.ignore();
cin.getline(Name, 50);
cout << "\nEnter the type of Account (C for current or S for savings): ";
cin >> type;
type = toupper(type);
cout << "\nEnter initial deposit amount: ";
cin >> Balance;
cout << "___________________________________________________________"
<< "\n\nAccount created." << endl;
};
void displayAcc()
{
cout << "\nAccount number: " << AccountNo
<< "\nAccount holder name: " << Name
<< "\nType of account: " << type
<< "\nAccount balance: $" << Balance
<< "\nTotal number of deposits: " << NoOfDepositPerMonth
<< "\nTotal number of withdrawals: " << NoOfWithdrawalPerMonth
<< "\nService Charge: $" << ServChargePerMonth << endl;
};
//getters
float getBalance() { return Balance; }
float getDepoAmt() { return DepoAmt; }
int getNoOfDeposit() { return NoOfDepositPerMonth; }
int getNoOfWithdraw() { return NoOfWithdrawalPerMonth; }
int getAccountNo() { return AccountNo; }
//setters
void setServChargePerMonth(float servCharge) //note: increasing, not setting
{
ServChargePerMonth += servCharge;
}
void setWithdrawAmt(float Amount)
{
WithdrwAmt = Amount;
}
void setBalance(float blnce)
{
Balance = blnce;
}
void setDepoAmt(float Amount)
{
DepoAmt = Amount;
}
};
class CheckingAccount : public BankAccount
{
public:
void makeWithdrawal(float WithdrwAmt)
{
if ((BankAccount::getBalance() - WithdrwAmt) < 0) //note: float doens't go below 0
setBalance(getBalance() - 15.0); //deducting $15
else
BankAccount::setWithdrawAmt(WithdrwAmt);
BankAccount::makeWithdrawal();
}
};
class SavingsAccount : public BankAccount
{
private:
bool statusVar;
bool status()
{
if (getBalance() < 25.0)
statusVar = false;
else
statusVar = true;
return statusVar;
}
public:
//setter
void setStatus(bool statusVar)
{
statusVar = status();
}
bool getStatus() { return statusVar; }
void makeWithdrawal()
{
if (status()) //check if active
{
cout << "Enter the amount you would like to withdraw today: ";
float WithdrwAmt;
cin >> WithdrwAmt;
CheckingAccount temp;
temp.makeWithdrawal(WithdrwAmt); //perform the reqd. check, as well as call the base ver.
}
else
{
cout << "Your account has deactivated. Please increase "
<< "your balance to reactivate your account.";
}
}
void makeDeposit()
{
cout << "Enter the amount you would like to deposit today: ";
float temp;
cin >> temp;
setDepoAmt(temp); //setting value for amt of deposit
//check previous balance
if (!status()) //if <$25,
{ //reactivate the acc. if depoAmt brings bal to $25
if ((getBalance() + getDepoAmt()) >= 25.0)
setStatus(true);
}
//check
BankAccount::makeDeposit(); //and then call the base ver.
}
};
void createAcc()
{
BankAccount ac;
ofstream writeFile;
writeFile.open("Account.dat", ios::binary | ios::app);
ac.createAcc();
writeFile.write(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
writeFile.close();
}
void makeDepositOrWithdraw(int option)
{
int num;
cout << "\nEnter account number: ";
cin >> num;
int amt;
bool found = false;
BankAccount ac;
SavingsAccount save;
fstream File;
File.open("Account.dat", ios::binary | ios::in | ios::out);
if (!File)
{
cout << "Cannot retrieve database right now. Try again later";
return;
}
while (!File.eof() && found == false)
{
File.read(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
if (ac.getAccountNo() == num)
{
ac.displayAcc();
if (option == 1)
save.makeDeposit();
if (option == 2)
save.makeWithdrawal();
int pos = (-1) * static_cast<int>(sizeof(ac));
File.seekp(pos, ios::cur);
//File.write((char *)&ac, sizeof(BankAccount));
File.write(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
cout << "__________________________________"
<< "\nRecord updated ";
found = true;
}
}
File.close();
if (!found)
cout << "Record not found";
}
void display()
{
int num;
cout << "\nEnter account number: ";
cin >> num;
bool flag = false;
BankAccount ac;
ifstream inFile;
inFile.open("Account.dat", ios::binary);
if (!inFile)
{
cout << "Cannot retrieve database right now. Try again later";
return;
}
cout << "\nBALANCE DETAILS\n";
while (inFile.read(reinterpret_cast<char *>(&ac), sizeof(BankAccount)))
{
if (ac.getAccountNo() == num)
{
ac.displayAcc();
flag = true;
}
}
inFile.close();
if (!flag)
cout << "\nAccount number does not exist";
}
void deleteAcc()
{
int num;
cout << "\nEnter account number: ";
cin >> num;
BankAccount ac;
ifstream inFile;
ofstream outFile;
inFile.open("Account.dat", ios::binary);
if (!inFile)
{
cout << "Cannot retrieve database right now. Try again later";
return;
}
outFile.open("temp.dat", ios::binary);
inFile.seekg(0, ios::beg);
while (inFile.read(reinterpret_cast<char *>(&ac), sizeof(BankAccount)))
{
if (ac.getAccountNo() != num)
{
outFile.write(reinterpret_cast<char *>(&ac), sizeof(BankAccount));
}
}
inFile.close();
outFile.close();
remove("Account.dat");
rename("temp.dat", "Account.dat");
cout << "__________________________________________"
<< "Your account has been closed.";
}
int main()
{
char opt;
int temp;
start:
do
{
system("clear");
cout << "\n1. Create new account"
<< "\n2. Make a deposit"
<< "\n3. Make a withdrawal"
<< "\n4. Balance enquiry"
<< "\n5. Close existing account"
<< "\n6. Exit"
<< "\n\nPlease select your option(1-6)" << endl;
cin >> opt;
system("clear");
switch (opt)
{
case '1':
createAcc();
break;
case '2':
makeDepositOrWithdraw(1);
break;
case '3':
makeDepositOrWithdraw(2);
break;
case '4':
display();
break;
case '5':
deleteAcc();
break;
case '6':
cout << "Thank you for banking with us" << endl;
break;
default:
cout << "\a" << endl;
goto start;
break;
}
cin.ignore();
cin.get();
} while (opt != '6');
}