C语言模拟ATM机_第1页
C语言模拟ATM机_第2页
C语言模拟ATM机_第3页
C语言模拟ATM机_第4页
C语言模拟ATM机_第5页
免费预览已结束,剩余20页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验目的通过设计一个ATM 机模拟操作的程序,全面运用课程的主要知识点,巩固对模块化程序设计、文件操作的理解,提高软件编程能力。实验要求要求每人独立完成设计,编写一个ATM 机模拟操作程序。提交实验报告、源程序、程序运行截图。1. 程序具有以下功能:1) 登录系统:输入卡号(16 位 )、密码(6 位 ) ,只有卡号、密码同时正确(帐户信息存放在文件中)才能进入系统;2) 操作功能:查询:查询帐户的存款余额。按任意键返回主菜单;修改密码:连续输入两次新密码(两次输入结果完全相同)后,新密码取代旧密码,并存放到帐户信息文件中。之后可返回主菜单;取款:输入 50 或 100 的倍数模拟为取款金额,

2、请注意:取款金额不得超过帐户余额,操作后帐户余额应相应减少。之后可返回主菜单;存款:输入 50 或 100 的倍数模拟为存款金额,现假设存款金额不得超过 20000 元,操作后帐户余额应相应增加。之后可返回主菜单;转帐:先输入一个帐户号(已保存在帐户信息文件中 ),然后显示一部分用户名(如:张* 山),储户确认无误后,再输入 50 或 100 的倍数模拟为转帐金额,请注意:转帐金额不得超过帐户余额,操作后帐户余额应相应减少。之后可返回主菜单;退出:退出系统。2. 定义如下结构体类型:日期”结构体 Date:成员有:year(年卜month(月卜day(日);帐户”结构体 Account:成员有

3、:no(帐户号)、name(姓名)、balance(余额)存取款记录”结构体 Record,:成员有:no(帐户号)、date(日期)、number(数量,可正可负,正 表示存款,负表示取款)3. 帐户信息存放在accounts.txt 文件,储户存取款记录保存在records.txt 中;4. 采用模块化程序设计方法来实现,即main()显示主菜单、调用相关函数实现相应功能, 起主控作用。5. 附加功能:储户一天内输错密码的次数不能超过3 次,否则无法进入系统;应避免输入存款金额、取款金额为负数等异常情况的出现。三、程序已经实现的功能点实验要求均已实现。此外还有:1. 卡号、密码位数输错时,

4、提示并返回重新输入,2. 简化取款时的输入3. 转账时,转账账户为原账户时,提示并返回重新输入4. 在多个模块中添加了退出功能,无需回到主菜单即可退出系统5. 在查询模块中加入了存取记录明细查询四、 程序运行截图及说明1. 登陆模块1) 卡号不为 16 位时,输出提示并返回重新输入2) 卡号不存在时,输出提示并返回重新输入3) 密码位数输错时,输出提示并返回重新输入密码,不作为密码错误处理,也无需重新输入卡号4) 密码连续输错三次时,锁定卡号,今日无法登录2. 登录后的系统主菜单3. 查询模块1) 查询模块主菜单2) 查询明细4. 取款模块1) 当余额不足 50 时,无法进入取款模块2) 取款

5、模块主菜单3) 便捷取款4) 手动输入取款金额输错时,返回重新输入5)取款后的菜单6)取款完成后选择显示余额5) 存款模块1)解决输入错误问题2)存款成功6) 密码修改模块1)原密码输错时,返回重新输入,不提供退出功能2)密码位数输错、两次输入新密码不一致时,返回重新输入3)输入无误时7) 转账模块1)转入卡号位数输错时,提示并返回重新输入2)未查找到该卡号时,输出提示,提供退出功能,键入除*外任意键重新输入3)转入卡号与当前卡号相同时,输出提示4)输出转入卡账户的部分用户名5)解决转账金额输错的问题6)转账成功五、采用的主要技术1.宏定义:由于本程序的printf语句较多,为了便于编写,故用

6、 PR代替2. 链表:账户信息采用链表结构,内存动态分配,使用内存无限制,可以扩展到所有可以使用的内存3. switch 多分支选择结构4. 文本文件的读写5. 利用 time.h 头文件,简便地获取系统日期6. system()S数和fflush()函数的简单使用六、 设计心得1. 各函数的功能要相对独立,逐步求精。2. 如果函数的参数为指针,且仅作为输入参数,则应在类型前加const,以防止该指针在函数体内被意外修改附:程序代码/* 运行本程序前,请在本程序根目录下建立文件“ accounts.txt” ,格式如下:* 卡号 1 ( 16 位)* 卡号 2 ( 16 位)姓名 1 账户余额

7、 1 密码 1姓名 2 账户余额 2 密码 2*/#include #include #include #include #define PR printf typedef struct short int year;short int month;short int day;Date;/ 日期typedef struct Account char no17;char name20;double balance;char password7; struct Account* next;Account;typedef structchar no17;Date date;double number

8、;Record;/ 记录Account *head = NULL;/ 账户信息链表表头Account *now_acc = NULL;/ 当前账户/*函数申明 */void InitializeAccount();/ 导入账户信息/ char LockAccountTopic(const char *no);/ 检测账户是否被锁定 void LockAccount(const char *no);/ 锁定账户/ void Login();/ 登录Account* FindbyNo(const char *no);/ 查找卡号对应账户信息在链表中的地址/void Demand();/ 查询主菜单

9、void PrintBalance();/ 输出余额void Printetail();/ 输出明细/void Modifiy();/ 修改密码/void Withdrawal();/ 取款主界面void WithdrawalOt(long money);/ 取款/void Depositing();/ 存款/void Transfer();/ 转账char *CoverUpName(const char *name);/ 掩盖部分用户名/void Log(double money, const char *no);/ 将存款记录写入文件中void Save();/ 保存账号信息void Fr

10、eeData();/ 释放链表空间/int main()char choose;InitializeAccount();/ 导入账户信息Login();/ 登录dosystem(cls);PR(ttn);PR(tt请选择服务n);PR(tt+-+-+n);PR(tt33转 账| 查 询32|1|n);PR(tt+-+-+nn);PR(tt+-+n);PR(tt| 取款32|2|n);PR(tt+-+nn);PR(tt+-+n);PR(tt| 存款32|3|n);PR(tt+-+nn);PR(tt+-+-+n);PR(tt|0|33 退出系统 | 修改密码 32|4|n);PR(tt+-+-+n

11、n);PR(请选择服务:);fflush(stdin);choose = getchar();switch (choose) case 1: Demand(); break;/ 查询case 2: Withdrawal(); break;/ 取款case 3: Depositing(); break;/ 存款case 4: Modifiy(); break;/ 修改密码case 5: Transfer(); break;/ 转账case 0: FreeData(); return 0;/ 退出default:printf( 输入错误,请重新选择n);/ 解决用户可能的输入错误system(pa

12、use); while (1);return 0;/*导入账户信息*/void InitializeAccount() FILE *fp;Account temp;PR(系统初始化中,请稍侯n);if (!(fp = fopen(accounts.txt, r)PR(07);/ 响铃PR(读取帐户信息失败,PR(卡号1 (16位)PR(卡号2 (16位)请在本程序根目录建立帐户信息文件姓名 1姓名 2账户余额1账户余额2(accounts.txt) 。 格式如下:密码 1n);密码 2n);n);PR(n);exit(0);while (fscanf(fp, %s %s %lf %s, tem

13、p.no, , &temp.balance, temp.password) = 4) / 读入账户信息Account *t = head;head = (Account*)malloc(sizeof(Account);*head = temp;head-next = t;fclose(fp);system(cls);/ 清除“系统初始化中,请稍侯.”提示/* 登录 */void Login()dochar no17;system(cls);PR(nnnnttt 请输入 16 位卡号: );fflush(stdin);gets(no);if (strlen(no) != 16)

14、PR(卡号应为16位n);system(pause);system(cls);continue;if (LockAccountTopic(no)/ 当该卡号被锁定时PR(07);/ 响铃PR(nn 您的登陆密码今日连续输错三次,已被临时锁定,次日将自动解锁,或当日持本人有效证件到柜台办理密码重置。 nn);system(pause);continue;if (!(now_acc = FindbyNo(no)/ 将卡号对应信息在链表的地址赋给now_acc/ 当卡号不存在时PR(nn 此卡号不存在,请重新输入! nn);system(pause);continue;char a = 2;/ 计算

15、剩余可输错密码次数do char password7;system(cls);PR(nnnnttt 请输入 16 位卡号: %sn, now_acc-no);PR(nnttt 请输入 6 位密码: );fflush(stdin);scanf(%s, password);if (strlen(password) != 6) PR(密码应为6位n);system(pause);system(cls); continue;if (!strcmp(now_acc-password, password) return;/ 密码正确,回到主函数if (a = 0)/ 输错密码三次,锁定账户PR(nn 您的

16、登陆密码今日连续输错三次,已被临时锁定,次日将自动解锁,或当日持本人有效证件到柜台办理密码重置。 nn);LockAccount(no); break;PR(07);/ 响铃PR(密码输入错误,还可以尝试c次nn, a-);system(pause); while (1); while (1);/* 检测账户是否被锁定 */char LockAccountTopic(const char *no)/ 被锁定则返回 0 FILE *fp;char CruuentTime11;/ 当前日期char ArchiveTime11;/ 锁卡档案日期char t17;if (!(fp = fopen(Lo

17、ckAccount.txt, a+)/ 课本上讲以 “a” 方式打开文件, 若文件不存在, 会出错。VS2013 实测,并不会出错,而是新建。为免第一次使用本程序时,根目录下没有LockAccount.txt 而导致出错,故此处不采用“ r ”方式。PR(07);/ 响铃PR(LockAccount.txt 无法打开 nn);exit(0);rewind(fp);/ 获取当前日期time_t rawtime;struct tm * timeinfo;rawtimetime(&rawtime);/ 获取时间,以秒计,从1970 年 1 月一日起算,存于timeinfo = localtime(&

18、rawtime);/ 转为当地时间, tm 时间结构strftime(CruuentTime, 11, %Y-%m-%d, timeinfo);/ 格式化时间fgets(ArchiveTime, 11, fp);/ 获取锁卡档案时间if (strcmp(ArchiveTime, CruuentTime)/ 若无锁卡档案,或锁卡档案日期与当前日期不同,则无账户被锁定fclose(fp);return 0;while (fscanf(fp, %s, t) = 1)if (!strcmp(t, no)/ 锁卡档案中,包含此卡号,返回 1 fclose(fp);return 1;fclose(fp);

19、return 0;/ 锁卡档案中,不含此卡号,返回 0/* 查找卡号对应账户信息在链表中的地址 */Account* FindbyNo(const char *no)for (Account *i = head; i; i = i-next) if (!strcmp(i-no, no) return i;return NULL;/*锁定账户 */void LockAccount(const char *no)FILE *fp;char CruuentTime11;/ 当前日期char ArchiveTime11;/ 锁卡档案日期if (!(fp = fopen(LockAccount.txt,

20、 r)PR(07);/ 响铃PR(error on open LockAccount.txt file!nn);exit(0);/ 获取当前日期time_t rawtime;struct tm * timeinfo;time(&rawtime);/ 获取时间,以秒计,从1970 年 1 月 1 日起算,存于 rawtimetimeinfo = localtime(&rawtime);/ 转为当地时间, tm 时间结构strftime(CruuentTime, 11, %Y-%m-%d, timeinfo);/ 格式化时间fgets(ArchiveTime, 11, fp);fclose(fp)

21、;if (strcmp(ArchiveTime, CruuentTime)/ 若档案日期与当前日期不同,则说明档案已过期或无档案,新建记录。if (!(fp = fopen(LockAccount.txt, w)PR(07);/ 响铃PR(error on open LockAccount.txt file!nn);exit(0);fprintf(fp, %sn, CruuentTime);else/ 若记录日期与当前日期相同,则追加记录if (!(fp = fopen(LockAccount.txt, a) PR(07);/ 响铃PR(error on open LockAccount.tx

22、t file!nn);exit(0);/ 添加记录fprintf(fp, %sn, no);fclose(fp);/*查询函数主菜单*/void Demand()char choose;dosystem(cls);PrintBalance();+-+n);| 查询明细 32|1|n);+-+nn);PR(ttttt PR(ttttt PR(tttttPR(tt+-+PR(tt|0|33 退出系统 |PR(tt+-+-+-+n);| 返 回 32|2|n);-+-+nn);PR(请选择服务:);fflush(stdin);choose = getchar();switch (choose)cas

23、e 1: Printetail(); break;/ 查询明细case 2: return;/ 返回case 0: FreeData(); exit(0);/ 退出系统 default:printf( 输入错误,请重新选择n);system(pause); while (1);/* 输出余额 */void PrintBalance()/ 解决用户可能的输入错误system(cls);PR(nnnnnnnnntt+n);PR(tt| 您的账户余额32|%-15.2f|n, now_acc-balance);PR(tt+nnnnnnn);/* 输出明细 */ void Printetail()FI

24、LE *fp;Record temp;int flag = 1;/ 当有记录时,置0if (!(fp = fopen(records.txt, r) PR(无存取记录,请进行存取后再使用本功能nn);system(pause);return;system(cls);PR(+ PR(| PR(+ +n);存取金额 |n);+n);if (!(strcmp(temp.no, now_acc-no) flag = 0;+n);PR(+PR(| 日期 | 存取金额 |n);/ 未免记录太多看不到表头,在最后加个表头PR(+n);if (flag)system(cls);/ 无记录时,清除表头PR(该卡

25、号未有任彳5存取记录nn);system(pause);return;system(pause);/ 当有存取记录时,输出后等待/* 将存款记录写入文件中 */void Log(double money, const char *no)FILE *fp;Date CruuentTime;/ 当前日期if (!money)/ 存取为零时 return;if (!(fp = fopen(records.txt, a)PR(07);/ 响铃PR(error on open records.txt file!);exit(0);/ 获取当前日期time_t rawtime;struct tm * ti

26、meinfo;time(&rawtime);/ 获取时间,以秒计,从1970 年 1 月 1 日起算,存于 rawtimetimeinfo = localtime(&rawtime);/ 转为当地时间, tm 时间结构CruuentTime.year = timeinfo-tm_year + 1900, CruuentTime.month = timeinfo-tm_mon + 1, CruuentTime.day = timeinfo-tm_mday;fprintf(fp, %sn%d-%d-%dn%fn, no, CruuentTime.year, CruuentTime.month, C

27、ruuentTime.day, money);fclose(fp);/* 取款主界面*/void Withdrawal()char choose;if (now_acc-balance 50.0)/ 当余额不足50 时,无法取款PR(07);/ 响铃PR(您的余额不足50,无法取款nn);system(pause);return;dosystem(cls);PR(nn);PR(tt+-+-+n);PR(tt|1|33100|2000 32|5|n);PR(tt+-+-+nn);PR(tt+-+-+n);PR(tt|2|33500|5000 32|6|n);PR(tt+-+-+nn);PR(tt

28、+-+-+n);PR(tt|3|331000| 其它金额 32|7|n);PR(tt+-+-+nn);PR(tt+-+-+n);PR(tt|4|33 退出系统 | 返 回 32|0|n);PR(tt+-+-+nn);PR(请选择服务:);fflush(stdin);scanf(%c, &choose);switch (choose)case 1: WithdrawalOt(100); break;case 2: WithdrawalOt(500); break;case 3: WithdrawalOt(1000); break;case 4: FreeData(); exit(0);case

29、5: WithdrawalOt(2000); break;case 6: WithdrawalOt(5000); break;case 7:do long money;PR(,请输入取款金额(50的倍数):); fflush(stdin);scanf(%ld, &money);if (money balance balance -= money;Save();Log(-money, now_acc-no);PR(取款成功nn);system(pause);/* 存款 */void Depositing() long money; doPR(请输入存款金额(50的倍数),单次存款金额不得超过20

30、000元:);fflush(stdin);scanf(%ld, &money);if (money 20000 | money % 50)/ 解决输入金额为负数、超过20000 、不是 50 的倍数的情况PR(07);/ 响铃PR(输入有误,请重新输入n);system(pause);continue;PR(正在处理,请稍候n);now_acc-balance += money;Save();/保存账户数据Log(money, now_acc-no);/ 保存存取数据PR(存款成功nn);system(pause);break; while (1); void Save()/*保存账户信息*/

31、FILE *fp;int i = 1;char ch;if (!(fp = fopen(accounts.txt, w)PR(07);/ 响铃PR(读取帐户信息失败!accounts.txt无法打开n); exit(0);for (Account *i = head; i; i = i-next)/ 写入账户信息fprintf(fp, %s %s %f %sn, i-no, i-name, i-balance, i-password); fclose(fp);/* 修改密码 */void Modifiy() char oldpass7, newpass17, newpass27;doPR(请输

32、入原密码:);fflush(stdin);gets(oldpass);if (strlen(oldpass) != 6)PR(密码应为6位n);system(pause);continue;if (strcmp(oldpass, now_acc-password) / 解决密码输入有误,出于安全性的考虑,原密码输入错误时不提供返回功能PR(密码有误,请重新输入nn); system(pause);continue;else break; while (1);doPR(请输入六位新密码:); fflush(stdin);scanf(%s, newpass1);if (strlen(newpass

33、1) != 6)PR(密码应为6位n); system(pause);continue;PR(请再次输入新密码:); fflush(stdin);scanf(%s, newpass2);if (strcmp(newpass1, newpass2)/ 两次输入密码不一致时PR(密码不一致(输入*取消修改)n); fflush(stdin);if (getchar() = *) break;else / 输入一致时strcpy(now_acc-password, newpass1);/ 修改密码Save();/保存用户数据PR(密码修改成功!nn);system(pause);break; while (1);/* 转账 */ void Transfer()Account* aimsite;/ 转入卡号在链表中的地址long money;/ 转账金额if (now_ac

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论