1. 程式人生 > 實用技巧 >c++程式設計實踐——銀行系統

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 << "\tTotal: " << Account::getTotal() << "\tcommand> ";
        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 << "\tTotal: " << Account::getTotal() << "\tcommand> ";
        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;

}