本作业atm部分我用了大概两天时间来完成。
一开始的工作是尝试着在原框架代码上加注释,以此来了解老师给出的基本思路。
同时着手对框架中不符合c++标准的,没有能很好地利用c++的特性的地方进行修改
本项目使用面向对象的编程方法,抽象出atm类和account账户类,做到基本实现作业要求
亮点之处:
1.充分利用c++的string类代替c语言风格的字符数组,简化了许多操作
2.统一管理用户界面,实现表现逻辑与业务逻辑的分离和代码重用
3.结合控制台清屏、延时、密码星号回显输入等技术,优化用户界面
4.使用简单文本文件作为本地持久化存储解决方案
5.规范的编码,包括变量和方法命名、注释等
6.全局的调试信息输出开关,方便测试程序
exe目录内含文件分别为打开/关闭全局调试信息输出开关、调试/发布方式编译得出的文件
目录中的另外三个文本文件为运行时需要用到的数据文件
本项目编译环境为win7 + c-free 5
#include"function.h"
/******************************************************************************
* 题目1.(100分)
* 用面向对象方法实现ATM的模拟,实现储存,取款,查账,转账,修改密码等一系列功能。
* (1)用类实现ATM的主要功能
* (2)提示用户执行操作,内置用户资料,输入操作动作和信息。
* (3)程序可执行对不同用户的储存,取款,查账,转账,修改密码等一系列动作。
******************************************************************************/
int main()
{
ATM atmServer;
atmServer.start();
return 0;
}
#include"function.h"
/******************************************************************************
*
* 文件: account.cpp
*
* ===========================================================================
*
* 内容: 账户类的实现
*
* 接口函数: account::account(string num,string pwd,float money)
* account::getPassword()
* account::toFile(string filename)
* account::fromFile(string filename)
* account::minusMoney(float money)
* account::addMoney(float money)
* account::queryMoney()
* account::changePassword(string newPassword)
* account::getCardNum()
*
* 用途: 实现账户类底层数据操作接口
*
* 注释: 本层未作一般条件限制,上层应予以实现
*
******************************************************************************/
/******************************************************************************
*
* 方法: account::account(string num,string pwd,float money)
*
* 功能: 账户类构造函数,同时初始化类成员变量
*
* 注释: 本层不做检测直接覆盖类成员变量里面的数据
*
******************************************************************************/
account::account (string num, string pwd, float money)
{
m_cardNum = num;
m_password = pwd;
m_money = money;
}
/******************************************************************************
*
* 方法: account::getPassword()
*
* 功能: 查询返回账户的密码
*
* 注释: 底层实现故未作任何条件限制,交给上层来实现
*
******************************************************************************/
string account::getPassword ()
{
return m_password;
}
/******************************************************************************
*
* 方法: account::toFile(string filename)
*
* 功能: 将一个账户类的数据写入到指定的文件中
*
* 注释: 请确保对应文件及目录具有写入权限,否则程序cerr输出后将退出
*
******************************************************************************/
void account::toFile (string filename)
{
ofstream out((char *)filename.c_str());
if(!out)
{
cerr << "打开输出文件错误!" << endl;
system("pause");
exit(1);
}
out << m_cardNum << endl << m_password << endl << m_money << endl;
out.close();
}
/******************************************************************************
*
* 方法: account::fromFile(string filename)
*
* 功能: 从指定的文件中将一个账户类的数据读入,覆盖原有所有数据
*
* 注释: 请确保对应文件及目录具有读取权限,否则程序cerr输出后将退出
* 本层不做检测直接覆盖类成员变量里面的数据,小心使用
* 可以先使用isAccountFileExist(string cardNum)方法检测账户是否存在
*
******************************************************************************/
void account::fromFile (string filename)
{
ifstream in((char *)filename.c_str());
if(!in)
{
cerr << "打开输入文件错误!" << endl;
system("pause");
exit(1);
}
in >> m_cardNum >> m_password >> m_money;
in.close();
}
/******************************************************************************
*
* 方法: account::minusMoney(float money)
*
* 功能: 在当前帐户类中扣除指定金额的钱
*
* 注释: 本方法内有余额不足检测,余额不足返回假,否则返回真
* 上层也应使用queryMoney()方法进行检查
*
******************************************************************************/
bool account::minusMoney (float money)
{
if (money > m_money) //余额不足以扣钱
{
return false;
}
m_money -= money;
return true;
}
/******************************************************************************
*
* 方法: account::addMoney(float money)
*
* 功能: 在当前帐户类中增加指定金额的钱
*
* 注释: 底层实现故未作任何条件限制,交给上层来实现
*
******************************************************************************/
void account::addMoney (float money)
{
m_money += money;
}
/******************************************************************************
*
* 方法: account::queryMoney()
*
* 功能: 返回在当前帐户中的余额
*
* 注释: 底层实现故未作任何条件限制,交给上层来实现
*
******************************************************************************/
float account::queryMoney ()
{
return m_money;
}
/******************************************************************************
*
* 方法: account::changePassword(string newPassword)
*
* 功能: 修改当前帐户的密码
*
* 注释: 本层不做检测直接覆盖类成员变量里面的数据
* 未作任何条件限制,上层应予以实现
*
******************************************************************************/
void account::changePassword (string newPassword)
{
m_password = newPassword;
}
/******************************************************************************
*
* 方法: account::getCardNum()
*
* 功能: 返回在当前帐户的账号
*
* 注释: 保存文件、转账自身是检测用
*
******************************************************************************/
string account::getCardNum()
{
return m_cardNum;
}
#include "function.h"
/******************************************************************************
*
* 文件: ATM.cpp
*
* ===========================================================================
*
* 内容: ATM机类的实现
*
* 接口函数: ATM::start()
* ATM::checkPassword()
* ATM::functionShow()
* ATM::lockAccount()
* ATM::loadAccount()
* ATM::welcome()
* ATM::depositMoney()
* ATM::withdrawMoney()
* ATM::changePassword()
* ATM::transferMoney()
* ATM::getCardBack()
*
* 用途: 实现ATM机上层用户操作接口
*
* 注释: 本层未作一般条件限制,上层应予以实现
*
******************************************************************************/
/******************************************************************************
*
* 方法: ATM::start()
*
* 功能: 模拟atm开机,引导初始化工作
*
* 注释: 对外的接口
*
******************************************************************************/
void ATM::start()
{
stopFlag = false;
while (!stopFlag) welcome();
}
/******************************************************************************
*
* 方法: ATM::welcome()
*
* 功能: 模拟atm机初始化显示欢迎界面给用户
*
* 注释: 本方法将清屏后输出欢迎界面,然后调用load()方法
*
******************************************************************************/
void ATM::welcome()
{
printMsg(101); //欢迎界面
loadAccount();
}
/******************************************************************************
*
* 方法: ATM::loadAccount()
*
* 功能: 模拟插卡和验证密码过程,最终读入对应账户的文件
*
* 注释: 对应账户的文件应该要存在
*
******************************************************************************/
void ATM::loadAccount()
{
string cardNum,password;
if (g_debug) printMsg(201); //调试账号提示
//账号验证
do
{
printMsg(102); //输入账号提示
cin >> cardNum;
if (account::isAccountFileExist(cardNum)) break; //输入正确跳出循环
printMsg(301); //账号错误提示
} while (true);
//账号读入
account tmpAccount;
int errPassTimes = 0;
tmpAccount.fromFile(cardNum + ".txt");
//密码验证 检验来源为文件中存储的密码数据,不能使用checkPassword()
do
{
if (g_debug) printMsg(202, tmpAccount.getPassword()); //调试密码提示
printMsg(103); //输入密码提示
password = ATM::inputPassword();
if (password == tmpAccount.getPassword()) break; //输入正确跳出循环
printMsg(302); //密码错误提示
errPassTimes++;
if (errPassTimes >= 3)
{
lockAccount();
return;
}
} while (true);
curAccount = tmpAccount;
functionShow();
}/* load() - 结束 */
/******************************************************************************
*
* 方法: ATM::checkPassword(string pwd)
*
* 功能: 检验给出的密码是否与atm内部当前账户密码一致
*
* 注释: 注意此处检验来源为atm对象中存储当前帐户的密码数据
*
******************************************************************************/
bool ATM::checkPassword(string pwd)
{
if(pwd == curAccount.getPassword())
return true;
else
return false;
}
/******************************************************************************
*
* 方法: ATM::lockAccount()
*
* 功能: 模拟atm输错密码次数过多后吞卡
*
* 注释: 吞卡后return一直到顶层start()里面重复welcome()的过程
*
******************************************************************************/
void ATM::lockAccount()
{
printMsg(303);
}
/******************************************************************************
*
* 方法: ATM::functionShow()
*
* 功能: 模拟atm验证密码成功后显示功能菜单并分流处理用户选择
*
* 注释: 分流出去处理具体过程,本方法作为一个总路由
*
******************************************************************************/
void ATM::functionShow()
{
do
{
printMsg(101); //顶部
if (g_debug) printMsg(204, ""); //退卡提示
printMsg(104); //功能菜单
int n;
cin>>n;
while(n<1||n>6)
{
printMsg(304); //操作编号有误
cin>>n;
}
switch(n)
{
case 1: //执行存款功能
depositMoney();
break;
case 2: //执行取款功能
withdrawMoney();
break;
case 3: //执行查询余额功能
queryMoney();
break;
case 4: //执行转账功能
transferMoney();
break;
case 5: //修改密码
if(!changePassword()) return; //验证密码失败一直退回到顶层重新welcome()
break;
case 6: //退卡
getCardBack();
return; //一直退回到顶层重新welcome()
break;
}
} while (true);
}
/******************************************************************************
*
* 方法: ATM::depositMoney()
*
* 功能: 模拟atm存钱
*
* 注释: 存钱 - 显示余额 - 返回菜单
*
******************************************************************************/
void ATM::depositMoney()
{
printMsg(101); //显示顶部
if (g_debug) printMsg(203); //调试存款提示
printMsg(106); //提示存款
float tmp;
cin >> tmp;
curAccount.addMoney(tmp);
printMsg(107, tmp); //显示实际存入金额
printMsg(108, curAccount.queryMoney()); //显示余额
}
/******************************************************************************
*
* 方法: ATM::withdrawMoney()
*
* 功能: 模拟atm取钱
*
* 注释: 取钱 - 显示余额 - 返回菜单
*
******************************************************************************/
void ATM::withdrawMoney()
{
printMsg(101); //显示顶部
if (g_debug) printMsg(205); //调试取款提示
float tmp;
do
{
printMsg(109); //提示取款
cin >> tmp;
if (tmp <= curAccount.queryMoney()) break;
printMsg(305);
} while (true);
curAccount.minusMoney(tmp);
printMsg(110, tmp); //显示实际存入金额
printMsg(108, curAccount.queryMoney()); //显示余额
}
/******************************************************************************
*
* 方法: ATM::queryMoney()
*
* 功能: 模拟atm查询余额
*
* 注释: 显示余额 - 返回菜单
*
******************************************************************************/
void ATM::queryMoney()
{
printMsg(101); //显示顶部
printMsg(108, curAccount.queryMoney()); //显示余额
}
/******************************************************************************
*
* 方法: ATM::changePassword()
*
* 功能: 模拟atm改密码
*
* 注释: 验证原有密码 - 设置新密码 - 确认新密码 - 返回菜单
* 验证原有密码失败则返回假一直退到顶层重新welcome过程
*
******************************************************************************/
bool ATM::changePassword()
{
int errPassTimes = 0;
string password, vPassword;
printMsg(101); //显示顶部
//验证原密码
if (g_debug) printMsg(202, curAccount.getPassword()); //调试密码提示
do
{
printMsg(103); //输入密码提示
password = ATM::inputPassword();
if (password == curAccount.getPassword()) break; //输入正确跳出循环
printMsg(302); //密码错误提示
errPassTimes++;
if (errPassTimes >= 3)
{
lockAccount();
return false;
}
} while (true);
//设置新密码
do
{
printMsg(111); //新密码输入提示
password = ATM::inputPassword();
printMsg(112); //新密码再次输入提示
vPassword = ATM::inputPassword();
if (password == vPassword) break;
printMsg(306);
} while (true);
//写入数据
curAccount.changePassword(password);
printMsg(113);
}
/******************************************************************************
*
* 方法: ATM::transferMoney()
*
* 功能: 模拟atm转账
*
* 注释: 当前帐户减钱 - 目标账户加钱 - 返回菜单
*
******************************************************************************/
void ATM::transferMoney()
{
printMsg(101); //显示顶部
//账号验证
string cardNum;
if (g_debug) printMsg(201); //调试账号提示
do
{
printMsg(114); //输入账号提示
cin >> cardNum;
if (account::isAccountFileExist(cardNum) && //账户存在
cardNum != curAccount.getCardNum() //不是给自己转
) break; //输入正确跳出循环
printMsg(301); //账号错误提示
} while (true);
//账号读入
account tmpAccount;
tmpAccount.fromFile(cardNum + ".txt");
//余额验证
float tmp;
do
{
printMsg(115); //提示转账
cin >> tmp;
if (tmp <= curAccount.queryMoney()) break;
printMsg(305);
} while (true);
//加减钱过程
curAccount.minusMoney(tmp);
tmpAccount.addMoney(tmp);
//临时账户的保存
tmpAccount.toFile(cardNum + ".txt");
printMsg(116); //转账成功
printMsg(108, curAccount.queryMoney()); //显示余额
}
/******************************************************************************
*
* 方法: ATM::getCardBack()
*
* 功能: 模拟atm退卡
*
* 注释: 保存文件 - 返回welcome
*
******************************************************************************/
void ATM::getCardBack()
{
//保存过程
curAccount.toFile(curAccount.getCardNum() + ".txt");
printMsg(101); //显示顶部
printMsg(117); //退卡提示
}
#include
#include
#include //cout格式输出
#include //延时函数 sleep
#include //类型转换用到
using namespace std;
/******************************************************************************
*
* 文件: printMsg.cpp
*
* ===========================================================================
*
* 内容: 实现一个向控制台输出信息的封装函数
*
* 用途: 统一管理用户界面所有可重用的输出
*
* 注释: 分离用户界面层表现逻辑和程序业务逻辑,实现输出信息统一管理
*
******************************************************************************/
/******************************************************************************
*
* 函数: printMsg(int index)
*
* 功能: 打印指定的信息到控制台
*
* 注释: index索引值用于指定要打印的信息,定义如下
* 普通信息: 1xx
* 101:显示欢迎界面
* 102:输入账号提示
* 103:输入密码提示
* 104:atm功能菜单
* 105:输入操作编号提示
* 106:存款提示
* 107:存款成功提示
* 108:余额提示
* 109:取款提示
* 110:取款成功提示
* 111:输入新密码提示
* 112:再次输入新密码提示
* 113:密码修改成功提示
* 114:转账输入账号提示
* 116:转账成功
* 117:退卡提示
*
* 调试提示信息: 2xx
* 201:显示可用的内置调试账户号码
* 202:显示可用的内置调试账户密码
* 203:显示存款提示
* 204:退卡提示
* 205:调试取款提示
*
* 错误提示信息: 3xx
* 301:账号不存在
* 302:显示密码错误
* 303:吞卡
* 304:功能菜单输入编号错
* 305:余额不足
* 306:两次密码不一致
* 307:自己转账给自己
*
******************************************************************************/
void printMsg(int index, string extraInfo)
{
switch(index)
{
case 101: //显示欢迎界面
system("cls");
cout << endl << " " << setfill('$') << setw(60) << "" << endl;
cout << setfill(' ') << " " << "$" << setw(59) << "$" << endl;
cout << setfill(' ') << " " << "$" << setw(20)<< "";
cout << "欢迎使用暨大银行ATM" << setw(20)<< "$" << endl;
cout << setfill(' ') << " " << "$" << setw(59) << "$" << endl;
cout << setfill('$') << " " << setw(60) << "" << endl << endl;
break;
case 102: //输入账号提示
cout << " 请输入您的账号:";
break;
case 103: //输入密码提示
cout << " 请输入您当前帐户的密码:";
break;
case 104: //atm功能菜单
cout << " 尊敬的客户您好,本机提供以下功能: " << endl << endl;
cout << " (1) 存款 " << endl
<< " (2) 取款 " << endl
<< " (3) 查询余额 " << endl
<< " (4) 转账 " << endl
<< " (5) 修改密码 " << endl
<< " (6) 退卡 " << endl << endl;
printMsg(105, "");
break;
case 105: //操作输入提示
cout << " 请输入操作数字编号:";
break;
case 106: //存款提示
cout << " 请输入要存入的金额:";
break;
case 107: //存款成功提示
cout << " 已成功存入:" << extraInfo << endl;
break;
case 108: //余额提示
cout << " 当前帐户的余额为:" << extraInfo << endl;
Sleep(3000); //延时3秒,返回功能界面
break;
case 109: //取款提示
cout << " 请输入要取出的金额:";
break;
case 110: //取款成功提示
cout << " 已成功取出:" << extraInfo << endl;
break;
case 111: //输入密码提示
cout << " 请输入您的新密码:";
break;
case 112: //输入密码提示
cout << " 请再次输入您的新密码:";
break;
case 113: //改密码成功提示
cout << " 密码修改成功,请记住您的新密码。" << endl;
Sleep(3000); //延时3秒,返回功能界面
break;
case 114: //转账输入账号提示
cout << " 请输入目标账号:";
break;
case 115: //转账金额输入提示
cout << " 请输入要转账的金额:";
break;
case 116: //转账输入账号提示
cout << " 转账成功!"<> ret;
return ret;
}
void printMsg(int index, float extraInfo)
{
printMsg(index, floatToString(extraInfo));
}
全部代码文件、工程文件、exe文件、说明文档打包下载点击这里ATM