I\'m trying to complete the C++ exercise below. The UML and sample output will b
ID: 3695973 • Letter: I
Question
I'm trying to complete the C++ exercise below. The UML and sample output will be provided in the question, while the sample file's contents will be a comment below.
Based on the following UML diagram, implement the three classes, Account, Checking, and
Savings. Then implement a main program that reads commands from bank2.txt and carries out
the commands using objects of these classes.
Explanation / Answer
main.cpp
#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
#include "Account.h"
#include"Checking.h"
#include"Savings.h"
using namespace std;
//Function prototypes.
void accountCreator(Account * p_accounts[], string p_command, int p_index, double p_initialBalance, double p_minBalance, double p_modifier);
void accountDeposit(Account *p_accounts[], int p_index, double p_amount = 0);
void accountWithdraw(Account *p_accounts[], int p_index, double p_amount = 0);
void accountBalance(Account *p_accounts[], int p_index);
void accountEndOfMonth(Account *p_accounts[]);
void accountReport(Account *p_accounts[]);
void arrayCountCheck(int p_index, string p_command);
int main()
{
//Declare variables.
ifstream bankText;
Account * accounts[9];
string command, junk;
int arrayIndex = 0;
double amount = 0, minBalance = 0, modifier = 0;
//Set precision for the entire program
cout << fixed << setprecision(2);
//Open File
bankText.open("bank2.txt");
if (bankText.is_open())
{
cout << "File is Opened." << endl;
while (bankText >> command)
{
//Exception handling for the commands.
try
{
//Goes through the options for the command string. Still upset that C++ does not allow switches for strings :/
if (command == "Savings" || command == "Checking")
{
try
{
bankText >> arrayIndex >> amount >> minBalance >> modifier;
arrayCountCheck(arrayIndex, command);
accountCreator(accounts, command, arrayIndex, amount, minBalance, modifier);
}
catch (char *arrayMsg)
{
if (bankText.peek() != ' ')
getline(bankText, junk);
cout << arrayMsg << arrayIndex << endl;
continue;
}
}
//All statements below have exception handling for the given array index.
else if (command == "Deposit")
{
try
{
bankText >> arrayIndex >> amount;
arrayCountCheck(arrayIndex, command);
accountDeposit(accounts, arrayIndex, amount);
}
catch (char *arrayMsg)
{
if (bankText.peek() != ' ')
getline(bankText, junk);
cout << arrayMsg << arrayIndex << endl;
continue;
}
}
else if (command == "Withdraw")
{
try
{
bankText >> arrayIndex >> amount;
arrayCountCheck(arrayIndex, command);
accountWithdraw(accounts, arrayIndex, amount);
}
catch (char *arrayMsg)
{
if (bankText.peek() != ' ')
getline(bankText, junk);
cout << arrayMsg << arrayIndex << endl;
continue;
}
}
else if (command == "Balance")
{
try
{
bankText >> arrayIndex;
arrayCountCheck(arrayIndex, command);
accountBalance(accounts, arrayIndex);
}
catch (char *arrayMsg)
{
if (bankText.peek() != ' ')
getline(bankText, junk);
cout << arrayMsg << arrayIndex << endl;
continue;
}
}
else if (command == "Close")
{
accountEndOfMonth(accounts);
}
else if (command == "Report")
{
accountReport(accounts);
}
else
{
throw "Unrecognized command - ";
}
}
catch (char *commandMsg)
{
if (bankText.peek() != ' ')
getline(bankText, junk);
cout << commandMsg << command << endl;
continue;
}
}
}
else
{
cout << "File not found" << endl;
exit(0);
}
if (bankText.eof())
{
bankText.close();
cout << "File closed" << endl;
}
//Keeps the program open after execution.
cin.get();
return 0;
}
void accountCreator(Account * p_accounts[], string p_command, int p_index, double p_initialBalance, double p_minBalance, double p_modifier)
{
//Declare variables.
Account * anAccount = nullptr;
//Set the Account pointer to equal what's passed into the function.
if (p_command == "Checking")
anAccount = new Checking(p_index, p_initialBalance, p_minBalance, p_modifier);
if (p_command == "Savings")
anAccount = new Savings(p_index, p_initialBalance, p_minBalance, p_modifier);
//Assigns the created account to the account array.
p_accounts[p_index - 1] = anAccount;
//Displays conformation message.
cout << p_command << " account number " << anAccount->getId() << " created ";
cout << "with an initial balance of $" << anAccount->getBalance() << endl;
}
//Function to deposit money into any given account.
void accountDeposit(Account *p_accounts[], int p_index, double p_amount)
{
p_accounts[p_index - 1]->deposit(p_amount);
cout << "Deposited $" << p_amount
<< " into account #" << p_accounts[p_index - 1]->getId() << endl
<< "current balance is $" << p_accounts[p_index - 1]->getBalance() << endl;
}
//Function to withdraw money from any given account.
void accountWithdraw(Account *p_accounts[], int p_index, double p_amount)
{
p_accounts[p_index - 1]->withdraw(p_amount);
cout << "Withdrew $" << p_amount
<< " from account #" << p_accounts[p_index - 1]->getId() << endl
<< "current balance is $" << p_accounts[p_index - 1]->getBalance() << endl;
}
//Function to check the balance for any given account.
void accountBalance(Account *p_accounts[], int p_index)
{
cout << "Current balance in account #" << p_accounts[p_index - 1]->getId()
<< " is $" << p_accounts[p_index - 1]->getBalance() << endl;
}
//Function to check if the given account exists or not.
void arrayCountCheck(int p_index, string p_command)
{
//Declare variables.
int objectCount = Account::getAccountCount();
//Ignores the command and then checks the validity of the account number.
if (p_command == "Deposit" || p_command == "Withdraw" || p_command == "Balance")
{
if (p_index > objectCount || p_index < 1 || p_index > 9)
throw "Invalid Account Number - ";
}
//Checks to see if the account is in range.
else if (p_command == "Savings" || p_command == "Checking")
{
if (p_index < 1 || p_index > 9)
throw "Only Accounts 1-9 can be created. Invalid Account Number - ";
}
else {
return;
}
}
void accountEndOfMonth(Account *p_accounts[])
{
///Declare variables.
int objectCount = Account::getAccountCount();
for (auto i = 0; i < objectCount; i++)
{
p_accounts[i]->closeMonth();
}
cout << "End of month processing complete. ";
}
void accountReport(Account *p_accounts[])
{
///Declare variables.
int objectCount = Account::getAccountCount();
for (auto i = 0; i < objectCount; i++)
{
p_accounts[i]->accountString();
}
}
Account.cpp
#include "Account.h"
#include<string>
using namespace std;
//Static variable to count how many accounts are active at any one time.
Account::Account()
{
id = 0;
balance = 0;
accountCount++;
}
Account::Account(int newID, double initialBalance)
{
id = newID;
balance = initialBalance;
accountCount++;
}
//Definition for the static accountCount variable.
int Account::accountCount = 0;
void Account::setId(int newID)
{
id = newID;
}
int Account::getId() const
{
return id;
}
void Account::setBalance(double newBalance)
{
balance = newBalance;
}
double Account::getBalance() const
{
return balance;
}
void Account::withdraw(double amount)
{
balance -= amount;
}
void Account::deposit(double amount)
{
balance += amount;
}
Account.h
#include<string>
using namespace std;
//Abstract Base Class for all bank accounts.
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
protected:
static int accountCount;
int id;
double balance;
public:
Account();
Account(int newID, double initialBalance);
static int getAccountCount() { return accountCount; };
void setId(int newID);
int getId() const;
void setBalance(double newBalance);
double getBalance() const;
void withdraw(double amount);
void deposit(double amount);
//Pure virtual functions. Must be defined by derived class.
virtual void accountString() = 0;
virtual void closeMonth() = 0;
};
#endif
Checking.h
#include "Account.h"
#include<string>
using namespace std;
#ifndef CHECKING_H
#define CHECKING_H
//Checking is a sub-class of the Account class.
class Checking : public Account{
private:
double minBalance;
double monthlyFee;
public:
//Constructors.
Checking();
Checking(int p_newId, double p_initialBalance, double p_minBalance, double p_monthlyFee);
//Mutators
void setMinBalance(double p_minBalance)
{ minBalance = p_minBalance; }
void setMonthlyFee(double p_monthlyFee)
{ monthlyFee = p_monthlyFee; }
//Accessors
double getMinBalance() const
{ return minBalance; }
double getMonthlyFee() const
{ return monthlyFee; }
//Overriden virtual functions defined in Checking.cpp
virtual void accountString();
virtual void closeMonth();
};
#endif
Savings.cpp
#include"Savings.h"
#include<string>
#include<iostream>
using namespace std;
Savings::Savings()
{
minBalance = 0;
interestRate = 0;
}
Savings::Savings(int p_newId, double p_initialBalance, double p_minBalance, double p_interestRate) : Account(p_newId, p_initialBalance)
{
id = p_newId;
balance = p_initialBalance;
minBalance = p_minBalance;
interestRate = p_interestRate;
}
void Savings::accountString()
{
cout << "Savings Account #" << id
<< " has a balance of $" << balance << endl;
}
void Savings::closeMonth()
{
if (balance > minBalance)
balance += balance * ((interestRate/100)/12);
}
Savings.h
#include "Account.h"
#include<string>
using namespace std;
#ifndef SAVINGS_H
#define SAVINGS_H
//Savings is a sub-class of the Account class.
class Savings : public Account {
private:
double minBalance;
//Interest rate should be annual.
double interestRate;
public:
//Constructors.
Savings();
Savings(int p_newId, double p_initialBalance, double p_minBalance, double p_interestRate);
//Mutators
void setMinBalance(double p_minBalance)
{
minBalance = p_minBalance;
}
void setInterestRate(double p_interestRate)
{
interestRate = p_interestRate;
}
//Accessors
double getMinBalance() const
{
return minBalance;
}
double getInterestRate() const
{
return interestRate;
}
//Overriden virtual functions defined in Savings.cpp
virtual void accountString();
virtual void closeMonth();
};
#endif
Checking.cpp
bank2.txt
Close
Report
sample output
File is Opened.
End of month processing complete.
File closed