C语言模拟ATM机

上传人:xuey****n398 文档编号:164654784 上传时间:2022-10-25 格式:DOC 页数:33 大小:590KB
收藏 版权申诉 举报 下载
C语言模拟ATM机_第1页
第1页 / 共33页
C语言模拟ATM机_第2页
第2页 / 共33页
C语言模拟ATM机_第3页
第3页 / 共33页
资源描述:

《C语言模拟ATM机》由会员分享,可在线阅读,更多相关《C语言模拟ATM机(33页珍藏版)》请在装配图网上搜索。

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

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

3、有:no(帐户号)、name(姓名)、balance(余额)l “存取款记录”结构体Record,:成员有:no(帐户号)、date(日期)、number(数量,可正可负,正表示存款,负表示取款)3. 帐户信息存放在accounts.txt文件,储户存取款记录保存在records.txt中;4. 采用模块化程序设计方法来实现,即main()显示主菜单、调用相关函数实现相应功能,起主控作用。5. 附加功能:l 储户一天内输错密码的次数不能超过3次,否则无法进入系统;l 应避免输入存款金额、取款金额为负数等异常情况的出现。三、 程序已经实现的功能点实验要求均已实现。此外还有: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()函数和fflush()函数的简单使用六、 设计心得1. 各函数的功能要相对独立,逐步求精。2. 如果函数的参数为指针,且仅作为输入参数,则应在类型前加const,以防止该指针在函数体内被意外修改附:程序代码/*运行本程序前,请在本程序根目录下建立文件“accounts.txt”,格式如下:*卡号1(16位)姓名1账户余额1密码1*卡号2(16位)姓

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

8、 *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();/查询主菜单void PrintBalance();/输出余额vo

9、id 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 FreeData();/释放链表空间/-int main()char

10、 choose;InitializeAccount();/导入账户信息Login();/登录dosystem(cls);PR(tt n);PR(tt 请选择服务 n);PR(tt+-+-+ +-+-+n);PR(tt|5|33转 账| |查 询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+-+

11、-+ +-+-+nn);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(p

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

13、mp.name, &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)PR(卡号应为16位n);syst

14、em(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;/计算剩余可输错密码次数dochar password7;

15、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)/被锁定则返回0FILE *fp;char CruuentTime11;/当前日期char ArchiveTime11;/锁卡档案日期char t17;if (!(fp = fopen(LockAccount.txt, a+)/课本上讲以“a”方式打开文件,若文件不存在,会出错。VS20

17、13实测,并不会出错,而是新建。为免第一次使用本程序时,根目录下没有LockAccount.txt而导致出错,故此处不采用“r”方式。PR(07);/响铃PR(LockAccount.txt无法打开nn);exit(0);rewind(fp);/获取当前日期time_t rawtime;struct tm * timeinfo;time(&rawtime);/获取时间,以秒计,从1970年1月一日起算,存于rawtimetimeinfo = localtime(&rawtime);/转为当地时间,tm 时间结构strftime(CruuentTime, 11, %Y-%m-%d, timein

18、fo);/格式化时间fgets(ArchiveTime, 11, fp);/获取锁卡档案时间if (strcmp(ArchiveTime, CruuentTime)/若无锁卡档案,或锁卡档案日期与当前日期不同,则无账户被锁定fclose(fp);return 0;while (fscanf(fp, %s, t) = 1)if (!strcmp(t, no)/锁卡档案中,包含此卡号,返回1fclose(fp);return 1;fclose(fp);return 0;/锁卡档案中,不含此卡号,返回0/*查找卡号对应账户信息在链表中的地址*/Account* FindbyNo(const char

19、 *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, r)PR(07);/响铃PR(error on open LockAccount.txt file!nn);exit(0);/获取当前日期time_t rawtim

20、e;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);if (strcmp(ArchiveTime, CruuentTime)/若档案日期与当前日期不同,则说明档案已过期或无档案,新建记录。if (!(fp = fopen(LockAccou

21、nt.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.txt file!nn);exit(0);/添加记录fprintf(fp, %sn, no);fclose(fp);/*查询函数主菜单*/void Demand()char choose;dosystem

22、(cls);PrintBalance();PR(ttttt +-+-+n);PR(ttttt |查询明细32|1|n);PR(ttttt +-+-+nn);PR(tt+-+-+ +-+-+n);PR(tt|0|33退出系统| | 返 回 32|2|n);PR(tt+-+-+ +-+-+nn);PR(请选择服务:);fflush(stdin);choose = getchar();switch (choose)case 1: Printetail(); break;/查询明细case 2: return;/返回case 0: FreeData(); exit(0);/退出系统default:pr

23、intf(输入错误,请重新选择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()FILE *fp;Record temp;int flag = 1;/当有记录时,置0if (!(fp = fopen(records.txt, r)PR(无存取记录,请进行存取后再使用本

24、功能nn);system(pause);return;system(cls);PR(+-+-+n);PR(| 日期 | 存取金额 |n);PR(+-+-+n);while (fscanf(fp, %s%d-%d-%d%lf, temp.no, &temp.date.year, &temp.date.month, &temp.date.day, &temp.number) = 5)if (!(strcmp(temp.no, now_acc-no)flag = 0;PR(|%d-%d-%d|%-14.2f|n, temp.date.year, temp.date.month, temp.date.

25、day, temp.number);PR(+-+-+n);PR(| 日期 | 存取金额 |n);/未免记录太多看不到表头,在最后加个表头PR(+-+-+n);if (flag)system(cls);/无记录时,清除表头PR(该卡号未有任何存取记录nn);system(pause);return;system(pause);/当有存取记录时,输出后等待/*将存款记录写入文件中*/void Log(double money, const char *no)FILE *fp;Date CruuentTime;/当前日期if (!money)/存取为零时return;if (!(fp = fopen

26、(records.txt, a)PR(07);/响铃PR(error on open records.txt file!);exit(0);/获取当前日期time_t rawtime;struct tm * timeinfo;time(&rawtime);/获取时间,以秒计,从1970年1月1日起算,存于rawtimetimeinfo = localtime(&rawtime);/转为当地时间,tm 时间结构CruuentTime.year = timeinfo-tm_year + 1900, CruuentTime.month = timeinfo-tm_mon + 1, CruuentTi

27、me.day = timeinfo-tm_mday;fprintf(fp, %sn%d-%d-%dn%fn, no, CruuentTime.year, CruuentTime.month, CruuentTime.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);P

28、R(tt|1|33 100 | | 2000 32|5|n);PR(tt+-+-+ +-+-+nn);PR(tt+-+-+ +-+-+n);PR(tt|2|33 500 | | 5000 32|6|n);PR(tt+-+-+ +-+-+nn);PR(tt+-+-+ +-+-+n);PR(tt|3|33 1000 | |其它金额32|7|n);PR(tt+-+-+ +-+-+nn);PR(tt+-+-+ +-+-+n);PR(tt|4|33退出系统| |返 回32|0|n);PR(tt+-+-+ +-+-+nn);PR(请选择服务:);fflush(stdin);scanf(%c, &choos

29、e);switch (choose)case 1: WithdrawalOt(100); break;case 2: WithdrawalOt(500); break;case 3: WithdrawalOt(1000); break;case 4: FreeData(); exit(0);case 5: WithdrawalOt(2000); break;case 6: WithdrawalOt(5000); break;case 7:dolong money;PR(请输入取款金额(50的倍数):);fflush(stdin);scanf(%ld, &money);if (money bal

30、ance balance -= money;Save();Log(-money, now_acc-no);PR(取款成功nn);system(pause);/*存款*/void Depositing()long money;doPR(请输入存款金额(50的倍数),单次存款金额不得超过20000元:);fflush(stdin);scanf(%ld, &money);if (money 20000 | money % 50)/解决输入金额为负数、超过20000、不是50的倍数的情况PR(07);/响铃PR(输入有误,请重新输入n);system(pause);continue;PR(正在处理,请

31、稍候.n);now_acc-balance += money;Save();/保存账户数据Log(money, now_acc-no);/保存存取数据PR(存款成功nn);system(pause);break; while (1);/*保存账户信息*/void Save()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(

32、fp, %s %s %f %sn, i-no, i-name, i-balance, i-password);fclose(fp);/*修改密码*/void Modifiy()char oldpass7, newpass17, newpass27;doPR(请输入原密码:);fflush(stdin);gets(oldpass);if (strlen(oldpass) != 6)PR(密码应为6位n);system(pause);continue;if (strcmp(oldpass, now_acc-password)/解决密码输入有误,出于安全性的考虑,原密码输入错误时不提供返回功能PR(

33、密码有误,请重新输入nn);system(pause);continue;elsebreak; while (1);doPR(请输入六位新密码:);fflush(stdin);scanf(%s, newpass1);if (strlen(newpass1) != 6)PR(密码应为6位n);system(pause);continue;PR(请再次输入新密码:);fflush(stdin);scanf(%s, newpass2);if (strcmp(newpass1, newpass2)/两次输入密码不一致时PR(密码不一致(输入*取消修改)n);fflush(stdin);if (getc

34、har() = *)break;else/输入一致时strcpy(now_acc-password, newpass1);/修改密码Save();/保存用户数据PR(密码修改成功!nn);system(pause);break; while (1);/*转账*/void Transfer()Account* aimsite;/转入卡号在链表中的地址long money;/转账金额if (now_acc-balance no)/解决转账双方卡号相同的情况PR(双方账户相同,请核对后重试(输入*取消转账)n);if (getchar() = *)return;continue;if (aimsit

35、e = FindbyNo(aim)break;/找到转入卡号对应信息时elsePR(未找到该卡号,输入*取消转账n);if (getchar() = *)return;continue; while (1);PR(汇款目标用户名为:%sn, CoverUpName(aimsite-name);PR(是否确认无误?(输入*确认,否则退出));fflush(stdin);if (getchar() != *)return;doPR(请输入转账金额(50的倍数):);fflush(stdin);scanf(%lu, &money);if (now_acc-balance balance -= mon

36、ey;aimsite-balance += money;Save();/保存账户数据Log(-money, now_acc-no);/当前账户存取记录Log(money, aimsite-no);/转入卡存取记录PR(转账成功nn);system(pause);break; while (1);/*掩盖部分用户名*/char *CoverUpName(const char *name)char temp20;strcpy(temp, name);int words = 0;/用于存放姓名的字数for (char* i = temp; *i; i += 2)words+;/计算姓名的字数swit

37、ch (words)case 2:temp0 = *, temp1 = *;/当姓名字数为2时,掩盖姓strcpy(temp + 1, temp + 2);/消除一个*号break;case 3:temp2 = *, temp3 = *;/当姓名字数为3时,掩盖名字中的第一个字strcpy(temp + 3, temp + 4);/消除一个*号break;default:temp0 = *, temp1 = *, temp2 = *, temp3 = *;/姓名字数大于3时,掩盖姓和名字中的第一个字strcpy(temp + 2, temp + 4);/消除两个*号return temp;/*释放链表空间*/void FreeData()Account* t;while (head)t = head;head = head-next;free(t);

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!