ATM业务模拟系统功能要求
客户端:
定义用户数据对象,并以此为参数生成用户操作对象;
存款操作:生成一条新的业务信息(业务对象),追加到交易记录中,并修改账号余额;
取款操作:判断取款数是否超过账号余额,超过显示错误信息,不做任何操作。否则,生成一条新的业务信息(业务对象),追加到交易记录中,并修改账号余额;
业务查询:包括余额查询、存/取款业务查询和指定日期、时间段内业务查询;
退出:将用户信息、交易记录更新到数据文件。
管理端:
增加用户:添加新用户信息并初始化(注意不重复添加,要判重);
注销账号:对用户进行临时冻结;
激活账号:对冻结的账号解封;
查看业务信息(查看所有用户/指定用户信息、查看指定时间段业务交易情况(取款、存款、全部)
退出:将用户信息写入数据文件;
ATM类设计要求
数据类:数据成员及get/set函数,成员函数构造函数、必要的运算符重载(含数据合法性检测)
操作类:必要的数据成员、构造函数,实现功能的成员函数。要使用继承、多态机制
文件命名方式:与前面的作业相同。
说明:课程设计为计算机系acm教练费教授所布置,博主拿到了最高等级的评分,以下为提交作业文件夹,附源码,课程设计仅供学习参考,如若抄袭后果自负~
#include<bits/stdc++.h>
using namespace std;
//日期类
class Date
{
private:
int year;
int month;
int day;
public:
friend ostream& operator<<(ostream& out, Date& d);
friend istream& operator>>(istream& in, Date& d);
Date operator+(int n);
bool operator<(const Date& d) const;
Date(int year, int month, int day = 1);
Date();
int get_year();
int get_month();
int get_day();
};
int Date::get_year()
{
return year;
}
int Date::get_month()
{
return month;
}
int Date::get_day()
{
return day;
}
Date::Date()
{
year = 2022;
day = 1;
month = 1;
}
Date::Date(int year, int month, int day)
{
this->year = year;
this->month = month;
this->day = day;
}
Date Date::operator+(int n)
{
int cal[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
while (n)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
cal[2] = 29;
day++;
if (day > cal[month])
{
day = 1;
month++;
}
if (month > 12)
{
month = 1;
year++;
}
n--;
}
return *this;
}
bool Date::operator<(const Date& d) const
{
if (year != d.year) return year <= d.year;
else if (month != d.month) return month <= d.month;
else return day <= d.day;
}
ostream& operator<<(ostream& out, Date& d)
{
out << d.year << "/" << d.month << "/" << d.day;
return out;
}
istream& operator>>(istream& in, Date& d)
{
int cal[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int year, month, day;
char op;
in >> year >> op >> month >> op >> day;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
cal[2] = 29;
if (month < 1 || month > 12)
{
return in;
}
else if (day < 1 || day > cal[month])
{
return in;
}
else {
d.year = year;
d.month = month;
d.day = day;
}
return in;
}
//
class Account
{
private:
string account_id;//账号id
double account_money;//账号余额
string account_state;//账号状态
public:
friend ostream& operator<<(ostream& out, Account& account);
friend istream& operator>>(istream& in, Account& account);
Account(string account_id, double account_money, string account_state);
Account(){
}
void set_Account_id(string account_id);
void set_Account_money(double account_money);
void set_Account_state(string account_state);
string get_Account_id();
double get_Account_money();
string get_Account_state();
};
ostream& operator<<(ostream& out, Account& account)
{
out << account.account_id << " " << account.account_money << " " << account.account_state << endl;
return out;
}
istream& operator>>(istream& in, Account& account)
{
in >> account.account_id >> account.account_money >> account.account_state;
return in;
}
void Account::set_Account_id(string account_id)
{
this->account_id = account_id;
}
void Account::set_Account_money(double account_money)
{
this->account_money = account_money;
}
void Account::set_Account_state(string account_state)
{
this->account_state = account_state;
}
string Account::get_Account_id()
{
return account_id;
}
double Account::get_Account_money()
{
return account_money;
}
string Account::get_Account_state()
{
return account_state;
}
Account::Account(string account_id, double account_money, string account_state)
{
this->account_id = account_id;
this->account_money = account_money;
this->account_state = account_state;
}
//记录类
class Record
{
private:
Date record_date;//日期
string account_id;//账号id
double account_money;//余额
double operate_money;//操作金额
string business;//业务
public:
Record(Date record_date, string account_id, double account_money, double operate_money, string business);
Record() {
}
void set_Record_date(Date record_date);
void set_Account_id(string account_id);
void set_Account_money(double account_money);
void set_Operate_money(double operate_money);
void set_Business(string business);
Date get_Record_date();
string get_Account_id();
double get_Account_money();
double get_Operate_money();
string get_Business();
friend ostream& operator<<(ostream& out, Record& record);
friend istream& operator>>(istream& in, Record& record);
};
void Record::set_Record_date(Date record_date)
{
this->record_date = record_date;
}
void Record::set_Account_id(string account_id)
{
this->account_id = account_id;
}
void Record::set_Account_money(double account_money)
{
this->account_money = account_money;
}
void Record::set_Operate_money(double account_money)
{
this->operate_money = operate_money;
}
void Record::set_Business(string business)
{
this->business = business;
}
Date Record::get_Record_date()
{
return record_date;
}
string Record::get_Account_id()
{
return account_id;
}
double Record::get_Account_money()
{
return account_money;
}
double Record::get_Operate_money()
{
return operate_money;
}
string Record::get_Business()
{
return business;
}
Record::Record(Date record_date, string account_id, double account_money, double operate_money, string business)
{
this->record_date = record_date;
this->account_id = account_id;
this->account_money = account_money;
this->operate_money = operate_money;
this->business = business;
}
ostream& operator<<(ostream& out, Record& record)
{
out << record.record_date << " " << record.account_id << " " << record.account_money << " " << record.operate_money << " " << record.business << endl;
return out;
}
istream& operator>>(istream& in, Record& record)
{
in >> record.record_date >> record.account_id >> record.account_money >> record.operate_money >>record.business;
return in;
}
class Operate_Base
{
protected:
vector<Record> record;
multimap<Date, int> map_record_date;//记录日期
multimap<string, int> map_record_id;//记录账号
multimap<string, int> map_record_business;//记录业务
public:
Operate_Base(){
record_read();
};
~Operate_Base(){
record_write();
}
void record_add(Record& record1);
void record_write();
void record_read();
void renew_RecordMap();
void record_find_date(Date d1);
void record_find_date_range(Date d1, Date d2);
};
void Operate_Base::record_add(Record& record1)
{
record.push_back(record1);
map_record_id.insert(make_pair(record1.get_Account_id(), record.size() - 1));
map_record_date.insert(make_pair(record1.get_Record_date(), record.size() - 1));
map_record_business.insert(make_pair(record1.get_Business(), record.size() - 1));
}
void Operate_Base::record_read()
{
Record record1;
ifstream ifs("2020214380record.txt");
if (!ifs)
return;
while (ifs >> record1)
{
record.push_back(record1);
map_record_id.insert(make_pair(record1.get_Account_id(), record.size() - 1));
map_record_date.insert(make_pair(record1.get_Record_date(), record.size() - 1));
map_record_business.insert(make_pair(record1.get_Business(), record.size() - 1));
}
ifs.close();
}
void Operate_Base::record_write()
{
fstream ofs("2020214380record.txt");
vector<Record>::iterator it;
for (it = record.begin(); it != record.end(); it++)
{
ofs << *it;
}
ofs.close();
}
void Operate_Base::renew_RecordMap()
{
vector<Record>::iterator it;
map_record_id.clear();
map_record_date.clear();
map_record_business.clear();
int index = 0;
for (it = record.begin(); it < record.end(); it++)
{
index = it - record.begin();
map_record_id.insert(make_pair(it->get_Account_id(), index));
map_record_date.insert(make_pair(it->get_Record_date(), index));
map_record_business.insert(make_pair(it->get_Business(), index));
}
}
class Operate:public Operate_Base
{
private:
vector<Account> account;
multimap<string, int> map_account_id;//账号id
multimap<string, int> map_account_state;//账号状态
public:
Operate();
~Operate()
{
account_write();
record_write();
}
void account_read();
void account_write();
void account_add(Account & account);
void account_dongjie(Account & account);
void account_jiedong(Account & account);
void account_find();
void account_find(string account_id);
void account_find_state(string account_state);
void renew_AccountMap();
void record_find();
void record_find(string account_id);
void record_find_cunkuan();
void record_find_qukuan();
void record_find_date(Date d);
void record_find_date_range(Date d1, Date d2);
};
Operate::Operate()
{
account_read();
//record_read();
}
void Operate::account_read()
{
Account account1;
ifstream ifs("2020214380account.txt");
if (!ifs)
return;
while (ifs >> account1)
{
account.push_back(account1);
map_account_id.insert(make_pair(account1.get_Account_id(), account.size() - 1));
map_account_state.insert(make_pair(account1.get_Account_state(), account.size() - 1));
}
ifs.close();
}
void Operate::account_write()
{
fstream ofs("2020214380account.txt");
vector<Account>::iterator it;
for (it = account.begin(); it != account.end(); it++)
{
ofs << *it;
}
ofs.close();
}
void Operate::account_add(Account& account1)
{
string n = account1.get_Account_id();
multimap<string, int>::iterator it;
it = map_account_id.find(n);
if(it == map_account_id.end())
{
account.push_back(account1);
map_account_id.insert(make_pair(account1.get_Account_id(), account.size() - 1));
map_account_state.insert(make_pair(account1.get_Account_state(), account.size() - 1));
}
else
{
cout << "重复添加" << endl;
}
}
void Operate::account_dongjie(Account & account1)
{
string n = account1.get_Account_id();
int money = account1.get_Account_money();
Account account2(n, money, "冻结");
multimap<string, int>::iterator it;
it = map_account_id.find(n);
if(it == map_account_id.end())
{
return;
}
else{
int a = it->second;
account[a] = account2;
renew_AccountMap();
}
}
void Operate::account_jiedong(Account & account1)
{
string n = account1.get_Account_id();
int money = account1.get_Account_money();
Account account2(n, money, "正常");
multimap<string, int>::iterator it;
it = map_account_id.find(n);
if(it == map_account_id.end())
{
return;
}
else{
int a = it->second;
account[a] = account2;
renew_AccountMap();
}
}
void Operate::renew_AccountMap()
{
vector<Account>::iterator it;
map_account_id.clear();
map_account_state.clear();
int index = 0;
for (it = account.begin(); it < account.end(); it++)
{
index = it - account.begin();
map_account_id.insert(make_pair(it->get_Account_id(), index));
map_account_state.insert(make_pair(it->get_Account_state(), index));
}
}
void Operate::account_find(string n)
{
multimap<string, int>::iterator it;
it = map_account_id.find(n);
if (it == map_account_id.end())
{
return;
}
else
{
cout << account[it->second] << endl;
}
}
void Operate::account_find()
{
vector<Account>::iterator it;
for (it = account.begin(); it != account.end(); it++)
{
cout << *it << endl;
}
}
void Operate::record_find()
{
vector<Record>::iterator it;
for (it = record.begin(); it != record.end(); it++)
{
cout << *it << endl;
}
}
void Operate::record_find(string n)
{
multimap<string, int>::iterator it;
it = map_record_id.find(n);
if (it == map_record_id.end())
{
return;
}
else
{
cout << record[it->second] << endl;
}
}
void Operate::record_find_cunkuan()
{
auto ret = map_record_business.equal_range("存款");
multimap<string, int>::iterator itbegin = ret.first;
multimap<string, int>::iterator itend = ret.second;
if (itbegin != map_record_business.end())
{
multimap<string, int>::iterator it = itbegin;
do
{
cout << record[it->second] << endl;
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void Operate::record_find_qukuan()
{
auto ret = map_record_business.equal_range("取款");
multimap<string, int>::iterator itbegin = ret.first;
multimap<string, int>::iterator itend = ret.second;
if (itbegin != map_record_business.end())
{
multimap<string, int>::iterator it = itbegin;
do
{
cout << record[it->second] << endl;
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void Operate::record_find_date(Date d)
{
auto ret = map_record_date.equal_range(d);
multimap<Date, int>::iterator itbegin = ret.first;
multimap<Date, int>::iterator itend = ret.second;
if (itbegin != map_record_date.end())
{
multimap<Date, int>::iterator it = itbegin;
do
{
cout << record[it->second] << endl;
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void Operate::record_find_date_range(Date d1, Date d2)
{
multimap<Date, int>::iterator itbegin = map_record_date.upper_bound(d1);
multimap<Date, int>::iterator itend = map_record_date.lower_bound(d2);
if (itbegin == itend)
{
cout << "没找到" << endl;
}
else
{
for (multimap<Date, int>::iterator it = itbegin; it != itend; it++)
{
cout <<record[it->second];
}
}
}
class Operate_User: public Operate_Base
{
private:
Account account;
Date date_now;
public:
Operate_User();
~Operate_User(){
record_write();
};
Operate_User(Account account, Date date_now);
void user_cunkuan(double money);
void user_qukuan(double money);
void find_money();
void record_find_cunkuan();
void record_find_qukuan();
void record_find_date(Date d1);
void record_find_date_range(Date d1, Date d2);
};
Operate_User::Operate_User(Account account, Date date_now)
{
this->account = account;
this->date_now = date_now;
}
Operate_User::Operate_User()
{
//record_read();
}
void Operate_User::user_cunkuan(double money)
{
double money1 = account.get_Account_money() + money;
Record record1(date_now, account.get_Account_id(), money1, money, "存款");
record_add(record1);
}
void Operate_User::user_qukuan(double money)
{
if(account.get_Account_money() >= money)
{
double money1 = account.get_Account_money() - money;
Record record1(date_now, account.get_Account_id(), money1, money, "取款");
record_add(record1);
}
else
{
cout << "余额不足" << endl;
}
}
void Operate_User::find_money()
{
cout << account.get_Account_money() << endl;
}
void Operate_User::record_find_date(Date d)
{
auto ret = map_record_date.equal_range(d);
multimap<Date, int>::iterator itbegin = ret.first;
multimap<Date, int>::iterator itend = ret.second;
if (itbegin != map_record_date.end())
{
multimap<Date, int>::iterator it = itbegin;
do
{
if(record[it->second].get_Account_id() == account.get_Account_id())
{
cout << record[it->second] << endl;
}
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void Operate_User::record_find_date_range(Date d1, Date d2)
{
multimap<Date, int>::iterator itbegin = map_record_date.upper_bound(d1);
multimap<Date, int>::iterator itend = map_record_date.lower_bound(d2);
if (itbegin == itend)
{
cout << "没找到" << endl;
}
else
{
for (multimap<Date, int>::iterator it = itbegin; it != itend; it++)
{
if(record[it->second].get_Account_id() == account.get_Account_id())
{
cout <<record[it->second];
}
}
}
}
void Operate_User::record_find_cunkuan()
{
auto ret = map_record_business.equal_range("存款");
multimap<string, int>::iterator itbegin = ret.first;
multimap<string, int>::iterator itend = ret.second;
if (itbegin != map_record_business.end())
{
multimap<string, int>::iterator it = itbegin;
do
{
if(record[it->second].get_Account_id() == account.get_Account_id())
{
cout << record[it->second] << endl;
}
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void Operate_User::record_find_qukuan()
{
auto ret = map_record_business.equal_range("取款");
multimap<string, int>::iterator itbegin = ret.first;
multimap<string, int>::iterator itend = ret.second;
if (itbegin != map_record_business.end())
{
multimap<string, int>::iterator it = itbegin;
do
{
if(record[it->second].get_Account_id() == account.get_Account_id())
{
cout << record[it->second] << endl;
}
it++;
} while (it != itend);
}
else
{
cout << "未找到" << endl;
}
}
void testDate()
{
Date test1(2007, 4, 29);
cout << test1 << endl;
test1 = test1 + 365;
cout << test1 << endl;
cout << endl;
}
void testAccount()
{
Account account("1234567", 10000, "正常");
cout << account << endl;
}
void testRecord()
{
Date date1(2022, 1, 6);
Record record1(date1, "123456", 10000, 1000, "取款");
cout << record1 << endl;
}
void testOperate()
{
Operate op1;
Account account1("1234567", 10000, "正常");
//op1.account_add(account1);
Account account2("1234568", 10000, "正常");
Date date(2022, 1, 4);
Date date1(2022,1,8);
op1.account_add(account2);
//op1.account_dongjie(account1);
op1.account_jiedong(account1);
//op1.record_find();
//op1.record_find("1234567");
//op1.record_find_date(date1);
//op1.record_find_date_range(date, date1);
//op1.record_find_cunkuan();
//op1.record_find_qukuan();
}
void testOperate_User()
{
Account account1("1234567", 10000, "正常");
Date date1(2022, 1, 4);
Date date2(2022, 2, 5);
Operate_User op_user1(account1, date1);
//op_user1.find_money();
//op_user1.user_cunkuan(100);
op_user1.user_qukuan(200);
//op_user1.user_qukuan(20000);
//op_user1.user_cunkuan(2000);
//op_user1.user_cunkuan(5000);
//op_user1.user_qukuan(1000);
//op_user1.user_qukuan(2000);
//op_user1.record_find_cunkuan();
//op_user1.record_find_qukuan();
//op_user1.record_find_date(date2);
//op_user1.record_find_date_range(date1, date2);
}
int main()
{
//testDate();
//testAccount();
//testRecord();
testOperate();
testOperate_User();
return 0;
}
一、设计问题解决思路与系统功能规划
针对ATM设计系统,我们做如下分析:
1.数据类:
1.1日期类
含有年、月、日,构造函数,必要的各种重载运算符。
1.2账号类
账号id、账号余额、账号状态(正常/冻结),构造函数、必要的各种重载运算符。
1.3记录类
日期、账号id、余额、操作金额、业务(存款/取款),构造函数,必要的各种重载运算符。
2.操作类
2.1操作基类
借阅记录向量、记录日期、记录账号、记录业务,增加记录、记录文件读写、按日期查找、按日期范围查找。
2.2客户端操作类
账号向量、账号id、账号状态、账号文件读写、账号添加、账号冻结、账号解冻、查找所有账号、按照账号id查找账号、按照账号状态查找账号。
2.3管理端操作类
账号用户、当前日期、存款、取款、按日期查找记录、按日期时间段查找记录
二、具体实现
日期类:
以下为日期类重载加号运算符
以下为日期类重载小于号运算符
以下为重载输入运算符,重载输入运算符是进行合法性检验
以下为重载输出运算符
账号类:
记录类:
操作类基类
管理端操作类
客户端操作类:
三、运行调试与分析讨论
1.测试日期类:
测试日期类时候,特意从2007年4月份+365天,因为跨过了闰年2008年,以此来证明日期类的正确性,这也是为什么不是2008年4月29日的原因
2.测试账号类
添加一个账号来测试账号类,账号id为1234567,账号余额为10000,账号状态为正常。
3.测试记录类
测试记录类,可以发现运行无误准确。
4.测试管理端操作类
添加两个用户
此类为文件操作,我们可以再文件中查看信息:
添加数据一致
当再次运行程序时,我们可以发现数据重复
将account1的账号冻结
将account1的账号解冻
查询所有记录
查询指定用户的所有记录
查询指定错误日期的记录
查询指定日期时间段的记录
查询所有存款的记录
查询所有取款的记录
5.测试客户端操作类
查询账号余额
用户存款
用户取款
给出非法数据
查找自己的存款记录
查找自己的取款记录
查询不存在日期的记录
查询指定日期段的记录
四、设计体会与小结
通过这次课程设计,利用ATM的实现方式来进行课程设计,我巩固了文件读写、重载运算符、继承、多态等C++面向对象编程的重要知识,通过本学期对图书管理系统的不断改进与优化,加上费老师的亲自教导,我对面向对象编程更加熟悉了,不过在此次课程设计中仍有许多小问题,最初在自己设计类的时候就遇到了麻烦,究竟设计几个类,每个类究竟有那些成员以及哪些成员函数,在进一步分析的过程中,我逐渐理解了本次ATM系统的各个类,很快便将他们写了下来并调试通过,其次,我觉得难点还是在操作类上,刚开始想不清楚每个函数应该具体去做什么,例如最初我在管理端增加了添加记录这个函数,但是当我写到客户端的时候我就发现了问题,添加记录这个函数是应在管理员实现吗?管理员有权限来给用户进行存款、取款操作吗,这显然是荒谬的,只有每个账户的拥有者才会对自己的钱进行合法操作,管理员可以查看我们的操作,并且如果短时间内出现金钱大量转出情况,管理员是可以对我们的账号进行注销的,所以我很快就找到了问题,每当用户进行一次操作的时候,我就在记录文件里增加一条记录,问题就解决了。在本次课程设计中,由于经过了之前图书管理系统的训练,这次我的思路明显清晰了,我很明白每个类的职责,以及如何写出优美的代码供其他程序员同学学习,这其实是很重要的,因为如果代码只有自己能看懂,那这在以后的团队中绝对不是优秀的代码。当然此次课程设计也暴露出了很多问题,对STL的内置函数存在记忆模糊现象,这是由于对知识点的遗忘,只有日后经常练习,才能真正掌握C++的本领,才能掌握面向对象编程的本领。最后,感谢费老师对我们每个人的悉心教导。
声明:设计报告中包含大量图片,为了防止部分同学直接抄袭,故不在这里放出了,如有同学们学习需要,可以联系博主~