您的位置:首页 > 编程语言 > C语言/C++

自动取款机流程模拟C语言的实现

2014-08-09 12:01 603 查看
C语言实现自动取款机的流程,锻炼对文件操作的理解和结构体的 运用,和对程序的组织能力,VC++6.0环境,win 7操作系统 。

代码如下:

#include<stdio.h>
#include<string.h>
#include <stdio.h>
#include<stdlib.h>
#include<direct.h>
#include<io.h>
#include <errno.h>//包含的头文件
/********************************************************************************
作者  :     万水千山总是情
QQ      :     824955445
时间   :     2014/4/29
功能:	:	  模拟自动取款机
test    :     结构体的运用,文件的读取和写入操作
备注	:    尽量考虑到了各种错误,但是一定有所疏忽,对于错误的处理并不是都感到满意。因为只是模拟
对于某些输入内容没有过于严格的进行检验。
暂时:实现功能如下:
1.用户帐号注册和登录
2.取款,存款,转账,更改密码,余额查询。

以后有时间或者有兴趣会增加其他功能的,比如帐号注销,超级管理员之类的。
**********************************************************************************/
#define AC_USER_NAME_MIN 6 //帐号的最小长度
#define AC_PASSWD_MIN 6//用户密码长度最小值
#define ILLEAGUE_CHAR 0//用于检测帐号密码设置时候是否出现了非法字符
#define TIME_OUT     -5//检测密码输入错误次数是否超过了某个值
#define PASSWD_WRONG -6//密码错误
#define LOAD_SUCCESSFUL -7//登录成功
#define CREAT_S -9 //创建帐号成功
#define CREAT_F -10 //创建帐号失败
#define LEAGUE_CHAR -11//帐号密码输入的字符符合要求
#define UNKNOW -12 //未知错误
#define AC_USER_NAME_MAX 15 //用户名最大长度
#define USER_NAME_MAX 12 //用户姓名的最大长度
#define AC_PASSWD_MAX 12//帐号的最大长度
char root_path[255]="D:\\bank_systems\\";//根目录
char auth[255]="D:\\bank_systems\\";//根目录
struct s_user
{
char name[USER_NAME_MAX];//姓名
char account_name [AC_USER_NAME_MAX];//帐号
char account_passwd [AC_PASSWD_MAX];//密码
char balance[10];//金额
char tel[12];//电话
char auth_flag;//登录是否成功
};
struct s_user g_user;//操作成功登录的用户信息

/*读文件,可选择出错误后是否终止程序*/
void read_file(FILE *fp,char *read_path,char *des,char *error,char exit_flag)
{
int i=0;
fp=NULL;
if((fp=fopen(read_path,"r"))!=NULL)//只读方式打开文件成功
{
do
{
des[i]=fgetc(fp);
}while(des[i++]!=EOF);
des[i-1]='\0';//读取文件到目标数组
}
else
{
printf("%s\n",error);
if(exit_flag==1)//出错后根据设置的标志位判断是否退出程序
{
exit(1);
}

}
fclose(fp);//关闭文件指针
}
/*写命令,同样可以选择设置出错后退出与否.*/
void write_file(FILE *fp,char *write_path,char *src,char *error,char exit_flag)
{
fp=NULL;
if((fp=fopen(write_path,"w"))!=NULL)
{
fwrite(src,sizeof(char),strlen(src),fp);
}
else
{
printf("%s\n",error);
if(exit_flag==1)
{
exit(1);
}
}
fclose(fp);
}
//把双精度数每一个字母都存储在一个字符数组里面,方便为以后的数据写入文件,写入的是字符
void dtos(double res,char*str_send)
{
long pow[]={1,10,100,1000,10000,100000,1000000};
long temp;
int i=0;
int t=0;
int len=0;
temp=(long)(res*100);
if(res!=0)
{

for(;;)
{
if(temp>=pow[i])
{
i++;
}
else
{
break;
}
}
for(t=0;t<i;t++)
{
str_send[t]=(char)(temp/pow[i-1-t]+'0');
temp=temp%pow[i-1-t];
}
str_send[i]='\0';
len=strlen(str_send);
str_send[len+1]='\0';
str_send[len]=str_send[len-1];
str_send[len-1]=str_send[len-2];
str_send[len-2]='.';
if(str_send[0]=='.')
{
str_send[strlen(str_send)+1]='\0';
for(i=strlen(str_send);i>0;i--)
{
str_send[i]=str_send[i-1];
}
str_send[0]='0';
}
}
else
{
str_send[0]='0';
str_send[1]='\0';
}

}
//打印用户信息,注册成功时候会用到
void type_user(struct s_user *user)
{
double result=0;
char *p;
printf("帐号    :%s \n",user->account_name);
printf("密码    : %s \n",user->account_passwd);
printf("用户姓名:%s\n",user->name);
result=strtod(user->balance,&p);
printf("存款金额:    %.2f\n",result);
printf("电话号码:%s",user->tel);
}
//检查用户名是否存在
int if_name_exist(char *ac_name)
{
char path[100];
strcpy(path,root_path);
strcat(path,ac_name);
if(_access(path,0)!=-1)
{
return 1;
}
else
{
return 0;
}
}
//创建一个用户,并生成用户路径和保存用户属性的信息
int creat_user(struct s_user *user)
{
FILE *f_user=NULL;
char tem_path[80];
char tem_path1[80];
char tem_path2[80];
char tem_path3[80];
char tem_path4[80];
int test=0;
strcpy(tem_path,root_path);
strcat(tem_path,user->account_name);
strcpy(tem_path1,tem_path);
strcpy(tem_path2,tem_path);
strcpy(tem_path3,tem_path);
strcpy(tem_path4,tem_path);
test=_mkdir(tem_path);
if(test==0)
{
strcat(tem_path,"\\account.txt");//account
strcat(tem_path1,"\\password.txt");//passwd
strcat(tem_path2,"\\name.txt");//name
strcat(tem_path3,"\\deposit.txt");//d
strcat(tem_path4,"\\tel.txt");//tel
write_file(f_user,tem_path,user->account_name,"write fail",1);
write_file(f_user,tem_path1,user->account_passwd,"write fail",1);
write_file(f_user,tem_path2,user->name,"write fail",1);
write_file(f_user,tem_path3,user->balance,"write fail",1);
write_file(f_user,tem_path4,user->tel,"write fail",1);
}

return test;
}
//检查用户名是否合法
int valid_judge(struct s_user *user)
{
int i;
char c_temp;
char illeague=0;
for(i=0;*(user->account_name+i)!='\0';i++)//只能是字母和数字
{
c_temp=*(user->account_name+i);
if( (c_temp<=57&&c_temp>=48) || (c_temp<=90&&c_temp>=65)||(c_temp<=122&&c_temp>=97))
{
;
}
else
{
illeague=1;
}
}
if(illeague==1)
{
return ILLEAGUE_CHAR;
}
else
{
return LEAGUE_CHAR;
}
}
//显示账户余额
void balance_show(struct s_user *user)
{
char money_sum[10];
char auth[80];
double money;
int i=0;
FILE *f_balance=NULL;
strcpy(auth,root_path);
if(user->auth_flag==1)//用户登录是否 成功
{
strcat(strcat(auth,user->account_name),"\\deposit.txt");
read_file(f_balance,auth,money_sum,"open deposit file fail",1);
money=atof(money_sum);
printf("当前存款: %.2f\n",money);
}
}
//存款
void add_money(struct s_user *user)
{
char money_sum[10];
char auth[80];
double money;
double add;
int i=0;
FILE *f_balance=NULL;
strcpy(auth,root_path);
if(user->auth_flag==1)//检测用户是否成功
{
strcat(strcat(auth,user->account_name),"\\deposit.txt");//获取存款文件的路径
read_file(f_balance,auth,money_sum,"open deposit file fail",1);//读取余额
money=atof(money_sum);//将读取过来的字符信息转化为double型数
printf("当前存款: %.2f\n",money);
printf("请输入存款金额:\n");
scanf("%lf",&add);
money+=add;//加上存入的金额
if((f_balance=fopen(auth,"w"))!=NULL)//打开文件
{
memset(money_sum,0x00,10);//清空临时数组
dtos(money,money_sum);//将double型数每一位存放在数组
fwrite(money_sum,sizeof(char),strlen(money_sum),f_balance);//将字符数组写会原来文件
fclose(f_balance);//关闭文件指针
printf("存入: %.2f,当前存款: %.2f",add,money);//显示存款信息

}
}
}
/*和存款没有什么差别*/
void take_money(struct s_user *user)
{
char money_sum[10];
char auth[80];
double money;
double take;
int i=0;
FILE *f_balance=NULL;
strcpy(auth,root_path);
if(user->auth_flag==1)
{
strcat(strcat(auth,user->account_name),"\\deposit.txt");
read_file(f_balance,auth,money_sum,"open deposit file fail",1);
money=atof(money_sum);
printf("请输入取款金额:\n");
scanf("%lf",&take);

while(money-take<0)//余额不足提示
{
printf("当前存款不足,请重新输入. \n");
scanf("%lf",&take);
}
money-=take;
printf("成功取款 %.2f,余额为 %.2f\n",take,money);
if((f_balance=fopen(auth,"w"))!=NULL)
{
memset(money_sum,0x00,10);
dtos(money,money_sum);
fwrite(money_sum,sizeof(char),strlen(money_sum),f_balance);
fclose(f_balance);
}
}
}

/*提示用户登录*/
int user_load()
{
struct s_user user;
char exit_count=3;
char exit_count_1=3;
char ac_pass_flag=0;
int i=0;
FILE * f_passwd=NULL;
char pass_path[100];
char tem_pass[AC_PASSWD_MAX];
user.auth_flag=0;
getchar();
printf("请输入您的信息!\n\n");
printf("用户名: ");
gets(user.account_name);
while(1)
{
if(if_name_exist(user.account_name)==1)//账户存在
{
ac_pass_flag=1;
break;
}
else
{
/*用户不存在则给三次机会重新输入*/
printf("您所输入的用户名不存在,还有%d!次机会\n",exit_count);// 账户不存在
exit_count--;
gets(user.account_name);
if(exit_count==0)
{
printf("输入次数用完,请重新登录!\n");
exit(1);
}

}
}
printf("密码 : ");//提示输入密码
gets(user.account_passwd);
strcpy(pass_path,root_path);//获取用户密码所在的文件路径
strcat(strcat(pass_path,user.account_name),"\\password.txt");
if(ac_pass_flag==1)//用户名存在
{
read_file(f_passwd,pass_path,tem_pass,"password file error",1);//读取密码,出错提示错误,并且退出
while(1)
{
if(strcmp(tem_pass,user.account_passwd)==0)//密码正确登录成功
{
printf("登录成功 !\n");
user.auth_flag=1;//登录标志位赋值1
g_user=user;//结构体赋值给g_user,以后用g_user操作用户的信息,存款,取款等等
/*各种服务的函数传递的都是struct s_user *user,用一个全局的结构来操作登录成功的用户,不用清零操作*/
getchar();
return LOAD_SUCCESSFUL;
}
else
{
printf("密码错误,请重新输入,还有%d次机会!\n",exit_count_1);//密码错误给三次机会
exit_count_1--;
gets(user.account_passwd);
if(exit_count_1==0)
{
printf("密码输入次数用完,请重新登录!\n");
exit(1);
}
else
{
;
}
}
}
}
return UNKNOW;
}
/*新用户注册*/
int make_new_user()
{
struct s_user new_user;//用户结构体
double result=0;//保存账户金额
char *endptr;//错误捕捉
int i=0;
char length_flag=0;//长度标志位
char league_flag=0;//字符合法标志位
FILE *f_user=NULL;//文件指针,为写入新用户的信息到磁盘做准备
printf("欢迎注册: \n\n");
printf("请注意,帐号和密码长度最小为6,最大为12\n");
printf("请输入您的帐号: \n");
gets(new_user.account_name);
while(1)
{
//检查用户名的合法性
if(strlen(new_user.account_name)>AC_USER_NAME_MAX)
{
printf("帐号过长! \n");
gets(new_user.account_name);
}
else if(strlen(new_user.account_name)<AC_USER_NAME_MIN)
{
printf("帐号过短!\n");
gets(new_user.account_name);
}
else
{
length_flag=1;
}
if(valid_judge(&new_user)==ILLEAGUE_CHAR)
{
printf("输入的内容含有非法字符!\n");
gets(new_user.account_name);
}
else
{
league_flag=1;
}
if(length_flag==1&&league_flag==1)
break;
}
printf("请输入密码 \n");
gets(new_user.account_passwd);//获取密码
while(1)//检查密码合法性
{
if(strlen(new_user.account_passwd)>AC_PASSWD_MAX)
{
printf("密码过长! \n");
gets(new_user.account_passwd);
}
else if(strlen(new_user.account_passwd)<AC_PASSWD_MIN)
{
printf("密码过短! \n");
gets(new_user.account_passwd);
}
else
{
break;
}
}
printf("请输入姓名 \n");//获取姓名
gets(new_user.name);
printf("请输入电话号码:\n");//获取联系方式
gets(new_user.tel);
while(1)
{
if(strlen(new_user.name)>AC_USER_NAME_MAX)
{
printf("姓名内容过长 \n");
gets(new_user.name);
}
else
{
break;
}
}
printf("请输入您的存款金额.\n");//获取取款金额
gets(new_user.balance);
if((result=strtod(new_user.balance,&endptr))<0)//字符转换为double,发现输入存款金额小于0
{
strcpy(new_user.balance,"0");//存款金额就是0
}
system("cls");//清屏
type_user(&new_user);
if(creat_user(&new_user)==0)//调用creat_user真正开始将用户信息写入磁盘,
{
printf(" 创建新帐号成功.\n");
getchar();
return CREAT_S;
}
else
{
printf("创建新帐号成功.\n");
getchar();
system("cls");
return CREAT_F;
}
}
/*各种服务的函数传递的都是struct s_user *user,用一个全局的结构来操作登录成功的用户,不用清零操作*/
void trans_accounts(struct s_user *user)//转账
{
struct s_user obj_user;
int i=0;
double src_m=0;//当前用户的金额
double obj_m=0;//目标用户的金额
char src_money[10];//当前用户的金额字符数组
char obj_money[10];//目标用户的金额字符数组
double trans_money=0;//转账金额
char obj_tel[12];//目标的手机号
char obj_path[80];//保存目标用户信息的路径
char obj_path_deposit[80];//目标用户信息的存款路径
char src_path_deposit[80];//当前用户的存款路径
FILE *f_tel=NULL;//文件指针
system("cls");
getchar();
strcpy(obj_path,root_path);
if(user->auth_flag ==1)//用户登录成功了
{
printf("请输入对方的帐号:\n");//1
gets(obj_user.account_name);
if(if_name_exist(obj_user.account_name )==1)
{
printf("请输入对方的电话号码\n");//
strcat(strcat(obj_path,obj_user.account_name ),"\\tel.txt");//获取对方手机号文件路径
gets(obj_user.tel);
read_file(f_tel,obj_path,obj_tel,"open tel error",1);//电话文件打开失败提示错误后退出
if(strcmp(obj_tel,obj_user.tel)==0)//转账号码正确
{
printf("请输入转账金额 :\n");
scanf("%lf",&trans_money);
if(trans_money<0)//转账金额小于0操作
{
trans_money=0;
}
strcpy(src_path_deposit,root_path);
strcat(strcat(src_path_deposit,user->account_name),"\\deposit.txt");
read_file(f_tel,src_path_deposit,src_money,"No read src!",1);//读当前用户的金额文件,失败退出
src_m=atof(src_money);//qian
if(src_m-trans_money<0)//判断是否够用
{
printf("您的卡内存款不足!\n");
exit(1);
}
strcpy(obj_path_deposit,root_path);
strcat(strcat(obj_path_deposit,obj_user.account_name ),"\\deposit.txt");
read_file(f_tel,obj_path_deposit,obj_money,"no read obj",1);
obj_m=atof(obj_money);//将读到的字符转换为浮点数进行计算
src_m=src_m-trans_money;
obj_m=obj_m+trans_money;
//清空临时数组,然后进行double到字符的转换,最后将当前账户和目标帐号转账完成后的金额重新写入
memset(obj_money,0x00,10);
memset(src_money,0x00,10);
dtos(src_m,src_money);
write_file(f_tel,src_path_deposit,src_money,"no write src",1);
dtos(obj_m,obj_money);
write_file(f_tel,obj_path_deposit,obj_money,"no write obj",1);
printf("成功转账 %.2f,余额:%.2f  .\n",trans_money,src_m);
}
else
{
printf("手机号码错误!\n");//手机号码错误到这里执行
exit(1);
}
}
else
{
printf("帐号不存在!\n");//帐号不存在到这里执行
}
}

}
void system_init()//系统初始化
{
char cmd[30]="attrib +h ";
char root_file[20]="D:\\bank_systems";
strcat(cmd,root_file);
if(_access(root_file,0)!=-1)//判断文件系统的目录是否存在不存在就创建,并且隐藏文件夹
{
;
}
else
{
mkdir(root_file);
}
system(cmd);
}
int show_menu()//服务菜单
{
int i;
i=0;
while(1)//等待输入选择服务
{
printf("请选择您的服务选项 :\n");
printf("1:  用户登录.\n");
printf("2:新用户注册.\n");
printf("0:  退出.\n");
scanf("%d",&i);
if(i==0)
{
printf("欢迎使用,再见!\n");
exit(1);
}
if(i>2)
{
printf("您输入的信息不正确.\n");
continue;
}
else
{
return i;
}
}
}
int show_service()//这是登录成功后供选择的服务
{
int i;/*选择的数字。*/
i=0;
system("cls");
while(1)
{
printf("请选择您的服务内容:\n\n");
printf(" 1: 余额查询.\n");
printf(" 2: 取款.\n");
printf(" 3: 存款.\n");
printf(" 4: 改密码 .\n");
printf(" 5: 转账.\n");
printf(" 0: 退出.\n");
scanf("%d",&i);
if(i==0)
{
printf("欢迎使用,再见!\n");
exit(1);
}
if((i!=1)&&(i!=2)&&(i!=3)&&(i!=4)&&(i!=5))
{
printf("您输入的信息不正确.\n");
continue;
}
else
{
return(i);
}
}
}
/*更改密码*/
void change_passwd(struct s_user *user)
{
FILE *f_p=NULL;
char passwd_path[80];
char old_passwd[AC_PASSWD_MAX];
char new_passwd[AC_PASSWD_MAX];
getchar();
if(user->auth_flag==1)//用户登录成功
{
strcpy(passwd_path,root_path);
strcat(strcat(passwd_path,user->account_name),"\\password.txt");
read_file(f_p,passwd_path,old_passwd,"read passwd error",1);//打开原来的密码文件
}
printf("请输入原来密码 !\n");
gets(new_passwd);
if(strcmp(new_passwd,old_passwd)==0)
{
printf("请输入新密码 !\n");
gets(new_passwd);
printf("请重新输入新密码!\n");
gets(old_passwd);
if(strcmp(old_passwd,new_passwd)==0)
{
write_file(f_p,passwd_path,new_passwd,"change fail",1);
printf("更改密码成功 !\n");
}
else
{
printf("两次输入的密码不一致,更改密码失败.\n");
exit(1);
}
}
else
{
printf("旧密码不正确.");
}
}
void main()
{
int m_select=0;
int u_select=0;
int s_select=0;
system_init();
start:m_select=show_menu();//利用goto语句来实现跳转
if(m_select==1)
{

if(user_load()==LOAD_SUCCESSFUL)//用户登录成功了
{
while(1)
{
u_select=show_service();//返回选择的服务
while(u_select>=1&&u_select<=5)
{
if(u_select==1)
{
balance_show(&g_user);
u_select=0;
getchar();
getchar();
break;
}
if(u_select==2)
{
take_money(&g_user);
u_select=0;
getchar();
getchar();
break;
}
if(u_select==3)
{
add_money(&g_user);
u_select=0;
getchar();
getchar();
break;
}
if(u_select==4)
{
change_passwd(&g_user);
u_select=0;
getchar();
break;
}
if(u_select==5)
{
trans_accounts(&g_user);
u_select=0;
getchar();
getchar();
break;
}
}
}
}

}
else if(m_select==2)
{
getchar();
if(make_new_user()==CREAT_S)
{
goto start;
}
}
else
{
exit(1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: