【娱乐大闯关】C语言实现模拟ATM机管理系统-创新互联
- 一、ATM.h
- 1、头文件
- 2、定义常量
- 3、账户信息
- 4、函数声明
- 二、Main_ATM
- 1、初始界面菜单
- 2、初始界面选择器
- 3、主函数
- 三、Fun_ATM
- 定义几个全局变量
- (一)初始化相关函数
- 1、获取本地已有数据
- 2、初始化
- (二)初始界面相关函数
- 1、开户
- 2、显示账户信息
- 3、登录
- 4、存盘
- (三)主界面相关函数
- 主界面选择系统
- a、主界面菜单
- b、主界面选择器
- 1、存款
- a、存取款金额选择菜单
- b、处理存款金额
- 2、取款
- 处理取款金额
- 3、查询余额
- 4、转账
- a、 核对账户是否存在
- b、 核对金额是否合法
- 5、修改密码
- 6、销户
- 补充功能
- 输入时密码隐藏
- 四、执行结果
文件相关知识可参考:文件(点击即可进入)
一段路大学学生专用银行
本行所提供的的服务包括以下几种:开户、显示、保存、登录、退出 登录成功后主要包括以下功能:存款、取款、查询余额、修改密码、转账、销毁、返回
一、ATM.h 1、头文件注:本程序的存储方式为文件磁盘的存储模式,采用数组的定义方式,未曾使用数据库!!
#include#include#include#include#include
2、定义常量#define MAX_ID 10 //账号
#define MAX_NAME 20 //姓名
#define MAX_SEX 5 //性别
#define MAX_DEP 30 //院系
#define MAX_MAJOR 30 //专业
#define MAX_CLASS 30 //班级
#define MAX_CARD 30 //卡号
#define MAX_PASSWORD 10 //密码
#define MAX_BANK 30 //开户行
#define MAX_MONEY 20000 //最高取款(转账)限度
3、账户信息本行账户所需信息主要包括:xh-账号、xm-姓名、xb-性别、yx-院系、zy-专业、bj-班级、kh-卡号、khh-开户行、khsj-开户时间、ye-余额、zt-状态、mm-初始密码
注:账户信息命名规则:一律采用的拼音首字母小写进行的变量命名
typedef struct ATM_ACCOUNT {char xh[MAX_ID], xm[MAX_NAME], xb[MAX_SEX], yx[MAX_DEP], zy[MAX_MAJOR],
bj[MAX_CLASS], kh[MAX_CARD], mm[MAX_PASSWORD], khh[MAX_BANK];
char zt;//银行卡状态
long khsj;//开户时间
float ye;//余额
}ATM_account;
4、函数声明//初始化相关函数
void init();//初始化函数
int getNum();//获取本机所有账户函数
//初始界面相关函数
void menu1();//初始界面菜单函数
void welcome();//初始界面选择功能函数
void Open_account();//开户函数
void Show_account();//显示账户信息函数
void Login();//登录函数
void Save_account();//保存函数
//主界面相关函数
void menu2();//主机菜单函数
void mainmenu();//主机菜单选择功能函数
void Money();//存取款金额选择函数
void Deposit();//存款函数
void Money_Slove1();//固定存款金额处理函数
void Other_Money1();//任意存款金额处理函数
void Draw();//取款函数
void Money_Slove2();//取款金额选择功能函数
void Sub_Money(int k);//固定金额取款处理函数
void Other_Money2();//任意金额取款处理函数
void Query();//查询余额函数
void ChangePwd();//修改密码函数
void Transfer();//转账函数
int validata_ID(char* p);//转账账户核对函数
int validata_Money(int money);//转账金额合法性检查函数
二、Main_ATM
1、初始界面菜单void menu1() {puts("**********************************************");
puts("*1.开户 2.显示账户 3.登录 4.存盘 0.退出*");
puts("**********************************************");
printf("请选择:>");
}
2、初始界面选择器void welcome() {int input = 0;
while (1) {system("cls");
menu1();
scanf("%d", &input);
switch (input) {case 1:Open_account(); break;
case 2:Show_account(); break;
case 3:Login(); break;
case 4:Save_account(); break;
case 0://退出之前要自动保存一下信息
Save_account(); puts("欢迎下次使用!"); system("pause"); exit(0);
default:puts("选择错误,请重试!"); system("pause"); break;
}
}
}
3、主函数int main() {init();//初始化
welcome();//欢迎界面
return 0;
}
三、Fun_ATM
定义几个全局变量int max_account,//账户的上限值,存在一个文本文件中
cnt_account,//现有账户数,存在一个二进制文件中
sign;//登录账户的角标
ATM_account atm_account;
ATM_account* p_account = &atm_account;//指向的内存块,存放具体的账户信息
(一)初始化相关函数1、获取本地已有数据注:开始前需在文件存储位置处,建立一个data文件夹,里面建立一个init.txt的文件,init.txt 文件里面存入max_account=100;,记录账户的上限
int getNum() {FILE* fp;
int i = 0;
long pos = 0;
if ((fp = fopen("data\\atm_account.dat", "rb")) == NULL) {perror("getNum_atm_account.dat"); system("pause"); return 0;
}
fseek(fp, 0, SEEK_END);//定位文件函数
pos = ftell(fp);//pos---->文件的尺寸!!!!
if (pos == -1) {puts("文件定位出错!"); system("pause");
return 0;
}
return pos / sizeof(ATM_account);//结果就是atm_account.dat存放了多少个账户的信息!!!
fclose(fp);
fp = NULL;
}
2、初始化void init() {FILE* fp;
int i = 0;
cnt_account = getNum();//获取本机现有账户数
if ((fp = fopen("data\\init.txt", "r")) == NULL) {perror("init_init.txt"); system("pause"); return;
}
fscanf(fp, "max_account=%d;", &max_account);
printf("max_account = %d\n", max_account);
if (max_account<= 0) {puts("初始化数据有误,程序终止执行!"); system("pause"); return;
}
//内存分配!
p_account = (ATM_account*)malloc(max_account * sizeof(ATM_account));
if (p_account == NULL) {puts("内存分配失败,程序终止执行!"); system("pause"); return;
}
fclose(fp);
if ((fp = fopen("data\\atm_account.dat", "rb")) == NULL) {perror("init_atm_account.dat"); system("pause"); return;
}
fread(&cnt_account, sizeof(int), cnt_account, fp);
fread(p_account, sizeof(ATM_account), cnt_account, fp);
printf("共有%d个账户信息!\n", cnt_account);
puts("初始化完毕!");
system("pause");
fclose(fp);
fp = NULL;
}
(二)初始界面相关函数
1、开户void Open_account() {printf("账号:>"); scanf("%s", p_account[cnt_account].xh);
printf("姓名:>"); scanf("%s", p_account[cnt_account].xm);
printf("性别:>"); scanf("%s", p_account[cnt_account].xb);
printf("院系:>"); scanf("%s", p_account[cnt_account].yx);
printf("专业:>"); scanf("%s", p_account[cnt_account].zy);
printf("班级:>"); scanf("%s", p_account[cnt_account].bj);
printf("卡号:>"); scanf("%s", p_account[cnt_account].kh);
printf("开户行:>"); scanf("%s", p_account[cnt_account].khh);
p_account[cnt_account].khsj = time(0);
p_account[cnt_account].ye = 0.0f;
p_account[cnt_account].zt = '0';//账户状态良好为'0'
strcpy(p_account[cnt_account].mm, "000000");
cnt_account++;//开户数增加1
puts("开户完毕!"); system("pause");
}
2、显示账户信息void Show_account() {int i = 0;
if (cnt_account == 0)
puts("还未有人开户,NO.1快去开户吧!");
else {while (i< cnt_account) { printf("%s\t%5s\t%5s\t%15s\t%15s\t%10s\t%10s\t%5s\t%5c\t%15s\t%15ld\t%10.2f\t\n",
p_account[i].xh, p_account[i].xm, p_account[i].xb,
p_account[i].yx, p_account[i].zy, p_account[i].bj,
p_account[i].kh, p_account[i].mm, p_account[i].zt,
p_account[i].khh, p_account[i].khsj, p_account[i].ye);
i++;
}
}
puts("显示完毕!"); system("pause");
}
3、登录注:此处若是三次登录都失败,可将账户锁定,锁定就将状态改为 ‘1’
void Login() {int times = 0, i = 0;
int flag = 0;
char xh[MAX_ID], mm[MAX_PASSWORD];
do {system("cls");
puts("欢迎使用农业银行ATM机");
printf("账号:>"); scanf("%s", xh);
printf("密码:>"); scanf("%s", mm);
//到p_account所指的内存中查找该账号和密码;
//如果比对上,则进入主操作界面(mainmenu());
//否则,重新输入账号、密码,循环,直到用完3次机会!
for (i = 0; i< cnt_account; i++)
if (strcmp(xh, p_account[i].xh) == 0 && strcmp(mm, p_account[i].mm) == 0) { sign = i;//记录当前登录的账户角标
flag = 1; break;
}
if (flag == 1) break;
else { puts("账户或密码错误,请重试!");
system("pause");
}
times++;
} while (times< 3);
if (times == 3) {//锁定——状态改为1
//strcpy(p_account[sign].zt,'1');//锁定账户
//puts("三次登录失败,账户已被锁定!");
puts("三次登录失败!");
system("pause");
}
if (flag == 1) {puts("登录成功!");
system("pause");
mainmenu();
}
}
4、存盘void Save_account() {FILE* fp;
int i = 0;
if ((fp = fopen("data\\atm_account.dat", "wb")) == NULL) {perror("Save_account_atm_account.dat"); system("pause"); return;
}
fwrite(&cnt_account, sizeof(cnt_account), cnt_account, fp);//先写账户总数
i = fwrite(p_account, sizeof(ATM_account), cnt_account, fp);//再写具体的账户信息
if (i == 0)
puts("存盘失败!");
else {printf("保存完毕,共存入%d个账户信息!\n", i);
}
system("pause");
fclose(fp);
fp = NULL;
}
(三)主界面相关函数
主界面选择系统
a、主界面菜单void menu2() {puts("**************************************************");
puts("*** 1、存款 2、取款 3、查询余额 4、修改密码 ***");
puts("*** 5、转账 6、销户 0、返回 ***");
puts("**************************************************");
printf("请选择:>");
}
b、主界面选择器void mainmenu() {int input = 0;
while (1) {system("cls");
menu2();
scanf("%d", &input);
switch (input) {case 1:Deposit(); break;
case 2:Draw(); break;//待完成项目
case 3:Query(); break;
case 4:ChangePwd(); break;
case 5:Transfer(); break;
case 6:Logout();
case 0:welcome(); break;
default:puts("选择有误,请重试!"); system("pause"); break;
}
}
}
1、存款存款金额:只能存入百元大钞(即:大于100且为100的整数倍)
void Deposit() {Money_Slove1();
printf("%s的余额为:%.2f\n", p_account[sign].xh, p_account[sign].ye);
puts("存款完毕!"); system("pause");
}
a、存取款金额选择菜单void Money() {puts("****************************************************");
puts("*** 1、100元 ** 2、200元 ** 3、500元 ***");
puts("*** 4、1000元 ** 5、2000元 ** 6、其他金额 ***");
puts("******************** 0、返回 ***********************");
puts("****************************************************");
printf("请选择:>");
}
b、处理存款金额void Money_Slove1() {int input = 0;
while (1) {system("cls");
Money();
scanf("%d", &input);
switch (input) {case 1:p_account[sign].ye += 100;
puts("已存入100元"); system("pause"); break;
case 2:p_account[sign].ye += 200;
puts("已存入200元"); system("pause"); break;
case 3:p_account[sign].ye += 500;
puts("已存入500元"); system("pause"); break;
case 4:p_account[sign].ye += 1000;
puts("已存入1000元"); system("pause"); break;
case 5:p_account[sign].ye += 2000;
puts("已存入2000元"); system("pause"); break;
case 6:Other_Money1(); break;
case 0:return;
default:puts("选择有误,请重试!"); system("pause"); break;
}
}
}
void Other_Money1() {//处理其他金额的情况
int money = 0;
puts("本行仅支持存入百元大钞!");
printf("请输入存款金额:>"); scanf("%d", &money);
//判断存入金额是否为百元大钞
if (money >= 100 && money % 100 == 0) {//是
p_account[sign].ye += money;
printf("已存入%d元\n", money);
}
else {//否
puts("存入金额不符要求,无法存入!");
}
system("pause");
}
2、取款取款金额条件:非负、余额充足、小于单笔上限、整取
void Draw() {printf("%s的余额为:%.2f\n", p_account[sign].xh, p_account[sign].ye);
Money_Slove2();//取款
printf("%s的余额为:%.2f\n", p_account[sign].xh, p_account[sign].ye);
puts("取款完毕!"); system("pause");
}
处理取款金额void Money_Slove2() {int input = 0;
int k = 0;
while (1) {system("cls");
Money();
scanf("%d", &input);
switch (input) {case 1:k = 100; Sub_Money(k); break;
case 2:k = 200; Sub_Money(k); break;
case 3:k = 500; Sub_Money(k); break;
case 4:k = 1000; Sub_Money(k); break;
case 5:k = 2000; Sub_Money(k); break;
case 6:Other_Money2(); break;
case 0:return;
default:puts("选择有误,请重试!"); system("pause"); break;
}
}
}
void Sub_Money(int k) {//处理余额不足的情况
if (k >p_account[sign].ye)
puts("余额不足,取款失败!");
else {p_account[sign].ye -= k;
printf("已取走%d元\n", k);
}
system("pause");
}
void Other_Money2() {//处理其他金额的情况
int money = 0;
puts("本行仅支持按50的倍数取款!");
printf("请输入取款金额:>"); scanf("%d", &money);
//判断取款金额:非负、小于余额、50的倍数、上限
if (money >= 0 && money<= p_account[sign].ye && money % 50 == 0 && money<= MAX_MONEY) {//是
p_account[sign].ye -= money;
printf("已取走%d元\n", money);
}
else {//否
puts("取款金额不符要求,无法取款!");
}
system("pause");
}
3、查询余额void Query() {printf("%s的余额为:%.2f\n", p_account[sign].xh, p_account[sign].ye);
system("pause");
}
4、转账输入对方账号:1、是否存在,2、账户状态,3、不能转给自己
输入转账金额:1、非负数,2、50的倍数,3、上限
转账:1、修改自己的余额,2、修改对方的余额 记录交易信息:1、自己转出的,2、对方的转入的(此功能未实现)
void Transfer() {char reci_xh[MAX_ID];
int trans_sign;//转账的账号角标
again3:
system("cls");
printf("请输入需要转账的账号:>"); scanf("%s", reci_xh);
//判断账号合法性
trans_sign = validata_ID(reci_xh);
if (trans_sign >= 0) {//合法
int tra_amount = 0;
printf("请输入转账金额:>"); scanf("%d", &tra_amount);
if (validata_Money(tra_amount) >0) {//合法
p_account[sign].ye -= tra_amount; p_account[trans_sign].ye += tra_amount;
printf("转账成功,共计转账%d元!", tra_amount); system("pause");
}
else { puts("金额不足,无法转账!"); system("pause");
}
}
else {//非法
int a = 0;
puts("账号有误,重试请按——1 !");
a = _getch();
if (a == 1) { goto again3;
}
else { puts("已取消转账!"); system("pause");
return;
}
}
}
a、 核对账户是否存在遍历所有账户,若存在且账户状态良好(即为0)返回该账户下标,否则返回-1
int validata_ID(char* p) {//查找账户是否存在,存在返回其角标k,否则返回-1
int i = 0;
if (strcmp(p_account[sign].xh, p) != 0) {//不是转给自己
for (i = 0; i< cnt_account; i++)//转账的账户存在
if (strcmp(p, p_account[i].xh) == 0)
if (p_account[i].zt == '0') return i;//转账的账户状态良好
}
return -1;
}
b、 核对金额是否合法转账金额:非负、50的倍数、小于单笔最高转账金额、余额充足
int validata_Money(int money) {//转账金额合法返回值为1,否则-1
if (money >= 0 && money % 50 == 0 && money<= MAX_MONEY)
if (money<= p_account[sign].ye) return 1;
return -1;
}
5、修改密码输入原密码:核对,若输错原密码三次可锁定账户(此项本程序未实现)
输入新密码:三次新密码要一致才能修改原密码,修改完之后要重新登录
void ChangePwd() {//修改密码
char ori_mm[MAX_PASSWORD];
char new_mm1[MAX_PASSWORD], new_mm2[MAX_PASSWORD], new_mm3[MAX_PASSWORD];
int times = 0;//记录输入次数
printf("请输入原密码:>"); scanf("%s", ori_mm);
if (strcmp(ori_mm, p_account[sign].mm) == 0) {puts("密码正确!"); system("pause");//下一步
system("cls");
printf("请输入新密码:>"); scanf("%s", new_mm1);
puts("输入成功,请再次输入!"); system("pause");
do { system("cls");
printf("请再次输入新密码:>"); scanf("%s", new_mm2);
times++;
if (strcmp(new_mm1, new_mm2) == 0) {//判断两次密码是否一致
puts("输入成功,请再次输入!"); system("pause");
break;
}
else { if (times == 3) {printf("%d次输入密码不一致,无法修改密码!\n", times);
return;
}
puts("两次密码不一致,请重新输入!"); system("pause");
}
} while (1);
do { system("cls");
times = 0;//将次数记录恢复到0,进行下次记录
printf("请再次输入新密码:>"); scanf("%s", new_mm3);
times++;
//判断三次密码是否一致
if (strcmp(new_mm3, new_mm2) == 0) { strcpy(p_account[sign].mm, new_mm3);//修改密码
puts("输入成功,密码已修改,请重新登录!"); system("pause"); Login();
break;
}
else { if (times == 3) {printf("%d次输入密码不一致,无法修改密码!\n", times);
return;
}
puts("密码输入不一致,请重新输入!"); system("pause");
}
} while (1);
}
else {puts("原密码输入有误,无法修改密码!"); system("pause");
}
}
6、销户此功能为银行人员使用!!!
void Logout() {//销户
char ori_mm[MAX_PASSWORD];
int n = 0,i = 0;
printf("请输入原密码:>"); scanf("%s", ori_mm);
if (strcmp(ori_mm, p_account[sign].mm) == 0) {system("cls");
puts("您确定要注销您的账户吗?\t确定请按<1>");
printf("请选择:>"); scanf("%d", &n);
if (n == 1) { for (i = sign; i< cnt_account; i++) { p_account[i] = p_account[i + 1];
}
cnt_account--;
puts("销户成功!\n"); system("pause");
}
}
else {puts("密码错误,无法销户!"); system("pause");
}
}
补充功能
输入时密码隐藏输入密码时,用*代替打印到屏幕上
1、中有一个 _getch() 函数,当使用它的时候不会回显字符。
2、‘\r’ 表示回车符;‘\b’ 表示退格符,当按下 “backspace” 时就是输入了 ‘\b’ 退格:光标往前一格,而原来位置显示的字符不变
void InPwd() {char ch;
int index = 0;
char password[MAX_PASSWORD];
puts("请输入密码,以回车键结束");
while ((ch = _getch()) != '\r') {if (ch != '\b') { printf("*");//判断若输入非退格符则显示 *
password[index++] = ch;//将ch读入到password中
}
else { //若为退格符,则需先显示 '\b' 使得光标往前一格,再
//显示空格符覆盖掉原来的 * ,最后再显示 '\b’使光标
//回退,达到视觉上的删除效果
printf("\b \b");
index--;
}
}
password[index] = '\0';
printf("\n");
//打印到屏幕上检查输入是否一致
printf("所输密码为:%s\n", password);//使用时不需要写这一句
system("pause");
}
四、执行结果执行结果均以一 段 路三人来演示
开户界面
一 段 路三人开户结果
存钱与改密码
存入金额与新密码情况如下:
一:1000 123456
二:2000 234567
三:3000 345678
让路给一转账1000元,使得三人余额均为2000元
其他功能的操作这里就不展示了,有兴趣的小猿自己操作哦!!! 不足之处,欢迎评论区留言!!!
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页名称:【娱乐大闯关】C语言实现模拟ATM机管理系统-创新互联
文章分享:http://scjbc.cn/article/ppihi.html