How to use 'fout' with inheritance - c++

I'm taking a class in C++ and I've run into a problem. We have to create a list of bankaccounts that each have their own savings and checking account. I've come quite far, but now I have to use "ofstream& fout" to print the checking and savings of an imaginairy account.
My header file of "Account.h" looks like this (I think it's correct):
#include <iostream>
#include <cmath>
#include <fstream>
#ifndef ACCOUNT_H
#define ACCOUNT_H
using namespace std;
class Account{
protected:
string number;
double balance;
public:
Account(){}
Account(string nr, double bl);
void deposit(double am);
string get_number();
double get_balance();
double withdraw(double am);
bool equals(Account other);
virtual void print();
void println();
void println(string s);
virtual void println(ofstream& fout);
virtual void read(ifstream& fin);
};
#endif
My definition file is where it all goes horribly wrong with the fstream part:
#include "Account.h"
Account::Account(string nr, double bl){
if (bl >= 0){
number = nr;
balance = bl;
}
else{
number = "incorrect";
}
}
void Account::deposit(double am){
if (am >= 0){
balance = balance + am;
}
}
string Account::get_number(){
return number;
}
double Account::get_balance(){
return balance;
}
double Account::withdraw(double am){
if (0 <= am && am <= get_balance()){
balance = balance - am;
return am;
}
else{
return 0;
}
}
bool Account::equals(Account other){
if (number == other.get_number()){
return true;
}
return false;
}
void Account::print(){
cout << "<Account(" << number << ",";
cout << balance << ")>" ;
}
void Account::println(){
print();
cout << endl;
}
void Account::println(string s){
cout << s;
println();
}
void Account::println(ofstream& fout){
fout << number << ",";
fout << balance;
fout << endl;
}
void Account::read(ifstream& fin){
fin >> number;
}
There is something wrong with the declaration of void Account::println(ofstream& fout). It gives me the output
<Account(number,balance,0)>
instead of
<Account(number,balance)>
Why does this happen? I have many more problems with the printing of the savings and checking numbers, but i feel if I understand why this is happening I can solve those. Thank you to anyone who wants to help me.

Account::println(ofstream&) will print "", but since the balance is a double, it prints with a decimal place:
if balance == 0.0, it will be printed as eiter 0.0 or 0,0, depending on your locale.
Either way, you have way too many print methods, and I think the solution should be implemented through an output operator:
Header:
class Account {
// ....
// no print methods defined
};
std::ostream& operator <<(std::ostream& out, const Account& a);
Source:
std::ostream& operator <<(std::ostream& out, const Account& a)
{
return out << "";
}
Client code:
#include <iostream> // console
#include <fstream> // file
Account a;
// print to console
std::cout << a << std::endl;
// print to file
std::ofstream fout("./account.txt");
fout << a << std::endl;

Related

base class initialization error, no matching constructor

First and foremost I'd like to apologize for the magnitude of code I'm dumping. I'm writing some code that allows the user to withdraw and deposit money into an account, the code also calculates the interest rate of the account and the number of withdrawals and deposits etc. I get on error when I try to call the base class functions to the child functions, "no matching constructor." I can't seem to find a problem with the constructors on my own. Can anyone help?
Account.cpp
#include "Account.h"
#include <iostream>
#include <iomanip>
using namespace std;
//overloaded constructor
Account::Account(double accBal, double annIntRate){
accBal = accBal;
annIntRate = annIntRate;
};
//deposit base class function
int Account::deposit(double accBal, int numWithdrawal)
{
cout << "Enter deposit: "<< endl;
double depos;
cin >> depos;
accBal += depos;
numDepos ++;
return accBal;
}
//withdraw base class function
void Account::withdraw(double accBal, int numWithdrawal)
{
double amount;
cin >> amount;
accBal -= amount;
numWithdrawal ++;
}
//interest rate calculation
void Account::calcInt(double accBal, double annIntRate)
{
double monthlyIntRate = annIntRate/2;
double monthlyInt = accBal * monthlyIntRate;
accBal += monthlyInt;
}
Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
//variable declarations
private:
int accNum;
double accBal;
int numWithdrawal;
int numDepos;
double annIntRate;
double monthServCharg;
public:
Account(double, double); //overloaded constructor
virtual int deposit(double, int); //base class deposit declaration
virtual void withdraw(double, int); //base class withdraw declaration
virtual void calcInt(double, double); //updates interest rate
void setAccNum(int); //setter
int getAccNum(){return accNum;} //getter
void setAccBal(double);//setter
double getAccBal(){return accBal;}//getter
void setNumWithdrawal(int);//setter
int getNumWithdrawal(){return numWithdrawal;}//getter
void setNumDep(int);//setter
int getNumDep(){return numDepos;}//getter
void setAnnIntRate(double);//setter
double getAnnIntRate(){return annIntRate;}//getter
void setMonthServCharg(double); //setter
double getMonthServCharg(){return monthServCharg;}//getter
};
#endif
SavingsAccount.cpp
#include "SavingsAcc.h"
#include "Account.h"
#include <iostream>
using namespace std;
//status constructor
SavingsAccount::SavingsAccount(bool status)
{
status = false;
}
//deposit money function
void SavingsAccount::deposit(bool status, double accBal, int numDepos)
{
Account obj;
obj.deposit(accBal); //PROBLEM
if (accBal > 25.00)
status = true;
else
status = false;
}
//withdraw money child function, updates account status, service charges, interest rate etc
void SavingsAccount::withdraw(double accBal, int numWithdrawal, double annIntRate, double monthServCharg)
{
double amount;
if (accBal <= 25.00)
cout << "Balance too low, withdrawals cannot be made at this time"<<endl;
else
{
do
{
Account obj;
obj.withdraw(numWithdrawal); // PROBLEM
if (numWithdrawal > 4)
monthServCharg += 1;
if (accBal < 25.00)
{annIntRate += 0.01;}
}
while (amount > accBal);
cout << "Insufficient funds!";
}
}
//outputs the report of account
void SavingsAccount::accountReport(int accNum, bool status, int numWithdrawal, int numDepos, double monthServeCharg, double accBal)
{
cout << "====ACCOUNT STATUS===="<<endl;
cout << "Account number: "<< accNum <<endl;
if (status == true) //status
cout << "Satus: Active" << endl;
else
cout <<"Status: Inactive" << endl;
cout << "Total deposits: "<< numDepos << endl;
cout << "Total withdrawals" << numWithdrawal << endl;
cout << "Service charges: "<< monthServeCharg << endl;
cout << "Balance: "<<accBal<<endl;
}
SavingsAccount.h
#ifndef SAVINGSACC_H
#define SAVINGSACC_H
#include <iostream>
class SavingsAccount: public Account
{
private:
bool status; //status variable
public:
SavingsAccount(bool); // constuctor
void deposit(bool, double, int); // deposit function
void withdraw(double, int, double, double); //withdraw function
void accountReport(int, bool, int, int, double, double ); // full report of account
};
#endif
The constructor
Account(double, double); //overloaded constructor
is actually not overloading constructor but invalidating the default constructor.
To use this constructor, passing values for the arguments when constructing SavingsAccount like
SavingsAccount::SavingsAccount(bool status) : Account(42, 334)
{
status = false;
}
is required.
Also the line
obj.deposit(accBal); //PROBLEM
is causing error because the class Account doesn't have function deposit that takes only one argument. You should delete the line or pass right number of arguments to resolve this error.

Comparing stacks

I have a project to compare the contents of two stacks and I am having issues with this function. I believe I have the rest of the program done correctly. I am getting errors on B.myCharacters.empty() (Expression must have class type) and B==B.myCharacters (no operator "==" matched these operands).
bool CharStack::IsEqual(CharStack & B)
{
if (B.empty())
{
cout << "Stack is empty" << endl;
return false;
}
else if (B.myCharacters.empty())
{
cout << "Stack is empty" << endl;
return false;
}
else if (B == B.myCharacters)
return true;
}
Any help would be greatly appreciated.
Here is the header and driver. They were provided by the teacher for this project and I am not allowed to change them, even if there is a better way to do it.
#include <iostream>
#include <string>
using namespace std;
const int STACK_CAPACITY = 128;
typedef char StackElement;
class CharStack
{
private:
char myCharacters[STACK_CAPACITY]; // STL stack of chars.
int myTop;
public:
CharStack();
bool empty();
void push(const StackElement & value);
StackElement top() const;
void pop();
void StringToStack(const string & inStr);
friend ostream & operator <<(ostream & out, const CharStack & CS);
CharStack Reverse();
bool IsEqual(CharStack & B);
};
Driver
#include <string>
#include <cassert>
#include "Header.h"
using namespace std;
//introduces namespace std
int main(void)
{
ifstream in;
string fileName, line[30];
int i = 0;
CharStack N, M, P;
cout << "Enter file name for palindrome check: ";
cin >> fileName;
in.open(fileName.c_str());
assert(in.is_open());
while (!in.eof())
{
getline(in, line[i]);
N.StringToStack(line[i]);
cout << N << endl;
P = N;
M = N.Reverse();
if (P.IsEqual(M))
cout << "This line is a palindrome line" << endl;
else
cout << "This line is not a palindrome line" << endl;
i++;
}
cout << "\nProgram ended normally.\n";
system("pause");
}
Assuming your CharStack internally keeps the characters in a std::string, i.e.
class CharStack
{
std::string myCharacters; // internal data
public:
bool IsEqual(CharStack const&) const;
/* ... */
};
and IsEqual() should return if two stacks are identical, then the implementation is simply
bool CharStack::IsEqual(CharStack const&other) const
{
return myCharacters == other.myCharacters;
}
This compares an empty and a non-empty stack as not equal, but two empty stacks as equal, which arguably is the correct behaviour. If you want two empty stacks to be not equal you can
bool CharStack::IsEqualNonEmpty(CharStack const&other) const
{
return !myCharacters.empty() && myCharacters == other.myCharacters;
}
Note also the various uses of the keyword const.

Different results in Linux than in Windows C++

I've created my code in Microsoft Visual Studio Express 2013 and it compiles and runs fine. I've moved this over to Linux and it gives me a different result for the GPA output. The GPA's are coming as 0 and 6.95281e-310 instead of the 3.9 and 3.5.
Also wondering if there is a difference between the strcmp and strncpy in Linux since I had to add #include <cstring> in my student.h?
Is there something else I should be using instead of strncpy in Linux?
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
Student(const char initId[], double gpa);
bool isLessThanByID(const Student& aStudent) const;
bool isLessThanByGpa(const Student& aStudent) const;
void print()const;
private:
const static int MAX_CHAR = 100;
char id[MAX_CHAR];
double gpa;
};
#endif
student.cpp
#include "student.h"
//implement the required 3 functions here
Student::Student(const char initId[], double gpa) : gpa(gpa)
{
// initialize a newly created student object with the passed in value
strncpy(id, initId, Student::MAX_CHAR - 1);
if (Student::MAX_CHAR > 0)
{
id[Student::MAX_CHAR - 1] = '\0';
}
}
bool Student::isLessThanByID(const Student& aStudent) const
{
// compare the current student object with the passed in one by id.
if (strcmp(id, aStudent.id) > 0)
{
return true;
}
else
{
return false;
}
}
bool Student::isLessThanByGpa(const Student& aStudent) const
{
// compare the current student object with the passed in one by gpa
if (gpa < aStudent.gpa)
{
return true;
}
else
{
return false;
}
}
void Student::print() const
{
cout << id << '\t' << gpa << endl;
}
app.cpp
#include "student.h"
int main()
{
Student s1("G10", 3.9);
Student s2("G20", 3.5);
s1.print();
s2.print();
if(s1.isLessThanByID(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
if(!s1.isLessThanByGpa(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
//system("pause");
return 0;
}
strcmp compares strings http://www.cplusplus.com/reference/cstring/strcmp/
strncpy copies them http://www.cplusplus.com/reference/cstring/strncpy/
There IS a great diff really between them, in Linux and other systems as well.

Initialize member in print() from another function

Not sure where I am at the moment, trying to figure it out. I need to initialize the members in print() const as it is giving me random gibberish. No matter what I try to do, it does not seem to work. Not sure what to even do. Can anyone give me a hand?
*edit: Added in the rest of the code. Forgot it when I submitted the first time.
Student.cpp
#include "student.h"
//implement the required 3 functions here
Student::Student(const char initId[], double gpa)
{
// initialize a newly created student object with the passed in value
}
bool Student::isLessThanByID(const Student& aStudent) const
{
// compare the current student object with the passed in one by id.
if (strcmp(id, aStudent.id) > 0)
{
return true;
}
else
{
return false;
}
}
bool Student::isLessThanByGpa(const Student& aStudent) const
{
// compare the current student object with the passed in one by gpa
if (gpa < aStudent.gpa)
{
return true;
}
else
{
return false;
}
}
void Student::print() const
{
cout << id << '\t' << gpa << endl;
}
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
using namespace std;
class Student
{
public:
Student(const char initId[], double gpa);
bool isLessThanByID(const Student& aStudent) const;
bool isLessThanByGpa(const Student& aStudent) const;
void print()const;
private:
const static int MAX_CHAR = 100;
char id[MAX_CHAR];
double gpa;
};
#endif
app.cpp
#include "student.h"
int main()
{
Student s1("G10", 3.9);
Student s2("G20", 3.5);
s1.print();
s2.print();
if(s1.isLessThanByID(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
if(!s1.isLessThanByGpa(s2))
{
cout << "about right!" << endl;
}
else
{
cout << "uhmm ..." << endl;
}
system("pause");
return 0;
}
There is nothing in that code that sets the values of Student::id and Student::gpa. Your constructor has parameters initId and gpa; you should copy those into your object. Based on the declaration of Student that you provided, something this should be appropriate:
Student::Student(const char initId[], double gpa) : gpa(gpa)
{
strncpy(id, initId, Student::MAX_CHAR-1);
id[Student::MAX_CHAR-1] = '\0';
}

Undefined reference error in c++ dynamic member

hi everyone im new to programming so excuse the noob question...
i tried every method to get through with the undefined refernce error but it keeps throwing that error at me
i tried using pointer "->" and the "::" sign and also the dot "."
what am i supposed to do? why cant it compile?
this is my cpp file:
#include <cstdlib>
#include "account.hpp"
using namespace std;
int Account::getAccountNumber()
{
return accountNumber;
}
double Account::getBalance()
{
return balance;
}
void Account::createAccount(LinkedList<Account>& accountsList, string name, int idNumber)
{
...
case 1:
accountsList.addFront(newAcc); //Where the error occurs.
break;
case 2:
do
{
cout << "\n\tWhich position would you like to insert the\n"
<< "\tnew account into?\n"
<< "\tPosition number: #";
cin >> target;
if (cin.fail())
{
cin.clear();
cin.ignore(20,'\n');
cout << "\n\n\tSorry, wrong input. Please enter a correct position.\n\n";
system("pause");
}
}
while(cin.fail());
accountsList.addMiddle(newAcc, target); //and here
break;
case 3:
accountsList.addEnd(newAcc); //and here
break;
}
cout << "\n\n\tAccount Created Successfully\n\n"
<< accountsList;
system("pause");
}
and here is my .hpp
#ifndef ACCOUNT_HPP_INCLUDED
#define ACCOUNT_HPP_INCLUDED
#include "linkedlist.hpp"
#include "generic.hpp"
class Account : public GenericAccount
{
int accountNumber;
double balance;
public:
Account(string name = "empty", int idNumber = 0, int accountNumber = 0, double balance = 0)
: GenericAccount(name, idNumber), accountNumber(accountNumber), balance(balance) {}
int getAccountNumber();
double getBalance();
void createAccount(LinkedList<Account>&, string, int);
void deposit(LinkedList<Account>&, Account&);
void withdraw(LinkedList<Account>&, Account&);
void displayAccount(LinkedList<Account>&, Account&);
void deleteAccount(LinkedList<Account>&);
friend istream& operator>> (istream& is, Account& x)
{
is >> x.accountNumber;
return is;
}
friend ostream& operator << (ostream& os, Account& c)
{
os << "Account Number= " << c.getAccountNumber() << "\t"
<< "Balance= "<< c.getBalance() << endl;
return os;
}
friend bool operator == (Account& a, Account& target)
{
return (a.getAccountNumber() == target.getAccountNumber());
}
};
#endif // ACCOUNT_HPP_INCLUDED
the full project can be downloaded HERE for refernce
THANK YOU ALL IN ADVANCE!
I think the issue is that there is that the addFront method is not being defined for the account type (in fact any type). See Why can templates only be implemented in the header file? for a much better explanation.
Moving the contents of cpp inline in the .h file should do the trick. Another option is to rename the the .cpp file to a .inl and include it at the bottom of linkedList.hpp