c++程序设计实践——银行系统

银行系统

 

本科大二程序设计实践的作业,算是一个比较简单的项目吧,主要使用的编程范式有面向对象编程

其中引入<multimap><map>头文件实现多映射输出存取记录

引入<fstream>实现文件的读取和写入,进而添加每次打开后能够观察前面的存取记录功能。

中间有很多使用了特例的地方,可以作为简单的参考,但是不能完全解决所有问题

一、测试样例

comman.txt

a s S3755217 0.015
a s 02342342 0.015
a c C5392394 10000 0.0005 50
c 5
d 0 5000 salary
c 15
w 2 2000 buy a cell
c 25
d 1 10000 sell stock 0323
n
d 2 2016 repay the credit
c 5
d 0 5500 salary
n
c 15
w 2 1500 buy a television

输出结果

二、代码部分

date.h

#pragma once
//date.h
#include <iostream>
//using namespace std::rel_ops;
using namespace std;
class Date
{
public:
    Date() = default;
    Date(int, int, int);                    //利用构造函数完成初始化
    ~Date();                                //析构
    bool operator < (const Date& date) const {
        if (year > date.year) {
            return 0;
        }
        else if (year < date.year) {
            return 1;
        }
        else if (year == date.year) {
            if (month > date.month) {
                return 0;
            }
            else if (month < date.month) {
                return 1;
            }
            else if (month == date.month) {
                if (day > date.day) {
                    return 0;
                }
                else if (day < date.day) {
                    return 1;
                }
                else
                    return 0;
            }


        }
    
    }




    //Date(int, int, int);
    //int deltadate;
    bool Isleapyear(int);                                //是否是闰年
    int DayInYear(int, int, int);                        //这一天是这一年的那一天
    int datebetween(int, int, int, int, int, int);            //两个日期之间的距离
    void showdate();

    static Date read(char*);

    int getDay();
    int getMonth();
    int getYear();
    int getMaxDay();

    int year = 0;
    int month = 0;
    int day = 0;

private:


};
#pragma once
    

accounnt.h

#pragma once
//account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include "date.h"
#include <iostream>
#include <utility>
#include <map>
using namespace std;
extern double total;
class Accumulator :public Date                                    //accumulator 类
{
public:
    Accumulator() = default;
    Accumulator(Date, double);
    ~Accumulator();
    double getsum(Date);
    void change(Date, double);
    Date lastdate;
    double sum;
    double value;
private:

};
class AccountRecord
{
public:
    Date date;
//    const Account* account;
    string id;
    double amount;
    double balance;
    string desc;
    //std::multimap
    void show();
    AccountRecord(Date, string,double,double);
    AccountRecord();
    ~AccountRecord();
private:
};
extern multimap<Date, AccountRecord> recordmap;
class Account :public Accumulator , AccountRecord                    //基类
{
public:

    string id;                                        //账号
    double balance;                                        //余额
    double rate;                                        //利率
    double accumulation;                                //余额之和
    static double  getTotal();                                        //总余额
    static double total;                                            //总余额函数
    
    static void query(Date,Date) ;
    static multimap<Date,AccountRecord> recordmap;
    virtual void show();

    virtual void deposit(Date, double, string) = 0;
    virtual void withdraw(Date, double,string) = 0;
    virtual void settle(Date)=0;
    

    Account();
    Account(Date, const string);
    ~Account();
    void record(Date, double);                                    //record函数,记录当前余额
    double accumulate(int deltadate) const {
        return accumulation + balance * (deltadate);
    }
private:
};

class SavingsAccount :public Account
{
public:
    SavingsAccount();                                        //默认构造函数
    SavingsAccount(Date, string, double);                //构造函数   日期、id、余额
    ~SavingsAccount();                                        //析构函数
    //void getId(const char*);
    //void getRate(double);
    void show();                                                //显示账户信息
    void deposit(Date, double, string);                    //存款
    void withdraw(Date, double,string);                    //取款
    void settle(Date);                                        //结算利息
private:
    Accumulator acc;
};
class CreditAccount :public Account
{
public:
    CreditAccount();
    CreditAccount(Date, string, double, double, double);                    //构造函数
    ~CreditAccount();                                                        //析构函数
    void  deposit(Date, double, string);                                //存钱
    void withdraw(Date, double, string);                                //取钱
    void settle(Date);
    void show();                                                //显示账户信息
private:
    //Accumulator acc;
    double credit;
    double fee;
    Accumulator acc;
};



#endif 

account.cpp

#include <cmath>
#include <utility>
#include <iostream>
#include <map>
#include <cctype>  
#include "account.h"
using namespace std;
//using namespace std::rel_ops;
using std::string;
double Account::total;
multimap<Date, AccountRecord>  Account::recordmap;

AccountRecord::AccountRecord() {

}


Account::Account(Date tempdate, string Id) :Accumulator()                        //构造函数
{

    AccountRecord r1(tempdate, Id,amount,balance);
    lastdate = tempdate;
    id = Id;
    accumulation = 0;
    balance = 0;
}
Account::~Account()
{
}


Accumulator::Accumulator(Date tempdate, double Value) :Date(tempdate)
{
    sum = 0;
    value = Value;
    lastdate = tempdate;
}
Accumulator::~Accumulator()
{
}
void Accumulator::change(Date, double) {

}
double Accumulator::getsum(Date tempdate) {
    int deltadate = datebetween(lastdate.year, lastdate.month, lastdate.day, tempdate.year, tempdate.month, tempdate.day);
    return sum + value * deltadate;
}

SavingsAccount::SavingsAccount(Date tempdate, string Id, double Rate) :Account(tempdate, Id)        //P290
{
    acc.sum = 0;
    id = Id;
    rate = Rate;
    tempdate.showdate();
    acc.lastdate = tempdate;
    cout << "    #" << Id << " created" << endl;
}
SavingsAccount::~SavingsAccount()
{
}/*
void SavingsAccount::getId(const char* p ) {
    id = p;
}
void SavingsAccount::getRate(double Rate) {
    rate = Rate;

}*/
void Account::show() {

}
void Account::settle(Date date) {

}


CreditAccount::CreditAccount(Date tempdate, string Id, double Credit, double Rate, double Fee) :Account(tempdate, Id)
{
    acc.sum = 0;
    balance = 0;
    value = 0;
    id = Id;
    rate = Rate;
    credit = Credit;
    fee = Fee;
    tempdate.showdate();
    acc.lastdate = tempdate;
    cout << "    #" << Id << " created" << endl;
}
CreditAccount::~CreditAccount()
{
}


void SavingsAccount::show() {
    cout << id << "    Balance: " << balance;
}
//show函数定义
void CreditAccount::show() {                                            //显示账户信息
    cout << id << "    Balance: " << balance << "    Avaliable credit:" << credit + balance;

}
//show函数定义

void Account::deposit(Date, double, string) {

}//实现虚函数的多态
void Account::withdraw(Date, double, string) {

}
    //实现虚函数的多态



void SavingsAccount::deposit(Date tempdate, double Amount, string desc) {
    acc.value = balance;
    acc.sum = acc.getsum(tempdate);
    record(tempdate, Amount);
    cout << "    " <<desc << endl;
    acc.lastdate = tempdate;                    //acc的lastdate成员,更新,用于计算每次的sum


    total = total + balance;
}
//deposit函数定义
void  CreditAccount::deposit(Date tempdate, double Amount, string desc) {
    acc.value = balance;
    acc.sum=acc.getsum(tempdate);
    record(tempdate, Amount);
    cout << "    " << desc << endl;
    acc.lastdate = tempdate;                    //acc的lastdate成员,更新,用于计算每次的sum

    total = total + balance;
}
//deposit函数定义


    void SavingsAccount::withdraw(Date tempdate, double Amount, string desc) {

    if (Amount > balance) {
        cout << "Error:not enough money" << endl;
    }
    else {
        record(tempdate, -Amount);
        cout << "    " << desc << endl;
        acc.lastdate = tempdate;                    //acc的lastdate成员,更新,用于计算每次的sum
        total = total - Amount;
    }
}
//withdraw函数定义
void CreditAccount::withdraw(Date tempdate, double Amount, string desc) {

    if (Amount > credit) {
        cout << "Error:not enough money" << endl;
    }
    else {
        record(tempdate, -Amount);                                                //record函数
        cout << "    " << desc << endl;
    
        sum=acc.getsum(tempdate);
        value = balance;
        acc.lastdate = tempdate;

        total = total - Amount;
    }
}
//withdraw函数定义


double Account::getTotal() {
    return total;
}
//getTotal 函数定义



void SavingsAccount::settle(Date tempdate) {
    if (balance == 0) {

    }
    else if  (tempdate.year - lastdate.year >= 1) {
        acc.value = balance;
        acc.sum = acc.getsum(tempdate);
        double interest = acc.sum * rate / 366;
        interest = floor(interest * 100 + 0.5) / 100;                //四舍五入
        //int deltadate = datebetween(lastdate.year, lastdate.month, lastdate.day, tempdate.year, tempdate.month, tempdate.day);
        //double interest = accumulate(deltadate) * rate / 366;
        record(tempdate, interest);
        cout << " interest" << endl;
        acc.sum = 0;
        total = total + interest;
        acc.lastdate = tempdate;
    }
}
//计算利息函数
void CreditAccount::settle(Date tempdate) {

    if (tempdate.year - lastdate.year >= 1) {
        acc.value = balance;
        acc.sum = acc.getsum(tempdate);
        double interest = acc.sum * rate;
        interest = floor(interest * 100 + 0.5) / 100;
        //int deltadate = datebetween(lastdate.year, lastdate.month, lastdate.day, tempdate.year, tempdate.month, tempdate.day);
        /*interest = Accumulator(tempdate, rate);*/
        record(tempdate, interest);
        cout << " interest" << endl;
        accumulation = 0;
        //total = total + balance;
        record(tempdate, -fee);
        cout << " annual fee" << endl;
        total = total -fee ;
        acc.sum = 0;
        acc.lastdate = tempdate;
    }
    else {

        acc.value = balance;
        acc.sum = acc.getsum(tempdate);
        double interest = acc.sum * rate;
        interest = floor(interest * 100 + 0.5) / 100;
        //int deltadate = datebetween(lastdate.year, lastdate.month, lastdate.day, tempdate.year, tempdate.month, tempdate.day);
        /*interest = Accumulator(tempdate, rate);*/
        record(tempdate, interest);
        cout << " interest" << endl;
        accumulation = 0;
        //total = total + balance;
        total = total + interest;
        acc.sum = 0;
        acc.lastdate = tempdate;
    }


}


void Account::record(Date tempdate, double Amount) {

    //sum = getsum(tempdate,Amount);
    //    
    //accumulation = accumulate(deltadate);
    //Amount = floor(Amount * 100 + 0.5) / 100;                                        //四舍五入取整
    balance = balance + Amount;
    tempdate.showdate();
    cout << "    " << "#" << id << "    " << Amount << "    " << balance;//打印
    AccountRecord r1(tempdate,id,Amount,balance);

    
    recordmap.insert(make_pair(tempdate, r1));

}



void Account::query(Date date1, Date date2) {
    
    auto iter = recordmap.lower_bound(date1);
    auto end = recordmap.upper_bound(date2);
    while (iter != end) {
        auto pr = recordmap.equal_range(iter->first);
        for (iter; iter != end; ++iter)
            iter->second.show();
    }


}
void AccountRecord::show() {
    date.showdate();
    cout << "    #" << id << "    " << amount << "    " << balance<<endl;
}

AccountRecord::AccountRecord(Date tdate, string Id,double tamount,double tbalance)
{
    amount = tamount;
    balance = tbalance;
    id = Id;
    date = tdate;
}

AccountRecord::~AccountRecord()
{
}

main.cpp

//step5.cpp
#include "account.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

struct deleter {

    template <class T> void operator () (T* p) { delete p; }

};


int main() {
    Date date(2008, 11, 1);//起始日期
    vector<Account*> accounts;//创建账户数组,元素个数为0


    fstream icin;
    icin.open("commands.txt");

    char temp[100] = {0};
    char cmd;
    do {
        
        int cun[10] = {0};                            //储存desc说明的位置,然后就可以直接输出
        icin.getline(temp,100);                //读取文件内的一行

        int i = 0;
        int j = 0;
        char x[100][100] = {0};
        for (int t = 0; t < 100; t++) {
            cun[i] = t;
            x[i][j] = temp[t];
            j++;
            if (temp[t] == ' ') {
                
                i++;
                j = 0;
                continue;
                
            }
            
        }


        //显示日期和总金额
        //date.showdate();
        //std::cout << "	Total: " << Account::getTotal() << "	command> ";
        char type;
        int index, day;
        double amount, credit, rate, fee;
        string id,desc;
        Account* account;
        Date date1, date2;


        string s = temp;
        

        cmd = x[0][0];
        switch (cmd) {



        case 'a'://增加账户
            type = x[1][0];

            if (type == 's') {
                id = x[2];
                rate = strtod(x[3],NULL);
                //rate = x[3];
                //cout << cmd << " " << type << " " << id << " " << rate << endl;
                account = new SavingsAccount(date, id, rate);

            }

            else {
                id = x[2];
                
                credit = strtod(x[3], NULL);
                rate = strtod(x[4], NULL);
                fee = strtod(x[5], NULL);

                //cout << cmd << " " << type << " " << id << " " << credit<<" "<<fee<<endl;
                account = new CreditAccount(date, id, credit, rate, fee);

            }

            accounts.push_back(account);

            break;

        case 'd'://存入现金
            index = atoi(x[1]);
            amount = strtod(x[2], NULL);
            desc = s.substr(cun[2],30); //s.substr(m,n) 意思是取字bai符串dus中位置m处开始,zhi长为n的子串dao
            //cout << cmd << " " << index << " " << amount << " " << desc << endl;
            //getline(cin, desc);
            
            accounts[index]->deposit(date, amount, desc);
            
            break;

        case 'w'://取出现金

            index = atoi(x[1]);
            amount = strtod(x[2], NULL);
            //getline(cin, desc);
            desc = s.substr(cun[2], 30); //s.substr(m,n) 意思是取字bai符串dus中位置m处开始,zhi长为n的子串dao
            //cout << cmd << " " << index << " " << amount << " " << desc << endl;
            accounts[index]->withdraw(date, amount, desc);
        
            break;

        case 's'://查询各账户信息

            for (size_t i = 0; i < accounts.size(); i++) {

                cout << "[" << i << "] ";

                accounts[i]->show();

                cout << endl;

            }
            break;

        case 'c'://改变日期
            day = atoi(x[1]);
            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);
                //cout << cmd << " "<<day<< endl;
            break;

        case 'n'://进入下个月
            //cout << cmd << endl;
            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);
            break;
    //    case 'q'://查询一段时间内的账目

    //        char p1[200];
    //        cin >> p1;
    //        char p2[200];
    //        cin >> p2;
    //        date1 = Date::read(p1);
    //        date2 = Date::read(p2);
    //        Account::query(date1, date2);
    //        OutFile << p1 << " " << p2 << endl;
    //        break;

        }
    } while (cmd != 'e');

    std::cout << "(a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit" << endl;
    icin.seekg(0, ios::end);
    icin << endl;

    do {
        //显示日期和总金额
        date.showdate();
        std::cout << "	Total: " << Account::getTotal() << "	command> ";
        char type;
        int index, day;
        double amount, credit, rate, fee;
        string id, desc;
        Account* account;
        Date date1, date2;
        std::cin >> cmd;
        icin << cmd<<" ";
        switch (cmd) {
        case 'a'://增加账户
            std::cin >> type >> id;
            if (type == 's') {
            
                std::cin >> rate;
                icin << 's' << " "<<id<<" "<<rate<<endl;
                account = new SavingsAccount(date, id, rate);
            }
            else {
                std::cin >> credit >> rate >> fee;
                icin << 'c' << " "<<id<<" "<<credit<<" "<<rate<<" "<<fee<<endl;
                account = new CreditAccount(date, id, credit, rate, fee);
            }
            accounts.push_back(account);
            break;
        case 'd'://存入现金
            std::cin >> index >> amount;
            desc = "";
            accounts[index]->deposit(date, amount, desc);
            icin << index << " " << amount << " " << desc << endl;
            break;
        case 'w'://取出现金
            std::cin >> index >> amount;
            desc = "";
            accounts[index]->withdraw(date, amount, desc);
            icin << index << " " << amount << " " << desc << endl;
            break;
        case 's'://查询各账户信息
            for (size_t i = 0; i < accounts.size(); i++) {
                std::cout << "[" << i << "] ";
                accounts[i]->show();
                std::cout << endl;
            }
            icin << endl;
            break;
        case 'c'://改变日期
            std::cin >> day;
            if (day < date.getDay())
                std::cout << "You cannot specify a previous day";
            else if (day > date.getMaxDay())
                std::cout << "Invalid day";
            else
                date = Date(date.getYear(), date.getMonth(), day);
            icin <<day<< endl;
            break;
        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);
            break;
        case 'q'://查询一段时间内的账目
            char p1[200];
            std::cin >> p1;
            char p2[200];
            std::cin >> p2;
            date1 = Date::read(p1);
            date2 = Date::read(p2);
            Account::query(date1, date2);
            icin << p1<<" " <<p2 << endl;
            break;
        }
    } while (cmd != 'e');
    for_each(accounts.begin(), accounts.end(), deleter());

    icin.close();
    return 0;

}

date.cpp

#include <iostream>
#include "date.h"


Date::Date(int y, int m, int d)                //利用构造函数完成初始化
{
    year = y;
    month = m;
    day = d;

}
Date::~Date()
{
}
bool Date::Isleapyear(int year) {                            //计算是不是闰年
    return (year % 4 == 0 || year % 400 == 0) && (year % 100 != 0);

}
int Date::DayInYear(int year, int month, int day)                //这一年的第几天
{
    //int _day = 0;
    int DAY[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    if (Isleapyear(year))
        DAY[1] = 29;
    for (int i = 0; i < month - 1; ++i)
    {
        day += DAY[i];
    }
    return day;
}
int Date::datebetween(int year1, int month1, int day1, int year2, int month2, int day2) {




    if (year1 == year2 && month1 == month2) {
        return day2 - day1;
    }
    //如果年份月份相同
    else if (year1 == year2) {
        int d1, d2;
        d1 = DayInYear(year1, month1, day1);
        d2 = DayInYear(year2, month2, day2);
        return d1 > d2 ? d1 - d2 : d2 - d1;

    }
    //如果年份相同
    else {
        //确保year1年份比year2早
        if (year1 > year2)
        {
            //swap进行两个值的交换
            swap(year1, year2);
            swap(month1, month2);
            swap(day1, day2);
        }
        int d1, d2, d3;
        if (Isleapyear(year1))
            d1 = 366 - DayInYear(year1, month1, day1); //取得这个日期在该年还于下多少天
        else
            d1 = 365 - DayInYear(year1, month1, day1);
        d2 = DayInYear(year2, month2, day2); //取得在当年中的第几天

        d3 = 0;
        for (int year = year1 + 1; year < year2; year++)
        {
            if (Isleapyear(year))
                d3 += 366;
            else
                d3 += 365;
        }
        return d1 + d2 + d3;

    }
    //都不相同情况 亲一部分+后一部分



}
void Date::showdate(void) {
    cout << year << "-" << month << "-" << day;

}




int Date::getDay() {
    return day;
}
int Date::getMonth() {
    return month;
}

int Date::getYear() {
    return year;
}
int Date::getMaxDay() {
    int DAY[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    if (Isleapyear(year))
        DAY[1] = 29;

    int MaxDay = DAY[month-1];


    return MaxDay;
}



Date Date::read(char*p) {
    Date date;
    int year=0;
    int month=0;
    int day=0;
    int exp = 1000;


    for (int i = 0; i < 4; i++) {
        int temp = p[i] - 48;
        year += temp*exp;
        exp = exp / 10;
    }

    exp = 10;

    for (int i = 5; i < 7;i++) {
        int temp = p[i] -48;
        month +=temp * exp;
        exp = exp / 10;
    }
    for (int i = 8; i < 9; i++) {
        day = p[i]-48;
    }
    date.year = year;
    date.month = month;
    date.day = day;


        return date;

}

 

原文地址:https://www.cnblogs.com/implus/p/13810834.html