zoukankan      html  css  js  c++  java
  • 个人银行账户管理程序

      这个程序是一个银行账户管理的程序,是用C++来实现程序功能的,该程序包含六个文件,其中有date.h头文件

    是日期类的头文件,date.cpp是日期类的实现文件,accumulator.h是按日将数值累加的accumulator类的头文件,

    account.h是各个储蓄账户类定义的头文件,account.cpp是各个储蓄账户类的实现文件,还有就是主函数文件。该

    程序包含了增加账户功能、存款功能、取款功能、查询账户信息功能、改变日期功能、进入下个月的处理功能,最

    后是退出程序。下面是各个程序文件:

     1.date.h日期类的头文件

    #ifndef _DATE_H
    #define _DATE_H
    #include <iostream>
    using namespace std;
    class Date
    {
    public:
        Date(int year = 1,int month = 1,int day = 1);
        int getYear()const
        {
            return year;
        }
        int getMonth()const
        {
            return month;
        }
        int getDay()const
        {
            return day;
        }
        int getMaxDay()const;        //获得当月有多少天
        bool isLeapYear() const      //判断当年是否为闰年
        {
            return year % 4 == 0 && year % 100 != 0 && year % 400 == 0;
        }
        void show()const;        //输出当前日期
        int operator-(const Date &date)const      //计算两个日期之间差多少天
        {
            return totalDays - date.totalDays;
        }
        bool operator<(const Date &date)const     //判断两个日期的前后顺序
        {
            return totalDays < date.totalDays;
        }
    private:
        int year;
        int month;
        int day;
        int totalDays;       //该日期是从公元元年1月1日开始的第几天
    };
    istream& operator >> (istream &in, Date &date);
    ostream& operator << (ostream &out, const Date &date);
    
    #endif

     2.date.cpp日期类实现的文件

    #include <iostream>
    #include <stdexcept>
    #include "date.h"
    using namespace std;
    
    namespace      //namespace使下面的定义只在当前文件中有效
    {
        //存储平年中的某个月1日之前有多少天,为便于getMaxDay函数的实现,该数组多出一项
        const int DAYS_BEFORE_MONTH[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 };
    }
    Date::Date(int year, int month, int day):year(year),month(month),day(day)
    {
        if (day <= 0 || day > getMaxDay())throw runtime_error("Invalid date");
        int years = year - 1;
        totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day;
        if (isLeapYear() && month > 2)
            totalDays++;
    }
    int Date::getMaxDay()const
    {
        if (isLeapYear() && month == 2)
            return 29;
        else
            return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
    }
    void Date::show()const
    {
        cout << getYear() << "-" << getMonth() << "-" << getDay();
    }
    istream& operator >> (istream &in, Date &date)
    {
        int year, month, day;
        char c1, c2;
        in >> year >> c1 >> month >> c2 >> day;
        if (c1 != '-' || c2 != '-')
            throw runtime_error("Bad time format");
        date = Date(year, month, day);
        return in;
    }
    ostream& operator<<(ostream &out, const Date &date)
    {
        out << date.getYear() << "-" << date.getMonth() << "-" << date.getDay();
        return out;
    }

     3.accumulator.h按日将数值累加的头文件

    #ifndef _ACCUMULATOR_H
    #define _ACCUMULATOR_H
    #include "date.h"
    class Accumulator            //将某个数值按日累加
    {
    public:
        //date为开始累加的日期,value为初始值
        Accumulator(const Date &date, double value):lastDate(date),value(value),sum(0)
        {
        }
        double getSum(const Date &date)const
        {
            return sum + value*(date - lastDate);
        }
        //在date将数值变更为value
        void change(const Date &date, double value)
        {
            sum = getSum(date);
            lastDate = date;
            this->value = value;
        }
        //初始化,将日期变为date,数值变为value,累加器清零
        void reset(const Date &date, double value)
        {
            lastDate = date;
            this->value = value;
            sum = 0;
        }
    private:
        Date lastDate;           //上次变更数值的时期
        double value;            //数值的当前值
        double sum;              //数值按日累加之和
    };
    
    #endif

     4.account.h各个储蓄账户类定义的头文件

    #ifndef _ACCOUNT_H
    #define _ACCOUNT_H
    #include "date.h"
    #include "accumulator.h"
    #include <iostream>
    #include <string>
    #include <map>
    #include <istream>
    #include <stdexcept>
    using namespace std;
    
    class Account;
    class AccountRecord        //账目记录
    {
    public:
        AccountRecord(const Date &date, const Account* account, double amount, double balance, const string &desc);
        void show()const;          //输出当前记录
    private:
        Date date;                 //日期
        const Account* account;    //账户
        double amount;             //金额
        double balance;            //余额
        string desc;               //描述
    };
    
    typedef multimap<Date, AccountRecord> RecordMap;
    //账户类
    class Account
    {
    public:
        const string& getId()const
        {
            return id;
        }
        double getBalance()const
        {
            return balance;
        }
        static double getTotal()
        {
            return total;
        }
        //存入现金,date为日期,amount为金额,desc为款项说明
        virtual void deposit(const Date &date, double amount, const string &desc) = 0;
        //取出现金,date为日期,amount为金额,desc为款项说明
        virtual void withdraw(const Date &date, double amount, const string &desc) = 0;
        //结算,每月结算一次,date为结算日期
        virtual void settle(const Date &date) = 0;
        //显示账户信息
        virtual void show(ostream &out)const;
        //查询指定时间内的账目记录
        static void query(const Date &begin, const Date &end);
    protected:
        //供派生类调用的构造函数
        Account(const Date &date, const string &id);
        //记录一笔账,date为日期,amount为金额,desc为说明
        void record(const Date &date, double amount, const string &desc);
        //报告错误信息
        void error(const string &msg)const;
    private:
        string id;              //账户
        double balance;         //余额
        static double total;    //所有账户的总金额
        static RecordMap recordMap;    //账目记录
    };
    inline ostream& operator<<(ostream &out, const Account &account)
    {
        account.show(out);
        return out;
    }
    
    class SavingAccount :public Account         //储蓄账户类
    {
    public:
        SavingAccount(const Date &date, const string &id, double rate);
        double getRate()const
        {
            return rate;
        }
        //存入现金
        void deposit(const Date &date, double amount, const string &desc);
        //取出现金
        void withdraw(const Date &date, double amount, const string &desc);
        //结算利息,每年1月1日调用一次该函数
        void settle(const Date &date);      
    private:
        Accumulator acc;           //辅助计算利息的累加器
        double rate;               //存款的年利率
    };
    
    class CreditAccount :public Account        //信用账户类
    {
    public:
        CreditAccount(const Date &date, const string &id, double credit, double rate, double fee);
        double getCredit()const
        {
            return credit;
        }
        double getRate()const
        {
            return rate;
        }
        double getFee()const
        {
            return fee;
        }
        double getAvailableCredit()const            //获得可用信用额度
        {
            if (getBalance() < 0)
                return credit + getBalance();
            else
                return credit;
        }
        //存入现金
        void deposit(const Date &date, double amount, const string &desc);
        //取出现金
        void withdraw(const Date &date, double amount, const string &desc);
        //结算利息和年费,每月1日调用一次该函数
        void settle(const Date &date);
        virtual void show(ostream &out)const;
    private:
        Accumulator acc;         //辅助计算利息的累加器
        double credit;           //信用额度
        double rate;             //欠款的日利率
        double fee;              //信用卡年费
        double getDebt() const   //获得欠款额
        {
            double balance = getBalance();
            return (balance < 0 ? balance : 0);
        }
    };
    
    class AccountException :public runtime_error
    {
    public:
        AccountException(const Account* account, const string &msg) :runtime_error(msg), account(account)
        {
        }
        const Account* getAccount()const
        {
            return account;
        }
    private:
        const Account* account;
    };
    
    #endif

     5.account.cpp各个储蓄账户类的实现文件

    #include <iostream>
    #include <cmath>
    #include <utility>
    #include "account.h"
    using namespace std;
    using namespace std::rel_ops;
    
    //AccountRecord类的实现
    AccountRecord::AccountRecord(const Date &date,const Account* account,double amount,double balance,const string &desc):
    date(date), account(account), amount(amount), balance(balance), desc(desc)
    {
    }
    void AccountRecord::show()const
    {
        cout << date << "	#" << account->getId() << "	" << amount << "	" << balance << "	" << desc << endl;
    }
    
    //Account类的实现
    double Account::total = 0;
    RecordMap Account::recordMap;
    Account::Account(const Date &date, const string &id):id(id),balance(0)
    {
        cout << date << "	#" << id << " created" << endl;
    }
    void Account::record(const Date &date, double amount, const string &desc)
    {
        amount = floor(amount * 100 + 0.5) / 100;      //保留小数点后两位
        balance += amount;
        total += amount;
        date.show();
        cout << "	#" << id << "	" << amount << "	" << balance << "	" << desc << endl;
    }
    void Account::show(ostream &out)const
    {
        out << id << "	Balance: " << balance;
    }
    void Account::error(const string &msg)const
    {
        throw AccountException(this, msg);
    }
    void Account::query(const Date &begin, const Date &end)
    {
        if (begin <= end)
        {
            RecordMap::iterator iter1 = recordMap.lower_bound(begin);
            RecordMap::iterator iter2 = recordMap.upper_bound(end);
            for (RecordMap::iterator iter = iter1;iter != iter2;++iter)
                iter->second.show();
        }
    }
    
    //CreditAccount类的实现
    CreditAccount::CreditAccount(const Date &date,const string &id,double credit,double rate,double fee):
    Account(date, id), credit(credit), rate(rate), fee(fee), acc(date, 0)
    {
    }
    void CreditAccount::deposit(const Date &date, double amount, const string &desc)
    {
        record(date, amount, desc);
        acc.change(date, getDebt());
    }
    void CreditAccount::withdraw(const Date &date, double amount, const string &desc)
    {
        if (amount - getBalance() > credit)
        {
            error("not enough credit");
        }
        else
        {
            record(date, -amount, desc);
            acc.change(date, getDebt());
        }
    }
    void CreditAccount::settle(const Date &date)
    {
        double interest = acc.getSum(date)*rate;
        if (interest != 0)
            record(date, interest, "interest");
        if (date.getMonth() == 1)
            record(date, -fee, "annual fee");
        acc.reset(date, getDebt());
    }
    void CreditAccount::show(ostream &out)const
    {
        Account::show(out);
        out << "	Available credit: " << getAvailableCredit();
    }
    
    //SavingAccount类的实现
    SavingAccount::SavingAccount(const Date &date, const string &id, double rate) :Account(date, id), rate(rate), acc(date, 0)
    {
    }
    void SavingAccount::deposit(const Date &date, double amount, const string &desc)
    {
        record(date, amount, desc);
        acc.change(date, getBalance());
    }
    void SavingAccount::withdraw(const Date &date, double amount, const string &desc)
    {
        if (amount > getBalance())
        {
            error("not enough money");
        }
        else
        {
            record(date, -amount, desc);
            acc.change(date, getBalance());
        }
    }
    void SavingAccount::settle(const Date &date)
    {
        if (date.getMonth() == 1)        //每年的1月计算一次利息
        {
            double interest = acc.getSum(date)*rate / (date - Date(date.getYear() - 1, 1, 1));
            if (interest != 0)
                record(date, interest, "interest");
            acc.reset(date, getBalance());
        }
    }

     6.主函数文件

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <algorithm>
    #include "account.h"
    using namespace std;
    
    struct deleter
    {
        template<class T>void operator()(T *p)
        {
            delete p;
        }
    };
    //控制器类,用来存储账户列表和处理命令
    class Controller
    {
    public:
        Controller(const Date &date) :date(date), end(false)
        {
        }
        ~Controller();
        const Date& getDate()const
        {
            return date;
        }
        bool isEnd()const
        {
            return end;
        }
        //执行一条命令,返回该命令是否改变了当前状态(即是否需要保存当前命令)
        bool runCommand(const string &cmdLine);
    private:
        Date date;
        vector<Account*> accounts;       //账户列表
        bool end;                        //用户是否输入了退出命令
    };
    Controller::~Controller()
    {
        for_each(accounts.begin(), accounts.end(), deleter());
    }
    bool Controller::runCommand(const string &cmdLine)
    {
        istringstream str(cmdLine);
        char cmd, type;
        int index, day;
        double amount, credit, rate, fee;
        string id, desc;
        Account* account;
        Date date1, date2;
        str >> cmd;
        switch (cmd)
        {
        case 'a':               //增加账户
            str >> type >> id;
            if (type == 's')
            {
                str >> rate;
                account = new SavingAccount(date, id, rate);
            }
            else
            {
                str >> credit >> rate >> fee;
                account = new CreditAccount(date, id, credit, rate, fee);
            }
            accounts.push_back(account);
            return true;
        case 'd':              //存入现金
            str >> index >> amount;
            getline(str, desc);
            accounts[index]->deposit(date, amount, desc);
            return true;
        case 'w':              //取出现金
            str >> index >> amount;
            getline(str, desc);
            accounts[index]->withdraw(date, amount, desc);
            return true;
        case 's':              //查询各账户信息
            for (size_t i = 0;i < accounts.size();++i)
            {
                cout << "[" << i << "]";
                accounts[i]->show(cout);
                cout << endl;
            }
            return false;
        case 'c':             //改变日期
            str >> day;
            if (day < date.getDay())
                cout << "You cannot specify a previous day";
            else if (day > date.getMaxDay())
                cout << "Invalid day";
            else
                date = Date(date.getYear(), date.getMonth(), day);
            return true;
        case 'n':               //进入下个月
            if (date.getMonth() == 12)
                date = Date(date.getYear() + 1, 1, 1);
            else
                date = Date(date.getYear(), date.getMonth() + 1, 1);
            for (vector<Account*>::iterator iter = accounts.begin();iter != accounts.end();++iter)
                (*iter)->settle(date);
            return true;
        case 'q':             //查询一段时间内的账目
            str >> date1 >> date2;
            Account::query(date1, date2);
            return false;
        case 'e':             //退出
            end = true;
            return false;
        }
        cout << "Invalid command: " << cmdLine << endl;
        return false;
    }
    int main()
    {
        Date date(2018, 1, 1);         //起始日期
        Controller controller(date);
        string cmdLine;
        const char *FILE_NAME = "commands.txt";
        ifstream fileIn(FILE_NAME);      //以读模式打开文件
        if (fileIn)                //如果正常打开,就执行文件中的每一条命令
        {
            while (getline(fileIn, cmdLine))
                controller.runCommand(cmdLine);
            fileIn.close();
        }
        ofstream fileOut(FILE_NAME, ios_base::app);        //以追加模式打开文件
        cout << "(a)add account  (d)deposit  (w)withdraw  (s)show  (c)change day  (n)next month  (q)query  (e)exit" << endl;
        while (!controller.isEnd())        //从标准输入读入命令并执行,直到退出
        {
            cout << controller.getDate() << "	Total: " << Account::getTotal() << "	command";
            string cmdLine;
            getline(cin, cmdLine);
            if (controller.runCommand(cmdLine))
                fileOut << cmdLine << endl;          //将命令写入文件
        }
        return 0;
    }

       最后运行主函数将程序功能实现,可以进行增加账户功能、存款功能、取款功能、查询账户信息功能、改变日期功

    进入下个月的处理功能将程序进行操作,最后附上一张我操作这些功能的截图。

           

  • 相关阅读:
    Ubuntu使用命令行打印文件
    Spring ConditionalOnProperty
    Spring EnableWebMvc vs WebMvcConfigurationSupport
    commons-httpclient中的超时设置
    jdb调试命令
    caching redirect views leads to memory leak (Spring 3.1)
    Clojure web初探
    在现有原生开发Android项目中集成hbuilder开发
    MessageBoard
    CSS布局(五) 圣杯布局
  • 原文地址:https://www.cnblogs.com/XNQC1314/p/9011891.html
Copyright © 2011-2022 走看看