C语言模拟ATM机PDF.pdf
- 格式:pdf
- 大小:798.81 KB
- 文档页数:33
书 山 有 路 1 一、 实验目的 通过设计一个ATM机模拟操作的程序,全面运用课程的主要知识点,巩固对模块化程序设计、文件操作的理解,提高软件编程能力。
二、 实验要求 要求每人独立完成设计,编写一个ATM机模拟操作程序。提交实验报告、源程序、程序运行截图。
1. 程序具有以下功能: 1) 登录系统: 输入卡号(16位)、密码(6位),只有卡号、密码同时正确(帐户信息存放在文件中)才能进入系统;
2) 操作功能: ⚫ 查询:查询帐户的存款余额。按任意键返回主菜单; ⚫ 修改密码:连续输入两次新密码(两次输入结果完全相同)后,新密码取代旧密码,并存放到帐户信息文件中。之后可返回主菜单; ⚫ 取款:输入50或100的倍数模拟为取款金额,请注意:取款金额不得超过帐户余额,操作后帐户余额应相应减少。之后可返回主菜单; ⚫ 存款:输入50或100的倍数模拟为存款金额,现假设存款金额不得超过20000元,操作后帐户余额应相应增加。之后可返回主菜单; ⚫ 转帐:先输入一个帐户号(已保存在帐户信息文件中),然后显示一部分用户名(如:张*山),储户确认无误后,再输入50或100的倍数模拟为转帐金额,请注意:转帐金额不得超过帐户余额,操作后帐户余额应相应减少。之后可返回主菜单; ⚫ 退出:退出系统。
2. 定义如下结构体类型: ⚫ “日期”结构体Date:成员有:year(年)、month(月)、day(日); ⚫ “帐户”结构体Account:成员有:no(帐户号)、name(姓名)、balance(余额) ⚫ “存取款记录”结构体Record,:成员有:no(帐户号)、date(日期)、number(数量,可正可负,正表示存款,负表示取款) 书 山 有 路
2 3. 帐户信息存放在accounts.txt文件,储户存取款记录保存在records.txt中; 4. 采用模块化程序设计方法来实现,即main()显示主菜单、调用相关函数实现相应功能,起主控作用。
5. 附加功能: ⚫ 储户一天内输错密码的次数不能超过3次,否则无法进入系统; ⚫ 应避免输入存款金额、取款金额为负数等异常情况的出现。
三、 程序已经实现的功能点 实验要求均已实现。此外还有: 1. 卡号、密码位数输错时,提示并返回重新输入, 2. 简化取款时的输入 3. 转账时,转账账户为原账户时,提示并返回重新输入 4. 在多个模块中添加了退出功能,无需回到主菜单即可退出系统 5. 在查询模块中加入了存取记录明细查询 四、 程序运行截图及说明 1. 登陆模块 1) 卡号不为16位时,输出提示并返回重新输入 书 山 有 路
3 2) 卡号不存在时,输出提示并返回重新输入
3) 密码位数输错时,输出提示并返回重新输入密码,不作为密码错误处理,也无需重新输入卡号
4) 密码连续输错三次时,锁定卡号,今日无法登录 书 山 有 路
4 2. 登录后的系统主菜单
3. 查询模块 1) 查询模块主菜单 书 山 有 路
5 2) 查询明细
4. 取款模块 1) 当余额不足50时,无法进入取款模块 书 山 有 路
6 2) 取款模块主菜单
3) 便捷取款 书 山 有 路
7 4) 手动输入取款金额
输错时,返回重新输入 书 山 有 路
8 5) 取款后的菜单
6) 取款完成后选择显示余额 书 山 有 路
9 5. 存款模块 1) 解决输入错误问题
2) 存款成功 书 山 有 路
10 6. 密码修改模块 1) 原密码输错时,返回重新输入,不提供退出功能 书 山 有 路
11 2) 密码位数输错、两次输入新密码不一致时,返回重新输入 书 山 有 路
12 3) 输入无误时
7. 转账模块 1) 转入卡号位数输错时,提示并返回重新输入 书 山 有 路
13 2) 未查找到该卡号时,输出提示,提供退出功能,键入除*外任意键重新输入
3) 转入卡号与当前卡号相同时,输出提示 书 山 有 路
14 4) 输出转入卡账户的部分用户名 书 山 有 路
15 5) 解决转账金额输错的问题
6) 转账成功 书 山 有 路
16 五、 采用的主要技术 1. 宏定义:由于本程序的printf语句较多,为了便于编写,故用PR代替 2. 链表:账户信息采用链表结构,内存动态分配,使用内存无限制,可以扩展到所有可以使用的内存
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 #include #define PR printf
typedef struct 书 山 有 路 17 { short int year; short int month; short int day; }Date;//日期
typedef struct Account { char no[17]; char name[20]; double balance; char password[7]; struct Account* next; }Account;
typedef struct { char no[17]; Date date; double number; }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();//查询主菜单 void PrintBalance();//输出余额 void Printetail();//输出明细 //-------------------------------------- void Modifiy();//修改密码 //-------------------------------------- void Withdrawal();//取款主界面 void WithdrawalOt(long money);//取款 //-------------------------------------- void Depositing();//存款 书 山 有 路 18 //-------------------------------------- void Transfer();//转账 char *CoverUpName(const char *name);//掩盖部分用户名 //-------------------------------------- void Log(double money, const char *no);//将存款记录写入文件中 void Save();//保存账号信息 void FreeData();//释放链表空间 //--------------------------------------
int main() { char choose; InitializeAccount();//导入账户信息 Login();//登录 do { system("cls"); PR("\t\t \n"); PR("\t\t 请选择服务 \n"); PR("\t\t+-+---------+ +---------+-+\n"); PR("\t\t|5|\33转 账| |查 询\32|1|\n"); PR("\t\t+-+---------+ +---------+-+\n\n"); PR("\t\t +---------+-+\n"); PR("\t\t |取 款\32|2|\n"); PR("\t\t +---------+-+\n\n"); PR("\t\t +---------+-+\n"); PR("\t\t |存 款\32|3|\n"); PR("\t\t +---------+-+\n\n"); PR("\t\t+-+---------+ +---------+-+\n"); PR("\t\t|0|\33退出系统| |修改密码\32|4|\n"); PR("\t\t+-+---------+ +---------+-+\n\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: