简单实现ATM(C+string库)
| 这个作业属于哪个课程 | <https://edu.cnblogs.com/campus/ahgc/AHPU-SE-19/> |
| 这个作业要求在哪里 | <https://edu.cnblogs.com/campus/ahgc/AHPU-SE-19/homework/11477> |
| 这个作业的目标 | <编写一个ATM管理系统> |
| 学号 | <3190704207> |
这次的系统做的比较急,很多细节方面的设计还不够完善,安全性方面也还存在着缺陷,希望到哪天有时间了可以给它更加完善吧,我这次的代码就当是打个样,简单实现和模拟一下ATM系统。
此次的代码,从总的方面,我将其分为两个界面。
一个是未登录页面,包含开户,销户,登录,退出四个功能,在window()函数中实现。

另一个是登录后的界面,包含查询余额,存款,取款,转账,退出五个功能,在LogIn()函数中实现。

介绍完总体的框架,接下来我将细致地介绍各个函数。
这个程序总共含有九个调用函数,一个结构体,两个静态全局变量,一个常量。
关于结构体,这次是比较简单的设计,主要实现的是一些关键信息的处理、存储和生成。像姓名,性别,年龄等次要信息,可以在扩展该程序的时候进行实现。
#define N 100 //该系统可输入的上限人数 static int x = 0; //记录已经输入的账号 static int now = 0; //记录当前在执行账号的下标 struct node { string account; //账号 string password; //密码 int balance; //余额 }accounts[N]; void OpenAccount(); void DeleteAccount(); void LogInCheck(); void LogIn(); void window(); void BalanceInquiry(); void Deposit(); void Withdrawal(); void Transfer();
关于未登录界面的应用有三个,分别是OpenAccount(),DeleteAccount(),LogInCheck()
- 开户函数OpenAccount()
在本函数中,作为实际应用的话,还不够严谨,需要扩展的话,我认为应该加上检查功能,检查输入的电话号码格式是否符合要求,在正常ATM系统中,更应该自动生成账号,而不是使用手机号。在密码显示方面,应该有隐藏功能,还需判断密码设置等级是否够高,以保障账户安全。
此处最后的Sleep()函数是为了延长显示时间,从而实现与用户的简单交互,window()函数主要是要在该功能结束后,重新再显示原来的界面。后面很多地方也用到了这两个函数,之后就不再一一赘述。
此处值得一提的是,这里的代码我是参照我之前写的工资管理系统的函数进行编写的,但我在处理while的判断条件的生成也在循环中,且判断条件前的一些语句我在循坏中也需要实现,当时没思路,用了goto语句解决了问题,但总所周知,goto语句比较危险,不被推荐,因此,在这次的代码中,我进行了改进,用do...while语句解决了该问题,详细用法见代码。
1 void OpenAccount(){ 2 system("cls"); 3 string str1,str2,oaccount; 4 bool flag; 5 int i; 6 do{ 7 printf("\n\n 请输入手机号作为你的账号名:"); //扩展:一、加入检查功能,非手机号要重新输入 8 cin>>oaccount; 9 for(i=0;i<x;i++){ 10 if(accounts[i].account==oaccount){ 11 flag=true; 12 printf(" 您输入的账号已存在,请重新输入!\n\n"); 13 break; 14 } 15 } 16 if(i==x){ 17 flag=false; 18 } 19 20 } 21 while(flag); 22 23 accounts[x].account=oaccount; 24 25 printf("\n\n 请输入密码:"); //扩展:密码显示隐蔽;密码不能太简单,需要格式限制 26 cin>>str1; 27 printf("\n 请再次输入密码:"); 28 cin>>str2; 29 while(str1!=str2) 30 { 31 printf(" 两次密码不一致,请重新输入!!!\n\n"); 32 printf("\n 请输入密码:\n"); 33 cin>>str1; 34 printf("\n 请再次输入密码:\n"); 35 cin>>str2; 36 } 37 accounts[x].password=str1; 38 accounts[x].balance=0; //由于没能搞懂怎么初始化结构体,所以在这里进行初始化 39 x++; 40 printf("\n 该账号注册成功!") ; 41 Sleep(600); 42 window(); 43 }

1 //此代码为工资管理系统中的一段代码,显示我用goto语句写的情况,随便看看 2 void SearchInfo() 3 { 4 int i,m; 5 char num[12]; 6 inexist: 7 printf("\n请输入想查询月工资的职工工号:\n"); 8 scanf("%s",num); 9 for( i=0; i<N; i++) 10 { 11 if(!strcmp(worker[i].no,num)) 12 break; 13 } 14 if(i==N) 15 { 16 printf("该职工工号不存在,请重新输入!\n"); 17 goto inexist; 18 } 19 else 20 { 21 printf("该职工姓名为%s\n",worker[i].name); 22 printf("请输入想查找的月份:\n"); 23 scanf("%d",&m); 24 printf("该员工该月工资为-----"); 25 printf("%.2f\n",worker[i].gz[m-1]); 26 printf("\n此功能结束,请输入下一功能序号:\n"); 27 } 28 }
- 销户函数DeleteAccount()
本函数存在浪费内存空间的问题,在此函数中,我仅仅将需要被注销的账户的各个信息清空,本身没有进行后面结构体对象向前进位的情况,就会导致被销户账号的下标不再被使用,从而导致了内存的浪费。
而在实际的ATM系统,账户的信息成千上万,他们基本上是用数据库来存储用户的信息,如果要模拟,应该生成一个文件(若会数据库则数据库)来存储和输入用户的相关信息。
void DeleteAccount(){ system("cls"); string delaccount; bool flag; int i; do{ printf("\n\n 请输入需要被注销的账号:"); cin>>delaccount; for(i=0;i<x;i++){ if(accounts[i].account==delaccount){ flag=false; break; } } if(i==x){ printf(" 您输入的账号不存在,请重新输入!\n\n"); flag=true; } } while(flag); accounts[i].account='\0'; accounts[i].password='\0'; accounts[i].balance=0; printf("\n 销户成功!!"); Sleep(600); window(); }

- 登录(检查)函数LogInCheck()
虽然我在程序显示里写的这是登录函数,其实它是检查账号密码是否匹配的一个函数,进行了账号的不存在情况的报错。
此处有一个代码十分总要,后面登录界面上的功能都仰赖于它,就是 now=i; 这段代码,它直接记录了登录账号的下标,方便了之后的查询和数据的调用和处理。
1 void LogInCheck(){ 2 system("cls"); 3 string saccount,spassword; 4 int i; 5 bool flag=false; 6 do{ 7 printf("\n\n 请输入登录账号:"); 8 cin>>saccount; 9 for(i=0;i<x;i++){ 10 if(accounts[i].account==saccount){ 11 flag=false; 12 break; 13 } 14 } 15 if(i==x){ 16 printf("\n 您输入的账号不存在,请重新输入!\n"); 17 flag=true; 18 } 19 } 20 while(flag); //goto语句和do...while语句的转换 21 22 do{ 23 printf("\n\n 请输入密码:"); 24 cin>>spassword; 25 if(accounts[i].password!=spassword){ 26 printf("\n 您输入的密码不正确,请重新输入!\n"); 27 flag=true; 28 }else{ 29 flag=false; 30 } 31 }while(flag); 32 now=i; 33 printf("\n 恭喜你成功登录!!!"); 34 Sleep(600); 35 LogIn(); 36 }

该系统主要是靠前面的函数形成框架,所以登录界面的函数就异常的好写,接下来的函数,我将仅对转账函数Transfer()进行解释。
- 查询余额函数BalanceInquiry()
1 void BalanceInquiry(){ 2 system("cls"); 3 printf("\n\n 当前账户余额为 %d 元",accounts[now].balance); 4 Sleep(1200); 5 LogIn(); 6 }

- 存款函数Deposit()
void Deposit(){ system("cls"); int money=0; printf("\n\n 请输入存款金额:"); scanf("%d",&money); accounts[now].balance+=money; printf("\n 成功存入 %d 元!!",money); //printf("%d",accounts[now].balance); //测试用 Sleep(600); LogIn(); }

- 取款函数Withdrawal()
1 void Withdrawal(){ 2 system("cls"); 3 int money=0; 4 bool flag; 5 6 do{ 7 printf("\n\n 请输入取款金额:"); 8 scanf("%d",&money); 9 if(money>accounts[now].balance){ 10 printf(" \n 余额不足,请重新输入!\n\n"); 11 flag=true; 12 }else{ 13 accounts[now].balance-=money; 14 printf("\n 成功取出 %d 元!!",money); 15 //printf("%d",accounts[now].balance); //测试用 16 flag=false; 17 } 18 } 19 while(flag); 20 21 Sleep(600); 22 LogIn(); 23 }

- 转账函数Transfer()
此函数中包含了上面的取款函数的对自身余额是否超出了支出金额的判断,更添加了合理性。
1 void Transfer(){ 2 system("cls"); 3 int money; 4 5 string taccount; 6 int i; 7 bool flag=false; 8 do{ 9 printf("\n\n 请输入想要转账的账户:"); 10 cin>>taccount; 11 for(i=0;i<x;i++){ 12 if(accounts[i].account==taccount){ 13 flag=false; 14 break; 15 } 16 } 17 if(i==x){ 18 printf("\n 您输入的账号不存在,请重新输入!\n"); 19 flag=true; 20 } 21 } while(flag); 22 23 do{ 24 printf("\n\n 请输入转账金额:"); 25 scanf("%d",&money); 26 if(money>accounts[now].balance){ 27 printf(" \n 余额不足,请重新输入!\n\n"); 28 flag=true; 29 }else{ 30 accounts[now].balance-=money; 31 accounts[i].balance+=money; 32 flag=false; 33 } 34 } 35 while(flag); 36 printf("\n 转账成功!!"); 37 Sleep(600); 38 LogIn(); 39 }

小结:
很显然能看出来,我不是完全运用了C语言的知识,也运用了C++的string类,我觉得在系统里这样写应该挺不伦不类的,但使用string库确实能节省不少代码量,也不知道这样可不可以,反正就先写着练练手。
这次实在是时间匆忙,本来想设计一下界面,现在就属于勉强能看吧,至少不是全部挤在一起了,不知道C有没有控制界面文字布局的库。
这次的ATM系统不算是太难吧,有思路基本能够简单实现,但如果要认真做还是大有学问的,希望以后有时间能认真做一下。
| 任务内容 | 计划完成需要的时间(min) | 实际完成需要的时间(min) |
| 计划 | 8 | 6 |
| 估计这个任务需要多少时间,并规划大致工作步骤 | 8 | 12 |
| 开发 | 150 | 180 |
| 需求分析(包括学习新技术) | 20 | 17 |
| 生成设计文档 | 5 | 4 |
| 设计复审 | 10 | 5 |
| 代码规范 | 5 | 1 |
| 具体设计 | 10 | 7 |
| 具体编码 | 50 | 35 |
| 代码复审 | 7 | 5 |
| 测试(自我测试,修改代码,提交修改) | 30 | 50 |
| 报告 | 20 | 15 |
| 测试报告 | 5 | 0 |
| 计算工作量 | 5 | 0 |
| 事后总结,并提出过程改进计划 | 10 | 15 |
接下来是完整代码
#include <iostream> #include <stdio.h> #include <string> #include <stdlib.h> #include <windows.h> using namespace std; #define N 100 //该系统可输入的上限人数 static int x = 0; //记录已经输入的账号 static int now = 0; //记录当前在执行账号的下标 struct node { string account; //账号 string password; //密码 int balance; //余额 }accounts[N]; void OpenAccount(); void DeleteAccount(); void LogInCheck(); void LogIn(); void window(); void BalanceInquiry(); void Deposit(); void Withdrawal(); void Transfer(); void OpenAccount(){ system("cls"); string str1,str2,oaccount; bool flag; int i; do{ printf("\n\n 请输入手机号作为你的账号名:"); //扩展:一、加入检查功能,非手机号要重新输入 cin>>oaccount; for(i=0;i<x;i++){ if(accounts[i].account==oaccount){ flag=true; printf(" 您输入的账号已存在,请重新输入!\n\n"); break; } } if(i==x){ flag=false; } } while(flag); accounts[x].account=oaccount; printf("\n\n 请输入密码:"); //扩展:密码显示隐蔽;密码不能太简单,需要格式限制 cin>>str1; printf("\n 请再次输入密码:"); cin>>str2; while(str1!=str2) { printf(" 两次密码不一致,请重新输入!!!\n\n"); printf("\n 请输入密码:\n"); cin>>str1; printf("\n 请再次输入密码:\n"); cin>>str2; } accounts[x].password=str1; accounts[x].balance=0; //由于没能搞懂怎么初始化结构体,所以在这里进行初始化 x++; printf("\n 该账号注册成功!") ; Sleep(600); window(); } void DeleteAccount(){ system("cls"); string delaccount; bool flag; int i; do{ printf("\n\n 请输入需要被注销的账号:"); cin>>delaccount; for(i=0;i<x;i++){ if(accounts[i].account==delaccount){ flag=false; break; } } if(i==x){ printf(" 您输入的账号不存在,请重新输入!\n\n"); flag=true; } } while(flag); accounts[i].account='\0'; accounts[i].password='\0'; accounts[i].balance=0; printf("\n 销户成功!!"); Sleep(600); window(); } void LogInCheck(){ system("cls"); string saccount,spassword; int i; bool flag=false; do{ printf("\n\n 请输入登录账号:"); cin>>saccount; for(i=0;i<x;i++){ if(accounts[i].account==saccount){ flag=false; break; } } if(i==x){ printf("\n 您输入的账号不存在,请重新输入!\n"); flag=true; } } while(flag); //goto语句和do...while语句的转换 do{ printf("\n\n 请输入密码:"); cin>>spassword; if(accounts[i].password!=spassword){ printf("\n 您输入的密码不正确,请重新输入!\n"); flag=true; }else{ flag=false; } }while(flag); now=i; printf("\n 恭喜你成功登录!!!"); Sleep(600); LogIn(); } void LogIn(){ system("cls"); int m; printf("\n\n WELCOME, MY LOVELY ACCOUNT!!!"); printf("\n\n choose the function:\n\n"); printf(" 1.balance inquiry(查询余额)\n"); printf(" 2.deposit(存款)\n"); printf(" 3.withdrawal(取款)\n"); printf(" 4.transfer(转账)\n"); printf(" 0.exit(退出)\n"); printf("------------------------------------------\n"); printf("请输入想要运行的功能:\n"); scanf("%d",&m); while(m) { switch(m) { case 1:BalanceInquiry();break; case 2:Deposit();break; case 3:Withdrawal();break; case 4:Transfer();break; default:printf("\n此功能不存在,请重新输入!\n"); } scanf("%d",&m); } window(); } void window(){ system("cls"); int n; //记录需要被运行的功能 printf("\n\n WELCOME TO USE THIS ATM SYSTEM!!!!!\n\n"); printf(" choose the function:\n\n"); printf(" 1.open account(开户)\n"); printf(" 2.delete account(销户)\n"); printf(" 3.log in(登录)\n"); printf(" 0.exit(退出)\n"); printf("------------------------------------------\n"); printf("请输入想要运行的功能:\n"); scanf("%d",&n); while(n) { switch(n) { case 1:OpenAccount();break; case 2:DeleteAccount();break; case 3:LogInCheck();break; default:printf("\n此功能不存在,请重新输入!\n"); } scanf("%d",&n); } exit(0); } void BalanceInquiry(){ system("cls"); printf("\n\n 当前账户余额为 %d 元",accounts[now].balance); Sleep(1200); LogIn(); } void Deposit(){ system("cls"); int money=0; printf("\n\n 请输入存款金额:"); scanf("%d",&money); accounts[now].balance+=money; printf("\n 成功存入 %d 元!!",money); //printf("%d",accounts[now].balance); //测试用 Sleep(600); LogIn(); } void Withdrawal(){ system("cls"); int money=0; bool flag; do{ printf("\n\n 请输入取款金额:"); scanf("%d",&money); if(money>accounts[now].balance){ printf(" \n 余额不足,请重新输入!\n\n"); flag=true; }else{ accounts[now].balance-=money; printf("\n 成功取出 %d 元!!",money); //printf("%d",accounts[now].balance); //测试用 flag=false; } } while(flag); Sleep(600); LogIn(); } void Transfer(){ system("cls"); int money; string taccount; int i; bool flag=false; do{ printf("\n\n 请输入想要转账的账户:"); cin>>taccount; for(i=0;i<x;i++){ if(accounts[i].account==taccount){ flag=false; break; } } if(i==x){ printf("\n 您输入的账号不存在,请重新输入!\n"); flag=true; } } while(flag); do{ printf("\n\n 请输入转账金额:"); scanf("%d",&money); if(money>accounts[now].balance){ printf(" \n 余额不足,请重新输入!\n\n"); flag=true; }else{ accounts[now].balance-=money; accounts[i].balance+=money; flag=false; } } while(flag); printf("\n 转账成功!!"); Sleep(600); LogIn(); } int main(){ window(); return 0; }

浙公网安备 33010602011771号