Outputting input and output to both console and file

Below are the instructions for my final course project, I spent a good three/four hours writing the code a few nights ago, but I realized at the end of the instructions it says to output all the code to an output file. I know I can manually write to an output file after each cout (example below), but my professor wants me to use templates to achieve that result.

1
2
cout << "Bank Account" << endl;
outFile << "Bank Account" << endl;


I found some information on the internet on using templates and operator overloading to obtain the desired code. The problem now is that both my stream and input objects successfully output to both console and a file, but the input object doesn't hold the value I set for the variable. For example:

1
2
3
int value = 0; //value set to 0
input >> value; //user sets value to 100
stream << value; //value still set to 0 


The value will still be 0, it doesn't update to the the value that I set.

Maybe a fresh set of eyes would help.

I have listed my header files along with my main cpp file below this post since the max character count is 9000.

This is the information I found on these forums that helped me: (link: http://www.cplusplus.com/forum/general/19489/):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class mstream {
   public:
   ofstream coss;
   mstream(void);
   ~mstream(void);
};

template <class T>
mstream& operator<< (mstream& st, T val) {
   st.coss << val;
   cout << val;
   return st;
};

//Works well with
sout << m << 0.1  << " haha\n";
//- But doesn't work well for
sout << endl;



*****Instructions*****

If you are doing this as a group project, include a summary of what each member established. If both are working on coding what each one has established and which code each person write? At the end submit your documentation (Pseudocode, source code, and input/output).

This program should be designed and written by a team of students. Here are some suggestions:

1. One student may work on a single class.
2. The requirements of the program should be analyzed so each student takes about the same work load.
3. The parameter and return type s of each function and class member function should be decided in advanced.
4. The program will be best implemented as a multi-file program, (header file, main program,..)
5. You need to upload only source code by the due date.

Design a generic class to hold the following information about a bank account:

Balance
Number of deposits this month
Number of withdrawals
Annual Interest Rate
Monthly service charges
The class should have the following member function:

Constructors: Accepts arguments for the balance and annual interest rate.

deposit: a virtual function that accepts an argument for the amount of the deposit. The function should add the argument to the account balance. It should also increment the variable holding the number of deposits.

withdraw: a virtual function that accepts an argument for the amount of the withdrawal. The function should subtract the argument from the account balance. It should also increment the variable holding the number of withdrawals.

calcInt: a virtual function that updates the balance by calculating the monthly interest earned by the account, and adding this interest to the balance. This is performed by the account, and adding this interest to the balance. This is performed by the following formulas:

Monthly Interest = Balance *Monthly Interest Rate
Monthly Interest Rate = (Annual Interest Rate /12)
Balance = Balance + Monthly Interest

monthlyProc: a virtual function that subtracts the monthly service charges from the balance, calls the calcInt function, and sets the variables that hold the number of withdrawals, number of deposits, and monthly service charges to zero.

Next, design a savings account class, derived from the generic account class. The savings account class should have the following additional member:

status (to represent an active or inactive account): If the balance of a saving account falls below $25, it becomes inactive. (The status member could be a flag variable. ) No more withdrawals may be made until the balance is raised above $25, at which time the account becomes active again. The saving account class should have the following member functions:

withdraw: A function that checks to see if the account is inactive before a withdrawal is made. (No withdrawal will be allowed if the account is not active.) A withdrawal is then made by calling the base class version of the function.deposit: A function that checks to see if the account is inactive before a deposit is made. If the account is inactive and deposit brings the balance above $25, the account becomes active again. The deposit is then made by calling the base class version of the function.

monthlyProc: Before the base class function is called, this function checks the number of withdrawals. If the number of withdrawals for the month is more than four, a service charge of $1 for each withdrawal above four is added to the base class variable that holds the monthly service charges. (Don’t forget to check the account balance after the service charge is taken. If the balance falls below $25, the account becomes inactive. )

Next, design a checking account class, also derived from the generic account class. It should have the following member function:

withdraw: Before the base class function is called, this function will determine if a withdrawal (a check written) will cause the balance to go below $0. If the balance goes below $0, a service charge of $15 will be taken from the account. (The withdrawal will not be made.) If there isn’t enough in the account to pay the service charge, the balance will become negative and the customer will owe the negative amount to the bank.

monthlyProc: Before the base class function is called, this function adds the monthly fee of $5 plus $0.10 per withdrawal (check written) to the base class variable that holds the monthly service charges.

Write a complete program that demonstrates these classes by asking the user to enter the amounts of deposits and withdrawals for a saving account and checking account. The program should display statistics for the month, including beginning balance, total amount of deposits, total amount of withdrawals, service charges, and the ending balance. Print the result on screen and an output file.

This is a sample output

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 1

Enter amount to deposit: 100

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 2

Enter amount to deposit: 200.50

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 3

Enter amount to withdraw: 20

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 4

Enter amount to withdraw: 100

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 5

SAVINGS ACCOUNT MONTHLY STATISTICS:
Withdrawals: 1
Deposits: 1
Service Charges: 0.00
Ending Balance: 80.33

Press a key to continue...

CHECKING ACCOUNT MONTHLY STATISTICS:
Withdrawals: 1
Deposits: 1
Service Charges: 5.10
Ending Balance: 95.82

******** BANK ACCOUNT MENU ********
1. Savings Account Deposit
2. Checking Account Deposit
3. Savings Account Withdrawal
4. Checking Account Withdrawal
5. Update and Display Account Statistics
6. Exit

Your choice, please: (1-6) 6
*****finalCourseProject.cpp*****

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <fstream>
#include "bankAccount.h"
#include "checkingAccount.h"
#include "savingsAccount.h"
#include "outputStream.h"
#include "inputStream.h"

using namespace std;

void menu(checkingAccount, savingsAccount);

int main() {
    double initialCBalance;
    double initialSBalance;
    double interestRate = 0;
    
    stream << "What is the initial balance in the savings account? $";
    input >> initialSBalance;
    
    stream << "What is the initial balance in the checking account? $";
    input >> initialCBalance;
    
    stream << "What is the annual interest rate? ";
    stream << interestRate;
    input >> interestRate;
    stream << interestRate;
    
    stream << "\n\n";
    
    checkingAccount checking(initialCBalance, interestRate);
    savingsAccount savings(initialSBalance, interestRate);
    menu(checking, savings);
    
    system("PAUSE");
    return 0;
}

void menu(checkingAccount checking, savingsAccount savings) {
    int menu_choice;
    double amount;
    
    stream << "******** BANK ACCOUNT MENU ********" << "\n\n";
    stream << "1. Savings Account Deposit\n";
    stream << "2. Checking Account Deposit\n";
    stream << "3. Savings Account Withdrawal\n";
    stream << "4. Checking Account Withdrawal\n";
    stream << "5. Update and Display Account Statistics\n";
    stream << "6. Exit\n";
    
    do {
        stream << "Your choice, please: (1-6) ";
        stream << menu_choice;
        input >> menu_choice;
        stream << menu_choice;
        
        if (menu_choice <= 0 || menu_choice >= 7) {
            stream << "Invalid option selected!\n";
        }
    } while (menu_choice <= 0 || menu_choice >= 7);
    
    switch(menu_choice) {
        case 1:
            stream << "Enter amount to deposit: $";
            input >> amount;
            
            savings.deposit(amount);
            
            stream << "\n\n";
            
            menu(checking, savings);
            break;
        case 2:
            stream << "Enter amount to deposit: $";
            input >> amount;
            
            checking.deposit(amount);
            
            stream << "\n\n";
            
            menu(checking, savings);
            break;
        case 3:
            stream << "Enter amount to withdraw: $";
            input >> amount;
            
            savings.withdraw(amount);
            
            stream << "\n\n";
            
            menu(checking, savings);
            break;
        case 4:
            stream << "Enter amount to withdraw: $";
            input >> amount;
            
            checking.withdraw(amount);
            
            stream << "\n\n";
            
            menu(checking, savings);
            break;
        case 5:
            stream << "\n";
            
            stream << "SAVINGS ACCOUNT MONTHLY STATISTICS:\n";
            savings.monthlyProc();
            
            stream << "\n";
            
            stream << "CHECKING ACCOUNT MONTHLY STATISTICS:\n";
            checking.monthlyProc();
            
            stream << "\n\n";
            
            menu(checking, savings);
            break;
        case 6:
            stream << "\n\n";
            break;
        default:
            break;
    }
}


*****outputStream.h*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef outputStream_h
#define outputStream_h

#include <iostream>
#include <fstream>

using namespace std;

class outputStream {
public:
    ofstream outFile;
    outputStream();
};

outputStream::outputStream() {
    outFile.open("output.txt");
}

template <class T>
outputStream& operator<< (outputStream& stream, T output) {
    stream.outFile << output;
    cout << output;
    return stream;
}

outputStream stream;

#endif /* outputStream_h */ 


*****inputStream.h*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef inputStream_h
#define inputStream_h

#include <iostream>
#include <fstream>

using namespace std;

class inputStream {
public:
    inputStream();
};

inputStream::inputStream() {
    
}

template <class T>
inputStream& operator>> (inputStream& input, T data) {
    cin >> data;
    stream.outFile << data << "\n";
    return input;
}

inputStream input;

#endif /* inputStream_h */ 
*****bankAccount.h*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#ifndef bankAccount_h
#define bankAccount_h

#include <iostream>
#include <fstream>
#include "outputStream.h"
#include "inputStream.h"

using namespace std;

class bankAccount {
public:
    bankAccount(double, double);
    virtual void deposit(double&, double&, int);
    virtual void withdraw(double&, double&, int);
    virtual void calcInt(double, double);
    virtual void monthlyProc(double, double&, double, int&, int&);
protected:
    double monthlyServiceCharges;
    double monthlyInterestRate;
    double monthlyInterest;
    const double minBalance = 25.00;
private:
};

bankAccount::bankAccount(double initialBalance, double interestRate) {
    
}

void bankAccount::deposit(double& balance, double& amount, int numDeposits) {
    balance += amount;
    numDeposits++;
}

void bankAccount::withdraw(double& balance, double& amount, int numWithdrawals) {
    balance -= amount;
    numWithdrawals++;
}

void bankAccount::calcInt(double interestRate, double balance) {
    monthlyInterestRate = (interestRate/12);
    monthlyInterest = balance * monthlyInterestRate;
    balance += monthlyInterest;
}

void bankAccount::monthlyProc(double interestRate, double& balance, double monthlyServiceCharges, int& numDeposits, int& numWithdrawals) {
    balance -= monthlyServiceCharges;
    calcInt(interestRate, balance);
    
    stream << "Withdrawals: " << numWithdrawals << "\n";
    stream << "Deposits: " << numDeposits << "\n";
    stream << "Service Charges: " << monthlyServiceCharges << "\n";
    stream << "Ending balance: " << balance << "\n";
    
    numWithdrawals = 0;
    numDeposits = 0;
    monthlyServiceCharges = 0;
}

#endif /* bankAccount_h */ 


*****checkingAccount.h*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef checkingAccount_h
#define checkingAccount_h

#include <iostream>
#include <fstream>
#include "bankAccount.h"

using namespace std;

class checkingAccount: public bankAccount {
public:
    checkingAccount(double, double);
    void deposit(double);
    void withdraw(double);
    void calcInt(double);
    void monthlyProc();
protected:
    double interestRate;
    double checkingBalance;
    int numDeposits;
    int numWithdrawals;
    double monthlyInterest;
    double monthlyInterestRate;
    const double monthlyFee = 5.00;
    const double perWithdrawalFee = 0.10;
    const double serviceCharge = 15.00;
private:
};

checkingAccount::checkingAccount(double initialBalance, double interestRate): bankAccount(initialBalance, interestRate) {
    checkingBalance = initialBalance;
    interestRate = interestRate;
    numWithdrawals = 0;
    numDeposits = 0;
}

void checkingAccount::deposit(double amount) {
    bankAccount::deposit(checkingBalance, amount, numDeposits);
}

void checkingAccount::withdraw(double amount) {
    if ((checkingBalance - amount) < 0) {
        checkingBalance -= serviceCharge;
        
        return;
    }
    bankAccount::withdraw(checkingBalance, amount, numWithdrawals);
}

void checkingAccount::calcInt(double interestRate) {
    bankAccount::calcInt(interestRate, checkingBalance);
}

void checkingAccount::monthlyProc() {
    monthlyServiceCharges = monthlyFee + (numWithdrawals * perWithdrawalFee);
    bankAccount::monthlyProc(interestRate, checkingBalance, monthlyServiceCharges, numDeposits, numWithdrawals);
}

#endif /* checkingAccount_h */ 


*****savingsAccount.h*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef savingsAccount_h
#define savingsAccount_h

#include <iostream>
#include <fstream>
#include "bankAccount.h"

using namespace std;

class savingsAccount: public bankAccount {
public:
    savingsAccount(double, double);
    void deposit(double);
    void withdraw(double);
    void calcInt(double);
    void monthlyProc();
protected:
    const double withdrawalCharge = 1.00;
    double interestRate;
    double savingsBalance;
    int numDeposits;
    int numWithdrawals;
    bool status = true;
    double monthlyInterest;
    double monthlyInterestRate;
private:
};

savingsAccount::savingsAccount(double initialBalance, double interestRate): bankAccount(initialBalance, interestRate) {
    savingsBalance = initialBalance;
    interestRate = interestRate;
    numWithdrawals = 0;
    numDeposits = 0;
}

void savingsAccount::deposit(double amount) {
    bankAccount::deposit(savingsBalance, amount, numDeposits);
    
    if (savingsBalance < minBalance) {
        status = false;
    } else if (savingsBalance >= minBalance) {
        status = true;
    }
}

void savingsAccount::withdraw(double amount) {
    bankAccount::withdraw(savingsBalance, amount, numWithdrawals);
    
    if (savingsBalance < minBalance) {
        status = false;
    } else if (savingsBalance >= minBalance) {
        status = true;
    }
}

void savingsAccount::calcInt(double interestRate) {
    bankAccount::calcInt(interestRate, savingsBalance);
}

void savingsAccount::monthlyProc() {
    if (numWithdrawals > 4) {
        monthlyServiceCharges = (numWithdrawals - 4) * withdrawalCharge;
    }
    
    bankAccount::monthlyProc(interestRate, savingsBalance, monthlyServiceCharges, numDeposits, numWithdrawals);
    
    if (savingsBalance < minBalance) {
        status = false;
    } else if (savingsBalance >= minBalance) {
        status = true;
    }
}

#endif /* savingsAccount_h */ 


Thanks in advance for any/all help!
> but the input object doesn't hold the value I set for the variable.

Pass by reference.
1
2
3
template <class T>
// inputStream& operator>> (inputStream& input, T data) {
inputStream& operator>> (inputStream& input, T& data) { // data is passed by reference 



> //Works well with sout << m << 0.1 << " haha\n";
> //- But doesn't work well for sout << endl;

std::endl is a template; so type deduction for the single template argument fails.
http://en.cppreference.com/w/cpp/io/manip/endl

The simplest fix would be something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

struct output_stream {

    output_stream( std::string file_name = "out.txt" ) : file(file_name) {}

    template < typename T > output_stream& operator<< ( const T& value ) {

        std::cout << value ;
        file << value ;
        return *this ;
    }

    // ios manipulators
    output_stream& operator<< ( std::ios_base& (*manip) ( std::ios_base& ) ) {
        std::cout << manip ;
        file << manip ;
        return *this ;
    }

    template < typename... T > // ostream manipulators with zero or more arguments
    output_stream& operator<< ( std::ostream& (*manip) (  std::ostream&, const T&... )  ) {

        std::cout << manip ;
        file << manip ;
        return *this ;
    }

    private: std::ofstream file ;
};

int main() {

    output_stream stm ;
    stm << 123456 << ' ' << std::hex << std::showbase << 123456 << ' ' << std::setw(23)
        << std::setfill( '~' ) << std::quoted( "hello world", '\'' ) << '\n' << std::endl ;
}

http://coliru.stacked-crooked.com/a/4ca294a243ef4020
Thank you so much, it worked like a charm. I don't know how I missed passing the data by reference.
Topic archived. No new replies allowed.