ImageVerifierCode 换一换
格式:DOCX , 页数:38 ,大小:425.32KB ,
资源ID:4216176      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4216176.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C语言模拟ATM机.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C语言模拟ATM机.docx

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

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

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

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

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

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

7、clude #define PR printftypedef 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 struct char no17; Date date; double number;Record;/记录Account *head = NULL;/账户信息链表表头Account

8、*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();/输出余额void Printetail();/输出明细/-void Mod

9、ifiy();/修改密码/-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 choose; InitializeAccount();/

10、导入账户信息 Login();/登录 do system(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+-+-+ +-+-+nn);

11、 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(

12、pause); 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,

13、temp.no, temp.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() do char no17; system(cls); PR(nnnnttt请输入16位卡号:); fflush(stdin); gets(no); if (strlen(no

14、) != 16) 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;

15、 char a = 2;/计算剩余可输错密码次数 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) /输错

16、密码三次,锁定账户 PR(nn您的登陆密码今日连续输错三次,已被临时锁定,次日将自动解锁,或当日持本人有效证件到柜台办理密码重置。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;

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

18、localtime(&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

19、 1; fclose(fp); 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(L

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

21、p); fclose(fp); 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

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

23、(stdin); choose = getchar(); switch (choose) case 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-

24、balance); PR(tt+-+-+nnnnnnn);/*输出明细*/void Printetail() FILE *fp; Record temp; int flag = 1;/当有记录时,置0 if (!(fp = fopen(records.txt, r) PR(无存取记录,请进行存取后再使用本功能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.day, temp.number); PR(+-+-+n); PR(| 日期

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1