重庆大学C++projectATM模拟程序的设计
//account.cpp
#pragma once
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
#define original_password "050429"
#define original_balance "10000"
class account
{
public:
void save();//保存数据
int getFLAG();//返回冻结情况
void showWelcome();//展示欢迎词
void setID();//输入账户,如果账户不存在就创建一个
void showMenu();//展示菜单
bool isPassword();//判断密码是否正确
void seeBalance();//1-查余额
void addCash();//2-存钱
void takeCash();//3-取钱
void tranPassword();//4-改密码
void transfer();//5-转账
private:
string ID;
string name;
string ID_card;
string balance= original_balance;
string password= original_password;
string MAX_day_tCash="0";
string FLAG = "1";//账户冻结
};
//account.cpp
#include "account.h"
#define MAX_day_takeCASH 500000
#define MAX_single_takeCASH 100000
#define Number_of_account 19
#define Number_of_ID_card 18
#define MIN_multiple_CASH 100
#define Number_of_password 6
//保存
void account::save()
{
string temp = ID + ".txt";
ofstream ofs(temp);
ofs << "账号:" << ID << endl;
ofs << "姓名:" << name << endl;
ofs << "身份证:" << ID_card << endl;
ofs << "密码:" << password << endl;
ofs << "余额:" << balance << endl;
ofs << "单日取款金额:" << MAX_day_tCash << endl;
ofs << "账号冻结情况:" << FLAG << endl;
ofs.close();
}
//返回冻结情况
int account::getFLAG()
{
return atoi(FLAG.c_str());
}
//展示欢迎词
void account::showWelcome()
{
cout << "********************************" << endl;
cout << "*** " << "欢迎使用ATM自助服务" << " ***" << endl;
cout << "*** " << "请输入卡号插卡!" << " ***" << endl;
cout << "********************************" << endl;
cout << "*** 若您输入一个不存在的卡号 ***" << endl;
cout << "*** 将为您自动开户 ***" << endl;
cout << "*** 开户后,初始密码为050429 ***" << endl;
cout << "********************************" << endl;
}
//输入账号
void account::setID()
{
string number;
bool flag = true;
while (flag)
{
cin >> number;
if (number.size() == Number_of_account)
{
flag = false;
for (int i = 0; i < number.size(); i++)
{
if (number[i] < '0' || number[i] > '9')
{
flag = true;//如果账户有误,返回true重新进入循环输入卡号
}
}
}
if (flag)
{
cout << "你输入的卡号有误,请重新输入" << endl;
}
}
ID = number;
ifstream ifs;
ifs.open(ID + ".txt", ios::in);
if (!ifs.is_open())
{
//打开失败,创建新账户并保存
cout << "自动开户中..." << endl;
cout << "请输入你的姓名" << endl;
string name;
cin >> name;
this->name = name;
cout << "请输入你的身份证" << endl;
string ID_card;
while (true)
{
cin >> ID_card;
if (ID_card.size() == Number_of_ID_card)
{
break;
}
cout << "身份证输入格式错误,请重新输入" << endl;
}
this->ID_card = ID_card;
cout << "开户成功!" << endl;
system("pause");
system("cls");
save();//
}
else
{
//打开文件成功,读取文件信息
string str[7];
for (int i = 0; i < 8; i++)
{
ifs >> str[i];
}
ID = str[0].substr(6);
name = str[1].substr(6);
ID_card = str[2].substr(8);
password = str[3].substr(6);
balance = str[4].substr(6);
MAX_day_tCash = str[5].substr(14);
FLAG = str[6].substr(14,1);
}
ifs.close();
}
//展示菜单
void account::showMenu()
{
cout << "*******************************" << endl;
cout << "*** 登陆成功! ***" << endl;
cout << "*** 1-余额查询 ***" << endl;
cout << "*** 2-存入现金 ***" << endl;
cout << "*** 3-提取现金 ***" << endl;
cout << "*** 4-现金转账 ***" << endl;
cout << "*** 5-修改密码 ***" << endl;
cout << "*** 6-退卡 ***" << endl;
cout << "*** 请以数字输入你的选择 ***" << endl;
cout << "*******************************" << endl;
}
//判断密码
bool account::isPassword()
{
cout << "请输入您的现密码: " << endl;
string n;
cin >> n;
string p = password;
if (n == p)
{
system("pause");
system("cls");
return true;
}
else
{
cout << "密码错误!您还有2次输入机会,请重新开始!" << endl;
cin >> n;
if (n == p)
{
system("pause");
system("cls");
return true;
}
else
{
cout << "密码错误!您还有1次输入机会,请重新开始!" << endl;
cin >> n;
if (n == p)
{
system("pause");
system("cls");
return true;
}
else
{
cout << "输入密码错误三次,您的账号已冻结" << endl;
FLAG = "0";//对帐户进行冻结
save();
system("pause");
system("cls");
return false;
}
}
}
system("pause");
system("cls");
}
//1-查询余额
void account::seeBalance()
{
cout << "您的余额为: " << balance << endl;
system("pause");
system("cls");
}
//2-存钱
void account::addCash()
{
cout << "请输入你要存入的数额,或按0返回主菜单" << endl;
long long n;
long long b = atoi(balance.c_str());
bool flag = true;
while (flag)
{
cin >> n;
if (n == 0)
{
cout << "返回成功" << endl;
system("pause");
system("cls");
return;
}
if (n < 0)
{
cout << "存入金额为负,存款失败" << endl;
system("pause");
system("cls");
return;
}
if (true)
{
b += n;
balance =to_string(b);
save();
system("pause");
system("cls");
return;
}
cout << "你输入的金额错误,请重新输入" << endl;
}
}
//3-取钱
void account::takeCash()
{
long long t = atoi(MAX_day_tCash.c_str());
cout << "请输入你要取款的数额("
<<MIN_multiple_CASH<<"的倍数且不超过"
<< MAX_single_takeCASH<<" ,单日取款不超过"
<<MAX_day_takeCASH<<"),或按0返回主菜单" << endl;
cout << "您今日已取款: " << t << endl;
long long n;
long long b = atoi(balance.c_str());
bool flag = true;
while (flag)
{
cin >> n;
if (n < 0)
{
cout << "你输入的金额错误,取款失败" << endl;
system("pause");
system("cls");
return;
}
if (n == 0)
{
cout << "返回成功" << endl;
system("pause");
system("cls");
return;
}
if (b >= n)
{
if (n % 100 == 0 && n <= MAX_single_takeCASH && t <= MAX_day_takeCASH)
{
b -= n;
t += n;
balance = to_string(b);
MAX_day_tCash = to_string(t);
cout << "取款成功!" << endl;
save();//保存
system("pause");
system("cls");
return;
}
cout << "你输入的金额错误,请重新输入" << endl;
}
else
{
cout << "您的余额不足qwq,请重新输入!" << endl;
}
}
}
//4-改密码
void account::tranPassword()
{
if (isPassword())
{
string s1, s2;
while (true)
{
while (true)
{
cout << "请输入修改后的密码 " << endl;
cin >> s1;
if (s1.size() == Number_of_password)
{
break;
}
cout << "密码格式错误" << endl;
}
cout << "请确认修改后的密码 " << endl;
cin >> s2;
if (s1 == s2)
{
password = s1;
cout << "密码修改成功!" << endl;
save();
system("pause");
system("cls");
return;
}
else
{
cout << "密码修改失败" << endl;
}
}
}
}
//5-转账
void account::transfer()
{
string number1,number2;
bool flag1 = true;
bool flag2 = true;
while (true)
{
flag1 = true;
flag2 = true;
cout << "请输入你要转入的账户(或按0返回主菜单): " << endl;
//判断第一次输入账户格式的正确性
while (flag1)
{
cin >> number1;
if (number1 == "0")
{
system("pause");
system("cls");
return;
}
if (number1.size() == Number_of_account)
{
flag1 = false;
for (int i = 0; i < number1.size(); i++)
{
if (number1[i] < '0' || number1[i] > '9')
{
flag1 = true;
}
}
}
if (flag1)
{
cout << "你输入的卡号有误,请重新输入" << endl;
}
}
cout << "请再次输入该账户以确认" << endl;
//判断第二次输入账户格式的正确性
while (flag2)
{
cin >> number2;
if (number2.size() == Number_of_account)
{
flag2 = false;
for (int i = 0; i < number2.size(); i++)
{
if (number2[i] < '0' || number2[i] > '9')
{
flag2 = true;
}
}
}
if (flag2)
{
cout << "你输入的卡号有误,请重新输入" << endl;
}
}
if (number1 == number2)
{
ifstream ifs;
ifs.open(number1 + ".txt", ios::in);
if (!ifs.is_open())
{
cout << "该账户不存在,请重新输入" << endl;
continue;
}
else if (number1 == ID)
{
cout << "您输入的是自己的原账户,请重新输入" << endl;
continue;
}
else
{
break;
}
}
cout << "两次输入不一致,请重新输入" << endl;
}
//两次输入正确的账户后,进行转账操作
ifstream ifs;
ifs.open(number1 + ".txt", ios::in);
string str[7];
for (int i = 0; i < 7; i++)
{
ifs >> str[i];
}
ifs.close();
long long t_balance = atoi(str[4].substr(6).c_str());
long long _balance = atoi(balance.c_str());
int flag = atoi(str[6].substr(14, 1).c_str());
if (flag == 0)
{
//无法对被冻结的账户进行转账
cout << "该账户已被冻结,转账失败" << endl;
system("pause");
system("cls");
return;
}
cout << "请输入你要转入该账户的金额(或按0返回主菜单)" << endl;
while (true)
{
int n;
cin >> n;
if (n == 0)
{
cout << "返回成功" << endl;
system("pause");
system("cls");
return;
}
else if (n < 0)
{
cout << "转账金额为负,转账失败,请重新输入" << endl;
}
else if (n > _balance)
{
cout << "余额不足,请重新输入(或按0返回主菜单)" << endl;
}
else
{
_balance -= n;
t_balance += n;
balance = to_string(_balance);
string s_balance = to_string(t_balance);
string temp = number1 + ".txt";
ofstream ofs(temp);
ofs << str[0] << endl;
ofs << str[1] << endl;
ofs << str[2] << endl;
ofs << str[3] << endl;
ofs << "余额:" << s_balance << endl;
ofs << str[5] << endl;
ofs << str[6] << endl;
ofs.close();
save();
cout << "转账成功!" << endl;
system("pause");
system("cls");
return;
}
}
}
//ATM模拟程序.cpp
#include"account.h"
int main()
{
account a;
a.showWelcome();
a.setID();
if (a.getFLAG() == 0)
{
cout << "您的账户已被冻结" << endl;
return 0;
}
a.isPassword();
int select = 0;
while (a.getFLAG())
{
a.showMenu();
string s;
cin >> s;
select = atoi(s.c_str());
switch (select)
{
case 1://查询余额
a.seeBalance();
break;
case 2://存入现金
a.addCash();
break;
case 3://提取现金
a.takeCash();
break;
case 4://转账
a.transfer();
break;
case 5://修改密码
a.tranPassword();
break;
case 6://退卡
cout << "欢迎下次使用" << endl;
system("pause");
return 0;
break;
default:
cout << "您的输入有误,请重新输入" << endl;
system("pause");
system("cls");
break;
}
}
return 0;
}
1.需求分析
ATM模拟程序的设计与实现的需求如下:
①显示欢迎词及提示信息;②用户插卡,ATM验证用户账号及密码有效性,输入错误3次即被锁卡;③余额查询:初始余额为10000元;④取款功能:每次取款余额为100的整数倍,有单笔和单日金额限制;⑤转账功能:可将本账户中的存款转入其他账户,转入账户账号需两次输入确认;⑥修改密码:密码为6位数字,新密码需要两次输入确认;⑦退卡。
①显示欢迎词及提示信息:直接使用C++中的标准输出流即可实现
②用户插卡:要求用户输入一个19位的数字,而long long虽然有19位,却不能涵盖所有的19位数字,因此用string实现并判断格式的准确性。与此同时输入密码,输入三次锁卡,并将账号等信息记录于文件中,方便继续使用。
③余额查询:返回余额并输出
④取款功能:取款额度为100的整数倍,即“number%100=0;”,要求设计一天取款的金额上限,这就要求将取款的金额累加保存在文件中,并在取款时加以限制。
⑤转账功能:需要用户输入两次账户以确认,同时和插卡时类似,需要判断格式,同时要求文件的查找功能。
⑥修改密码:修改密码时需要输入原密码,所改密码也要两次确认
⑦退卡
2.系统设计
//设计时,考虑到代码量比较大,可以利用分文件进行编写,同时,各功能用函数实现(除了非常简单的退卡),提供充分的注释,提高代码的可读性。设计账户(account)类,对账户进行初始化和保存操作时比较简便。具体的代码可以在附件中查看。同时请在VS2022的64位下运行该代码。
①显示欢迎词及提示信息
void showWelcome();//展示欢迎词
②用户插卡
void setID();//输入账户,如果账户不存在就创建一个
③余额查询
void seeBalance();//1-查余额
④取款功能
void takeCash();//3-取钱
⑤转账功能
void transfer();//5-转账
⑥修改密码
void tranPassword();//4-改密码
⑦退卡
cout << "欢迎下次使用" << endl;
system("pause");
return 0;
break;
3.系统实现
1、显示欢迎词及提示信息
同时进行异常处理(输入错误卡号)
********************************
*** 欢迎使用ATM自助服务 ***
*** 请输入卡号插卡! ***
********************************
*** 若您输入一个不存在的卡号 ***
*** 将为您自动开户 ***
*** 开户后,初始密码为050429 ***
********************************
123
你输入的卡号有误,请重新输入
1qw
你输入的卡号有误,请重新输入
2、自动开户时提醒用户输入姓名和身份证,并进行异常处理:
1231231231231231231
自动开户中...
请输入你的姓名
qqq
请输入你的身份证
123445
身份证输入格式错误,请重新输入
123123123123123123
开户成功!
请按任意键继续. . .
3、判断密码的正确性:
请输入您的现密码:
1234
密码错误!您还有2次输入机会,请重新开始!
234556
密码错误!您还有1次输入机会,请重新开始!
050429
请按任意键继续. . .
PS:初始密码为050429
4、密码正确后进入菜单界面,提醒用户输入数字1~6,如果用户没有输入正确的数字,提醒用户重新输入:
*******************************
*** 登陆成功! ***
*** 1-余额查询 ***
*** 2-存入现金 ***
*** 3-提取现金 ***
*** 4-现金转账 ***
*** 5-修改密码 ***
*** 6-退卡 ***
*** 请以数字输入你的选择 ***
*******************************
132
您的输入有误,请重新输入
请按任意键继续. . .
5、余额查询
在此操作中,用户如果不想存了,也可以按0并回车返回主菜单
1
您的余额为: 10000
请按任意键继续. . .
6、提取现金
3
请输入你要取款的数额(100的倍数且不超过100000 ,单日取款不超过500000),或按0返回主菜单
您今日已取款: 0
224
你输入的金额错误,请重新输入
2000
取款成功!
请按任意键继续. . .
7、转账
如果用户输入账户错误,提醒输入的账户错误
同时不能转入自己的原账户
也实现了需要两次确认的功能
4
请输入你要转入的账户(或按0返回主菜单):
1111111111111111111
请再次输入该账户以确认
1111111111111111111
该账户不存在,请重新输入
请输入你要转入的账户(或按0返回主菜单):
1234567890987654321
请再次输入该账户以确认
1234567890987654321
该账户不存在,请重新输入
请输入你要转入的账户(或按0返回主菜单):
1234567890123456789
请再次输入该账户以确认
1234567890123456789
请输入你要转入该账户的金额(或按0返回主菜单)
1234
转账成功!
请按任意键继续. . .
8、修改密码
修改密码时需要输入原密码确认身份,如果三次未输入成功也会对账户进行冻结
5
请输入您的现密码:
1
密码错误!您还有2次输入机会,请重新开始!
050429
请按任意键继续. . .
请输入修改后的密码
111111
请确认修改后的密码
111111
密码修改成功!
请按任意键继续. . .
9、退卡
6
欢迎下次使用
请按任意键继续. . .
10、其他功能
①在取款时如果输入一个大于余额的金额,会提醒用户余额不足,同时输入一个小于0的数也会提醒用户取款失败
3
请输入你要取款的数额(100的倍数且不超过100000 ,单日取款不超过500000),或按0返回主菜单
您今日已取款: 2000
12343455436
您的余额不足qwq,请重新输入!
-1234
你输入的金额错误,取款失败
请按任意键继续. . .
②冻结
输入错误三次密码即对账户进行冻结并记录(下次无法登录该账户并且无法向该账户转账)
4
请输入你要转入的账户(或按0返回主菜单):
1231231231231231231
请再次输入该账户以确认
1231231231231231231
该账户已被冻结,转账失败
请按任意键继续. . .
1231231231231231231
您的账户已被冻结
③考虑代码的可维护性
\#define MAX_single_takeCASH 100000
\#define Number_of_account 19
\#define Number_of_ID_card 18
\#define MIN_multiple_CASH 100
\#define Number_of_password 6
\#define original_password "050429"
\#define original_balance "10000"
定义常量,方便后续进行修改和维护
4、参考文献
[1]刘瑞芳、肖波、许桂平、孙勇、徐慧民.《C++语言程序设计》[M].西安市太白路2号:西安电子科技大学出版社,2017.