Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

help in C++ with pure virtual functions 1) This project will create a base accou

ID: 3860252 • Letter: H

Question

help in C++ with pure virtual functions

1) This project will create a base account class that has the members:

std::string account_code; std::string first_name; std::string last_name; double balance;

Provide a constructor that initializes ALL members in its initialization list with data passed in as arguments to the constructor. Provide any accessor functions you may need (e.g. to get the account code and balance and to set the balance).

In addition, include two pure virtual functions that look like the following:

virtual void monthly_update() = 0; virtual char type() const = 0;

2) Design and implement the following derived classes that will inherit from account and implement the monthly_update function in the following manner:

Class Name Implementation

simple_account balance *= 1.05

bonus_account balance = balance * (balance > 5000 ? 1.06 : 1.04)

service_account balance = (balance - 5.0) * 1.04

balanced_account balance = balance > 500.0 ? balance * 1.05 : (balance - 5.0) * 1.03

Each derived class will also override the type function to return a single character that describes the type as indicated in (3) below instead of storing the character.

3) Create a factory function or class that reads data in the following fixed format:

account code : 10 characters first name : 15 characters last name : 25 characters type: 1 character balance : numeric 8 digits, decimal place, 2 digits

and uses that data to dynamically allocate and construct one of the derived objects based on the value of type as indicated in the following table:

Type Class to Dynamically Instantiate

‘A’ simple_account

‘B’ bonus_account

‘C’ service_account

‘D’ balanced_account

If the type is an ‘X’, skip the account record. In other words, the account should not be processed by the rest of the program and should not appear in the result.

If the type is anything else, log the error to a file named “account.log”, but DO NOT stop processing the rest of the accounts.

Trim spaces from the right of the first_name and last_name members using the trim library you constructed in assignment 5.

4) Write a manager class that has a std::map> member. Note the use of std::unique_ptr for the “ownership” of the accounts added to the map. This will automatically clean up the accounts when the map goes out of scope.

5) The manager class will have a member function that performs the processing of the accounts. This processing is laid out as follows:

a. Open an std::ifstream on the file, "account2.dat", which will be supplied to you. If the file does not exist, log this to the "account.log" file and exit the program (presumably using an exception).

b. For each account in the input file, invoke the factory function/class written in part 3. Each object returned from the factory function will then be inserted into the map, using the account as the key. If the account is to be ignored, or if the factory function throws a fatal exception, no account should be inserted into the map (let alone even created). At the end of the stream, proceed with the next step.

c. Open another std::ifstream on the transaction file, “transact.dat”, which has the following format:

account : 10 characters amount : numeric 8 digits, decimal place, 2 digits

For each record in the transaction file, find the account in the map and apply the transaction amount (which could be negative) to the balance for that account. Output an error to the “account.log” file if the account is not found in the map, but do NOT stop processing the transaction file.

d. When all transactions are processed, iterate through the map and invoke the monthly_update function for each account in the map.

e. Using a std::ofstream, output each account in the map to a new file named "update.dat" in the SAME format as "account2.dat".

f. Output the accounts in a "human readable format" to a file, "report.txt". The output format is of your choice, but please include all the members of each account per line (including the type).

6) In your program's main function, instantiate your manager class from part 4, and invoke the member function in (5) to process the records. Remember to take care of any exceptions that could possibly "leak" out.

acount2.dat file is:

1234567890Fred Murtz C00002000.01
9237405759Nolan Ryan A07237895.75
5285064395Debbie Schneiderman C00201537.31
5839659462Friedman Hochstrasser A00048392.42
9587498357Bayern Richard E00003457.12
3245987475Breeches Lefty X00000000.00
7395659299Milhouse Van Houten D00000002.85
2956294386Julian Schwinger B00335821.93
9765324598Joanne Bryant B08459873.08
4385638273Richard Ames A00008468.74

Explanation / Answer

main.cpp
----------------------
#include"account_manager.h"
#include"jlexcept.h"
#include<iostream>

int main() try {
    jl::account_manager a_mgr("account2.dat");
    a_mgr.main();
} catch(jl::jlexcept& e) {
    std::cerr << e.what() << ' ';
} catch(std::exception& e) {
    std::cerr << e.what() << ' ';
} catch(...) {
    std::cerr << "Unknown error occurred ";
}
--------------------------------------------
account.cpp
-----------------------
#include"account.h"
#include<sstream>
#include<iomanip>

jl::account::account(const std::string& _init_account_code, const std::string& _init_first_name, const std::string& _init_last_name, double _init_balance) try :
        account_code(_init_account_code), first_name(_init_first_name), last_name(_init_last_name), balance(_init_balance)
{
    if(account_code.empty())
        throw jl::jlexcept("Account code cannot be an empty string");
    if(first_name.empty())
        throw jl::jlexcept("First name cannot be an empty string");
    if(last_name.empty())
        throw jl::jlexcept("Last name cannot be an empty string");
} catch(jl::jlexcept& e) {
    throw e;
} catch(std::exception& e) {
    throw jl::jlexcept(e.what());
} catch(...) {
    throw jl::jlexcept(construct_excpt_msg) + jl::jlexcept("Unknown error");
}

std::string jl::account::to_string() const {
    std::string rtn_string;
    rtn_string = account_code;
    rtn_string += first_name;
    std::fill_n(std::back_inserter(rtn_string), 15 - first_name.size(), ' ');
    rtn_string += last_name;
    std::fill_n(std::back_inserter(rtn_string), 25 - last_name.size(), ' ');
    rtn_string += type();
    std::stringstream ss;
    ss << std::setfill('0') << std::setw(11) << std::fixed << std::setprecision(2) << balance;
    rtn_string += ss.str();
    return rtn_string;
}

----------------------------------------------
account.h
-----------------------
#pragma once

#if !defined(__JL__ACCOUNT_HEADER_INCLUDED__)
#define __JL__ACCOUNT_HEADER_INCLUDED__
#include"jlexcept.h"
#include<cstdlib>
#include<iomanip>
#include<string>

namespace jl {
    const char construct_excpt_msg[] = { "Error occurred while attempting to construct account object" };
    const char invalid_mbr_excpt_msg[] = {"An error occurred while attempting to change to value of a data member"};
    class account {
    private:
        std::string account_code;
        std::string first_name;
        std::string last_name;
        double balance;
    public:
        account(const std::string&, const std::string&, const std::string&, double);
        virtual void monthly_update() = 0;
        virtual char type() const = 0;

        inline const std::string& get_account_code() const throw() { return account_code; };
        inline const std::string& get_first_name() const throw() { return first_name; };
        inline const std::string& get_last_name() const throw() { return last_name; };
        inline const double get_balance() const throw() { return balance; };

        inline void set_account_code(const std::string&); //defined below
        inline void set_first_name(const std::string&);    //defined below
        inline void set_last_name(const std::string&);     //defined below
        inline void set_balance(double b) { balance = b; }
        std::string to_string() const;
        inline void output(std::ostream& s) const {
            s << this->type() << ',' << account_code << ',' << first_name << ',' << last_name << ',' << std::fixed << std::setprecision(2) << balance;
        }

        inline bool operator<(const std::string& s) const { return account_code < s; }
        inline bool operator<=(const std::string& s) const { return account_code <= s; }
        inline bool operator==(const std::string& s) const { return account_code == s; }
        inline bool operator>(const std::string& s) const { return account_code > s; }
        inline bool operator>=(const std::string& s) const { return account_code >= s; }
        inline bool operator<(const char* s) const { return account_code < s; }
        inline bool operator<=(const char* s) const { return account_code <= s; }
        inline bool operator==(const char* s) const { return account_code == s; }
        inline bool operator>(const char* s) const { return account_code > s; }
        inline bool operator>=(const char* s) const { return account_code >= s; }

        template<typename T>
        inline bool operator<(const T a) const { return account_code < a.account_code; }
        template<typename T>
        inline bool operator<=(const T a) const { return account_code <= a.account_code; }
        template<typename T>
        inline bool operator==(const T a) const { return account_code == a.account_code; }
        template<typename T>
        inline bool operator>(const T a) const { return account_code > a.account_code; }
        template<typename T>
        inline bool operator>=(const T a) const { return account_code >= a.account_code; }
        friend inline std::ostream& operator<<(std::ostream& s, const jl::account& a) {
            a.output(s);
            return s;
        }
    };

    inline void jl::account::set_account_code(const std::string& s) try {
        if(s.empty())
            throw jl::jlexcept("Account code cannot be an empty string");
        account_code = s;
    } catch(jl::jlexcept& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + e;
    } catch(std::exception& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept(e.what());
    } catch(...) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept("Unknown error");
    }

    inline void jl::account::set_first_name(const std::string& s) try {
        if(s.empty())
            throw jl::jlexcept("First name cannot be an empty string");
        first_name = s;
    } catch(jl::jlexcept& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + e;
    } catch(std::exception& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept(e.what());
    } catch(...) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept("Unknown error");
    }

    inline void jl::account::set_last_name(const std::string& s) try {
        if(s.empty())
            throw jl::jlexcept("Last name cannot be an empty string");
        last_name = s;
    } catch(jl::jlexcept& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + e;
    } catch(std::exception& e) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept(e.what());
    } catch(...) {
        throw jl::jlexcept(invalid_mbr_excpt_msg) + jl::jlexcept("Unknown error");
    }
}
#endif
----------------------------------------------
account_factory.cpp
-----------------------
#include"account_factory.h"
#include<sstream>
jl::account* jl::account_factory::operator()(const char _type, const std::string& _account_code, const std::string& _first_name, const std::string& _last_name, double _balance) {
    jl::account* a_ptr = nullptr;
    switch(_type) {
        case 'A':
            a_ptr = new jl::simple_account(_account_code, _first_name, _last_name, _balance);
            break;
        case 'B':
            a_ptr = new jl::bonus_account(_account_code, _first_name, _last_name, _balance);
            break;
        case 'C':
            a_ptr = new jl::service_account(_account_code, _first_name, _last_name, _balance);
            break;
        case 'D':
            a_ptr = new jl::service_account(_account_code, _first_name, _last_name, _balance);
            break;
        case 'X':
            break;
        default:
            std::stringstream ss;
            ss << _type << " is not a recognized account type";
            throw jl::jlexcept(ss.str());
            break;
    }
    return a_ptr;
}
----------------------------------------------
account_factory.h
-----------------------
#pragma once
#if !defined(__JL__ACCOUNT_FACTORY_HEADER_INCLUDED__)
#define __JL__ACCOUNT_FACTORY_HEADER_INCLUDED__
#include"simple_account.h"
#include"bonus_account.h"
#include"balanced_account.h"
#include"service_account.h"

namespace jl {
    class account_factory {
    public:
        jl::account* operator()(const char, const std::string&, const std::string&, const std::string&, double);
    };
}

#endif
----------------------------------------------
account_manager.cpp
-----------------------
#include"account_manager.h"

void jl::account_manager::main() {
    std::ifstream is;
    uint32_t _records_processed = 0;
    try {
        open_input_file(is);
    } catch(jl::jlexcept& e) {
        _log.add_exception(e);
        _log.dump();
        throw e;
    }
    std::string line_input;
    while(!is.eof()) {
        char _buffer = is.peek();
        while(_buffer == ' ' && _buffer != EOF) {
            is.ignore(1);
            _buffer = is.peek();
        }
        if(_buffer != EOF) {
            ++_records_processed;
            std::getline(is, line_input, ' ');
            try {
                jl::acct_data* a_data = parse_line_input(line_input);
                add_account(a_data->_type, a_data->_account_code, a_data->_first_name,
                            a_data->_last_name, a_data->_balance);
                delete a_data;
            } catch(jl::jlexcept& e) {
                _log.add_exception(e, _records_processed);
            }
        } else {
            break;
        }
    }
    update_accounts();
    std::vector<std::string> u_vec;
    u_vec = to_string();
    std::ofstream os;
    os.open("update.dat");
    if(os.bad() || os.fail()) {
        _log.add_exception("Output file for updated accounts could not be opened");
    } else {
        for(auto s : u_vec)
            os << s << ' ';
        os.close();
        if(os.bad() || os.fail()) {
            _log.add_exception("Output file for updated accounts could not be closed");
        }
        try {
            print_report("Report.txt");
        } catch(jl::jlexcept& e) {
            _log.add_exception(e);
        }
    }
    _log.dump();
}

jl::acct_data* jl::account_manager::parse_line_input(const std::string& _input) const {
    if(_input.size() != 62)
        throw jl::jlexcept("Line input is not formatted correctly. "
                                   "Fields are delimited by fixed widths: Account = 10 First Name = 15 Last Name = 25"
                                   " Type = 1 Balance = 11 - Balance should be filled with 0's and two decimal places");
    jl::acct_data* a_data_ptr = new jl::acct_data;
    a_data_ptr->_account_code = _input.substr(0, 10);
    a_data_ptr->_first_name = generic::trim_right(_input.substr(10, 15));
    a_data_ptr->_last_name = generic::trim_right(_input.substr(25, 25));
    a_data_ptr->_type = _input.substr(50, 1).c_str()[0];
    a_data_ptr->_balance = std::stod(_input.substr(51, 11));
    return a_data_ptr;
}

void jl::account_manager::print_report(const std::string& _output) const {
    std::ofstream os;
    os.open(_output);
    if(os.bad() || os.fail())
        throw jl::jlexcept(_output + " could not be opened");
    os << "Type" << "    " << std::setw(12) << std::left << "Account Code" << "    "
       << std::setw(35) << std::left << "Last Name, First Name"
       << std::setw(12) << std::right << "Balance ";
    for(jl::account* a : accounts) {
        os << a->type() << "       " << std::setw(12) << std::left << a->get_account_code()
           << "    " << std::setw(35) << std::left << a->get_last_name() + ", " + a->get_first_name()
           << std::setw(11) << std::fixed << std::setprecision(2) << std::right << a->get_balance() << ' ';
    }
    os.close();
    if(os.bad() || os.fail())
        throw jl::jlexcept(_output + " could not be closed");

}
----------------------------------------------
account_manager.h
-----------------------
#pragma once
#if !defined(__JL__ACCOUNT_MANAGER_HEADER_INCLUDED__)
#define __JL__ACCOUNT_MANAGER_HEADER_INCLUDED__
#include"account_factory.h"
#include"exception_log.h"
#include"trim.h"
#include<vector>
#include<fstream>
#include<string>
namespace jl {
    struct acct_data {
        char _type;
        std::string _account_code;
        std::string _first_name;
        std::string _last_name;
        double _balance;
    };
    class account_manager {
    private:
        const std::string input_file_name;
        std::vector<jl::account*> accounts;
        jl::exception_log _log;
        inline void open_input_file(std::ifstream& is) {
            is.open(input_file_name);
            if(is.bad() || is.fail())
                throw jl::jlexcept("Input file could not be opened or does not exist");
        }
    public:
        account_manager(const std::string& _init_input_file_name) try : input_file_name(_init_input_file_name), _log("account.log", std::ios_base::out) {
            if(input_file_name.empty())
                throw jl::jlexcept("Input file name cannot be empty string");
        } catch(std::exception& e) {
            throw e;
        } catch(...) {
            throw jl::jlexcept("Unknow error occurred while constructing jl::account_manager");
        }
        ~account_manager() { for(jl::account* a : accounts) delete a; }
        void main();
        acct_data* parse_line_input(const std::string&) const;
        void print_report(const std::string&) const;
        inline void update_accounts() { for(jl::account* a : accounts) a->monthly_update(); }
        inline void output(std::ostream& s) const { for(jl::account* a : accounts) s << *a << ' '; }
        inline void add_account(const char, const std::string&,
                                const std::string&, const std::string&, double);
        inline std::vector<std::string> to_string() const {
            std::vector<std::string> s_vec;
            for(jl::account* a : accounts)
                s_vec.push_back(a->to_string());
            return s_vec;
        }
        inline friend std::ostream& operator<<(std::ostream& s, const jl::account_manager& a_mgr) {
            a_mgr.output(s);
            return s;
        }
    };

    inline void jl::account_manager::add_account(const char _type, const std::string& _account_code,
                                                 const std::string& _first_name, const std::string& _last_name, double _balance) {
        jl::account_factory __factory;
        jl::account* acct_ptr = __factory(_type, _account_code, _first_name, _last_name, _balance);
        if(acct_ptr)
            accounts.push_back(acct_ptr);
    }
}

#endif
----------------------------------------------
balanced_account.h
-----------------------
#pragma once
#if !defined(__JL__BALANCED_ACCOUNT_HEADER_INCLUDED__)
#define __JL__BALANCED_ACCOUNT_HEADER_INCLUDED__
#include"account.h"
#include"jlexcept.h"
#include<string>
namespace jl {
    class balanced_account : public account {
    public:
        balanced_account(const std::string& _init_account_code, const std::string& _init_first_name, const std::string& _init_last_name, double _init_balance) try :
                jl::account(_init_account_code, _init_first_name, _init_last_name, _init_balance)
        {
        } catch(jl::jlexcept& e) {
            throw e;
        } catch(std::exception& e) {
            throw e;
        } catch(...) {
            throw jl::jlexcept("Unknown error");
        }
        inline void monthly_update() { set_balance(get_balance() > 500.0 ? get_balance() * 1.05 : (get_balance() - 5.0) * 1.03); }
        inline char type() const { return 'D'; }
    };
}
#endif
----------------------------------------------
bonus_account.h
-----------------------
#pragma once
#if !defined(__JL__BONUS_ACCOUNT_HEADER_INCLUDED__)
#define __JL__BONUS_ACCOUNT_HEADER_INCLUDED__
#include"account.h"
#include"jlexcept.h"
#include<string>
namespace jl {
    class bonus_account : public account {
    public:
        bonus_account(const std::string& _init_account_code, const std::string& _init_first_name, const std::string& _init_last_name, double _init_balance) try :
                jl::account(_init_account_code, _init_first_name, _init_last_name, _init_balance)
        {
        } catch(jl::jlexcept& e) {
            throw e;
        } catch(std::exception& e) {
            throw e;
        } catch(...) {
            throw jl::jlexcept("Unknown error");
        }
        inline void monthly_update() { set_balance(get_balance() * (get_balance() > 5000 ? 1.06 : 1.04)); }
        inline char type() const { return 'B'; }
    };
}
#endif
----------------------------------------------
exception_log.h
-----------------------
#pragma once
#if !defined(__JL__EXCEPTION_LOG_HEADER_INCLUDED__)
#define __JL__EXCEPTION_LOG_HEADER_INCLUDED__
#include"exception_record.h"
#include"jlexcept.h"
#include<vector>
#include<fstream>
namespace jl {
    class exception_log {
    private:
        std::string _log_file_name;
        std::ios_base::open_mode _open_mode;
        uint32_t _exception_count;
        std::vector<jl::exception_record> _exceptions;
    public:
        exception_log(const std::string& _init_log_file_name, const std::ios_base::openmode& _init_open_mode) :
                _log_file_name(_init_log_file_name), _open_mode(_init_open_mode), _exception_count(0) {
            if(_log_file_name.empty())
                throw jl::jlexcept("jl::exception_log member '_log_file_name' cannot be an empty string");
        }
        ~exception_log() { if(_exception_count > 0) dump(); }
        inline void add_exception(const jl::exception_record& er) { _exceptions.push_back(er); ++_exception_count; }
        inline void add_exception(const std::string& s, const uint32_t r = 0) { _exceptions.push_back(jl::exception_record(s, r)); ++_exception_count; }
        inline void add_exception(const char* s, const uint32_t r = 0) { _exceptions.push_back(jl::exception_record(s, r)); ++_exception_count; }
        template<typename T>
        inline void add_exception(const T& e, const uint32_t r = 0) { _exceptions.push_back(jl::exception_record(e.what(), r)); ++_exception_count; }
        inline void dump() {
            if(_exception_count > 0) {
                std::ofstream _log;
                _log.open(_log_file_name.c_str(), _open_mode);
                if(_log.bad() || _log.fail())
                    throw jl::jlexcept(_log_file_name + " could not be opened");
                for(jl::exception_record er : _exceptions)
                    _log << er << ' ';
                _log.close();
                _exceptions.clear();
                _exception_count = 0;
            }
        }
    };
}

#endif
----------------------------------------------
exception_record.h
-----------------------
#pragma once
#if !defined(__JL__EXCEPTION_RECORD_HEADER_INCLUDED__)
#define __JL__EXCEPTION_RECORD_HEADER_INCLUDED__
#include<cstdint>
#include<string>
namespace jl {
    class exception_record {
    private:
        std::string exception_msg;
        uint32_t record_number;
    public:
        exception_record(const std::string& _init_msg, const uint32_t _init_record = 0) :
                exception_msg(_init_msg), record_number(_init_record)
        {}
        inline void output(std::ostream& s) const {
            if(!record_number)
                s << exception_msg;
            else
                s << "Record Number: " << record_number << ' ' << exception_msg;
        }
        inline friend std::ostream& operator<<(std::ostream& s, const exception_record& er) {
            er.output(s);
            return s;
        }
    };
}

#endif
----------------------------------------------
jlexcept.h
-----------------------
#if !defined(_JL_EXCEPT_HEADER_INCLUDED_)
#define _JL_EXCEPT_HEADER_INCLUDED_
#pragma once

#include<sstream>
#include<string>

namespace jl {
    class jlexcept {
    private:
        std::string file;
        int line;
        std::string description;
        std::string what_string;
    public:
        //constructors
        jlexcept(std::string init_file,int init_line,std::string init_desc) :
                file(init_file),
                line(init_line),
                description(init_desc)
        {
            std::ostringstream s;
            s << file << "(" << line << "): ERROR - " << description << ' ';
            what_string = s.str();
        }
        jlexcept(std::string init_desc) : file(__FILE__), line(__LINE__), description(init_desc) {
            std::ostringstream s;
            s << description;
            what_string = s.str();
        }
        //accessors
        inline std::string get_file() const throw() { return file; }
        inline int get_line() const throw() { return line; }
        inline std::string get_description() const throw() { return description; }
        const char* what() const throw() { return what_string.c_str(); }

        //modifiers
        inline static void combine_exception_info(jlexcept& e_left, const jlexcept& e_right) {
            std::ostringstream s;
            s << e_left.get_file() << "(" << e_left.get_line() << "): ERROR - " << e_left.get_description() << ' ';
            s << e_right.get_file() << "(" << e_right.get_line() << "): ERROR - " << e_right.get_description() << ' ';
            e_left.what_string = s.str();
        }
        //operators
        inline friend jlexcept& operator +=(jlexcept& e_left, const jlexcept& e_right) {
            combine_exception_info(e_left, e_right);
            return e_left;
        }
        inline friend jlexcept& operator+(const jlexcept& e_left, const jlexcept& e_right) {
            return jlexcept(e_left) = e_right;
        }
    };
}
#endif

----------------------------------------------
service_account.h
-----------------------
#pragma once
#if !defined(__JL__SERVICE_ACCOUNT_HEADER_INCLUDED)
#define __JL__SERVICE_ACCOUNT_HEADER_INCLUDED
#include"account.h"
#include"jlexcept.h"
#include<string>
namespace jl {
    class service_account : public account {
    public:
        service_account(const std::string& _init_account_code, const std::string& _init_first_name, const std::string& _init_last_name, double _init_balance) try :
                jl::account(_init_account_code, _init_first_name, _init_last_name, _init_balance)
        {
        } catch(jl::jlexcept& e) {
            throw e;
        } catch(std::exception& e) {
            throw e;
        } catch(...) {
            throw jl::jlexcept("Unkown error");
        }
        inline void monthly_update() { set_balance((get_balance() - 5.0) * 1.04); }
        inline char type() const { return 'C'; }
    };
}
#endif
----------------------------------------------
simple_account.h
-----------------------
#pragma once
#if !defined(__JL__SIMPLE_ACCOUNT_HEADER_INCLUDED__)
#define __JL__SIMPLE_ACCOUNT_HEADER_INCLUDED__
#include"account.h"
#include"jlexcept.h"
#include<string>
namespace jl {
    class simple_account : public jl::account {
    public:
        simple_account(const std::string& _init_account_code, const std::string& _init_first_name, const std::string& _init_last_name, double _init_balance) try :
                jl::account(_init_account_code, _init_first_name, _init_last_name, _init_balance)
        {
        } catch(jl::jlexcept& e) {
            throw e;
        } catch(std::exception& e) {
            throw e;
        } catch(...) {
            throw jl::jlexcept("Error occurred while constructing simple account");
        }
        inline void monthly_update() { set_balance(get_balance() * 1.05); }
        inline char type() const { return 'A'; }
    };
}
#endif
----------------------------------------------
trim.cpp
-----------------------
#include "trim.h"

namespace generic {

    std::string trim_right(const std::string& s) {
        std::string::size_type e = s.find_last_not_of(" ");
        return std::string(s, 0, e == std::string::npos ? 0 : e + 1);
    }

    std::string trim_left(const std::string& s) {
        std::string::size_type b = s.find_first_not_of(" ");
        return std::string(s, b == std::string::npos ? 0 : b, std::string::npos);
    }

    std::string trim(const std::string& s) {
        const char* ws = " ";
        std::string::size_type e = s.find_last_not_of(ws);
        std::string::size_type b = s.find_first_not_of(ws);
        if (b == std::string::npos) { b = 0; }
        return std::string(s, b, e == std::string::npos ? 0 : e - b + 1);
    }

}

----------------------------------------------
trip.h
-----------------------
#pragma once

#if !defined(__generic_trim_h__)
#define __generic_trim_h__

#include <string>

namespace generic {

    std::string trim_right(const std::string& s);
    std::string trim_left(const std::string& s);
    std::string trim(const std::string& s);

}

#endif
----------------------------------------------
account2.dat
----------------------
1234567890Fred           Murtz                    C00002000.01
9237405759Nolan          Ryan                     A07237895.75
5285064395Debbie         Schneiderman             C00201537.31
5839659462Friedman       Hochstrasser             A00048392.42
9587498357Bayern         Richard                  E00003457.12
3245987475Breeches       Lefty                    X00000000.00
7395659299Milhouse       Van Houten               D00000002.85
2956294386Julian         Schwinger                B00335821.93
9765324598Joanne         Bryant                   B08459873.08
4385638273Richard Ames A00008468.74