C语言模拟ATM机.docx
- 文档编号:9909752
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:44
- 大小:6.52MB
C语言模拟ATM机.docx
《C语言模拟ATM机.docx》由会员分享,可在线阅读,更多相关《C语言模拟ATM机.docx(44页珍藏版)》请在冰豆网上搜索。
C语言模拟ATM机
一、实验(shíyàn)目的
通过设计(shèjì)一个ATM机模拟操作的程序,全面运用课程的主要知识点,巩固对模块化程序设计、文件(wénjiàn)操作的理解,提高软件编程能力。
二、实验(shíyàn)要求
要求每人独立完成设计(shèjì),编写一个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(数量,可正可负,正表示存款,负表示取款)
3.帐户信息(xìnxī)存放在accounts.txt文件,储户存取款记录(jìlù)保存在records.txt中;
4.采用(cǎiyòng)模块化程序设计方法来实现,即main()显示(xiǎnshì)主菜单、调用相关函数实现相应功能,起主控作用。
5.附加(fùjiā)功能:
●储户一天内输错密码的次数不能超过3次,否则无法进入系统;
●应避免输入存款金额、取款金额为负数等异常情况的出现。
三、程序已经实现的功能点
实验要求均已实现。
此外还有:
1.卡号、密码位数输错时,提示并返回重新输入,
2.简化取款时的输入
3.转账时,转账账户为原账户时,提示并返回重新输入
4.在多个模块中添加了退出功能,无需回到主菜单即可退出系统
5.在查询模块中加入了存取记录明细查询
四、程序运行截图及说明
1.登陆模块
1)卡号不为16位时,输出提示并返回重新输入
2)卡号不存在(cúnzài)时,输出提示并返回(fǎnhuí)重新输入
3)密码(mìmǎ)位数输错时,输出(shūchū)提示并返回重新输入密码,不作为密码错误处理,也无需重新输入卡号
4)密码连续(liánxù)输错三次时,锁定卡号,今日无法登录
2.登录(dēnɡlù)后的系统主菜单
3.查询(cháxún)模块
1)查询(cháxún)模块主菜单
2)查询(cháxún)明细
4.取款模块(mókuài)
1)当余额(yúé)不足50时,无法进入(jìnrù)取款模块
2)取款模块(mókuài)主菜单
3)便捷(biànjié)取款
4)手动输入(shūrù)取款金额
输错时,返回(fǎnhuí)重新输入
5)取款后的菜单(càidān)
6)取款完成(wánchéng)后选择(xuǎnzé)显示(xiǎnshì)余额
5.存款(cúnkuǎn)模块
1)解决输入错误(cuòwù)问题
2)存款(cúnkuǎn)成功
6.密码(mìmǎ)修改模块
1)原密码输错时,返回重新输入(shūrù),不提供退出功能
2)
密码(mìmǎ)位数输错、两次输入(shūrù)新密码不一致时,返回重新(chóngxīn)输入
3)输入(shūrù)无误时
7.转账(zhuǎnzhànɡ)模块
1)转入卡号位数输错时,提示并返回重新(chóngxīn)输入
2)未查找到该卡号时,输出提示,提供退出(tuìchū)功能,键入(jiànrù)除*外任意键重新(chóngxīn)输入
3)转入卡号与当前卡号相同(xiānɡtónɡ)时,输出提示
4)输出(shūchū)转入卡账户的部分用户名
5)解决转账(zhuǎnzhànɡ)金额输错的问题(wèntí)
6)转账(zhuǎnzhànɡ)成功
五、采用(cǎiyòng)的主要技术
1.宏定义(dìngyì):
由于本程序的printf语句(yǔjù)较多,为了便于(biànyú)编写,故用PR代替(dàitì)
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
#definePRprintf
typedefstruct
{
shortintyear;
shortintmonth;
shortintday;
}Date;//日期(rìqī)
typedefstructAccount
{
charno[17];
charname[20];
doublebalance;
charpassword[7];
structAccount*next;
}Account;
typedefstruct
{
charno[17];
Datedate;
doublenumber;
}Record;//记录(jìlù)
Account*head=NULL;//账户信息(xìnxī)链表表头
Account*now_acc=NULL;//当前(dāngqián)账户
/************函数(hánshù)申明************/
voidInitializeAccount();//导入账户信息
//--------------------------------------
charLockAccountTopic(constchar*no);//检测账户是否被锁定
voidLockAccount(constchar*no);//锁定账户
//--------------------------------------
voidLogin();//登录
Account*FindbyNo(constchar*no);//查找卡号对应账户信息在链表中的地址
//--------------------------------------
voidDemand();//查询主菜单
voidPrintBalance();//输出余额
voidPrintetail();//输出明细
//--------------------------------------
voidModifiy();//修改密码
//--------------------------------------
voidWithdrawal();//取款主界面
voidWithdrawalOt(longmoney);//取款
//--------------------------------------
voidDepositing();//存款(cúnkuǎn)
//--------------------------------------
voidTransfer();//转账(zhuǎnzhànɡ)
char*CoverUpName(constchar*name);//掩盖(yǎngài)部分用户名
//--------------------------------------
voidLog(doublemoney,constchar*no);//将存款(cúnkuǎn)记录写入文件中
voidSave();//保存账号(zhànɡhào)信息
voidFreeData();//释放链表空间
//--------------------------------------
intmain()
{
charchoose;
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();return0;//退出(tuìchū)
default:
printf("输入(shūrù)错误,请重新(chóngxīn)选择\n");//解决用户可能的输入(shūrù)错误
system("pause");
}
}while
(1);
return0;
}
/**********导入账户(zhànɡhù)信息**********/
voidInitializeAccount()
{
FILE*fp;
Accounttemp;
PR("系统初始化中,请稍侯...\n");
if(!
(fp=fopen("accounts.txt","r")))
{
PR("\07");//响铃
PR("读取帐户信息失败,请在本程序根目录建立帐户信息文件(accounts.txt)。
格式如下:
\n");
PR("卡号1(16位)姓名1账户余额1密码1\n");
PR("卡号2(16位)姓名2账户余额2密码2\n");
PR("……\n");
exit(0);
}
while(fscanf(fp,"%s%s%lf%s",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");//清除“系统初始化中,请稍侯...”提示
}
/**********登录**********/
voidLogin()
{
do
{
charno[17];
system("cls");
PR("\n\n\n\n\t\t\t请输入(shūrù)16位卡号:
");
fflush(stdin);
gets(no);
if(strlen(no)!
=16)
{
PR("卡号应为16位\n");
system("pause");
system("cls");
continue;
}
if(LockAccountTopic(no))
{//当该卡号被锁定(suǒdìnɡ)时
PR("\07");//响铃
PR("\n\n您的登陆密码今日(jīnrì)连续输错三次,已被临时锁定,次日将自动解锁,或当日持本人有效证件到柜台办理密码重置。
\n\n");
system("pause");
continue;
}
if(!
(now_acc=FindbyNo(no)))//将卡号对应信息(xìnxī)在链表的地址赋给now_acc
{//当卡号不存在(cúnzài)时
PR("\n\n此卡号不存在,请重新输入!
\n\n");
system("pause");
continue;
}
chara='2';//计算剩余可输错密码次数
do
{
charpassword[7];
system("cls");
PR("\n\n\n\n\t\t\t请输入16位卡号:
%s\n",now_acc->no);
PR("\n\n\t\t\t请输入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;//密码正确(zhèngquè),回到主函数
if(a=='0')
{//输错密码三次,锁定(suǒdìnɡ)账户
PR("\n\n您的登陆密码今日连续输错三次,已被临时(línshí)锁定,次日将自动解锁,或当日持本人有效证件到柜台办理密码重置。
\n\n");
LockAccount(no);
break;
}
PR("\07");//响铃
PR("密码输入错误(cuòwù),您还可以尝试%c次\n\n",a--);
system("pause");
}while
(1);
}while
(1);
}
/**********检测账户是否(shìfǒu)被锁定**********/
charLockAccountTopic(constchar*no)//被锁定则返回0
{
FILE*fp;
charCruuentTime[11];//当前日期
charArchiveTime[11];//锁卡档案日期
chart[17];
if(!
(fp=fopen("LockAccount.txt","a+")))//课本上讲以“a”方式打开文件,若文件不存在,会出错。
VS2013实测,并不会出错,而是新建。
为免第一次使用本程序时,根目录下没有LockAccount.txt而导致出错,故此处不采用“r”方式。
{
PR("\07");//响铃
PR("LockAccount.txt无法打开\n\n");
exit(0);
}
rewind(fp);
{//获取当前日期
time_trawtime;
structtm*timeinfo;
time(&rawtime);//获取时间,以秒计,从1970年1月一日起算,存于rawtime
timeinfo=localtime(&rawtime);//转为当地时间,tm时间结构
strftime(CruuentTime,11,"%Y-%m-%d",timeinfo);//格式化时间
}
fgets(ArchiveTime,11,fp);//获取锁卡档案(dàngàn)时间
if(strcmp(ArchiveTime,CruuentTime))
{//若无锁卡档案,或锁卡档案日期与当前(dāngqián)日期不同,则无账户被锁定
fclose(fp);
return0;
}
while(fscanf(fp,"%s",t)==1)
{
if(!
strcmp(t,no))
{//锁卡档案中,包含(bāohán)此卡号,返回1
fclose(fp);
return1;
}
}
fclose(fp);
return0;//锁卡档案(dàngàn)中,不含此卡号,返回0
}
/**********查找卡号对应账户信息(xìnxī)在链表中的地址**********/
Account*FindbyNo(constchar*no)
{
for(Account*i=head;i;i=i->next)
{
if(!
strcmp(i->no,no))
returni;
}
returnNULL;
}
/**********锁定账户**********/
voidLockAccount(constchar*no)
{
FILE*fp;
charCruuentTime[11];//当前日期
charArchiveTime[11];//锁卡档案日期
if(!
(fp=fopen("LockAccount.txt","r")))
{
PR("\07");//响铃
PR("erroronopenLockAccount.txtfile!
\n\n");
exit(0);
}
{//获取当前日期
time_trawtime;
structtm*timeinfo;
time(&rawtime);//获取(huòqǔ)时间,以秒计,从1970年1月1日起算,存于rawtime
timeinfo=localtime(&rawtime);//转为当地(dāngdì)时间,tm时间(shíjiān)结构
strftime(CruuentTime,11,"%Y-%m-%d",timeinfo);//格式化时间(shíjiān)
}
fgets(ArchiveTime,11,fp);
fclose(fp);
if(strcmp(ArchiveTime,CruuentTime))
{//若档案日期(rìqī)与当前日期不同,则说明档案已过期或无档案,新建记录。
if(!
(fp=fopen("LockAccount.txt","w")))
{
PR("\07");//响铃
PR("erroronopenLockAccount.txtfile!
\n\n");
exit(0);
}
fprintf(fp,"%s\n",CruuentTime);
}
else//若记录日期与当前日期相同,则追加记录
{
if(!
(fp=fopen("LockAccount.txt","a")))
{
PR("\07");//响铃
PR("erroronopenLockAccount.txtfile!
\n\n");
exit(0);
}
}
//添加记录
fprintf(fp,"%s\n",no);
fclose(fp);
}
/**********查询函数主菜单**********/
voidDemand()
{
charchoose;
do
{
system("cls");
PrintBalance();
PR("\t\t\t\t\t+---------+-+\n");
PR("\t\t\t\t\t|查询(cháxún)明细\32|1|\n");
PR("\t\t\t\t\t+---------+-+\n\n");
PR("\t\t+-+---------++---------+-+\n");
PR("\t\t|0|\33退出(tuìchū)系统||返回\32|2|\n");
PR("\t\t+-+---------++---------+-+\n\n");
PR("请选择(xuǎnzé)服务:
");
fflush(stdin);
choose=getchar();
switch(choose)
{
case'1':
Printetail();break;//查询(cháxún)明细
case'2':
return;//返回(fǎnhuí)
case'0':
FreeData();exit(0);//退出系统
default:
printf("输入错误,请重新选择\n");//解决用户可能的输入错误
system("pause");
}
}while
(1);
}
/**********输出余额**********/
voidPrintBalance()
{
system("cls");
PR("\n\n\n\n\n\n\n\n\n\
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 模拟 ATM
![提示](https://static.bdocx.com/images/bang_tan.gif)