自动取款机流程模拟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); } }
相关文章推荐
- c语言实现模拟发送报文改进版(添加程序自动打log)
- c语言:模拟实现一个输入密码自动取款的程序
- c语言:模拟实现一个输入密码自动取款的程序
- 编一个程实现模拟电子表(C语言)
- C#三种模拟自动登录和提交POST信息的实现方法
- 在FlowPortal.net中实现-请假流程审批通过后自动设定外出
- 文本框+层模拟下拉框,并实现输入自动提示和过滤
- 实现C语言自动释放资源的方法与探讨
- C#三种模拟自动登录和提交POST信息的实现方法[收藏]
- 用AJAX实现google输入自动完成的简单模拟
- 实现自动按键的方法 驱动级模拟(硬件模拟)
- C#三种模拟自动登录和提交POST信息的实现方法
- C#三种模拟自动登录和提交POST信息的实现方法
- 用AJAX实现google输入自动完成的简单模拟
- 51单片机模拟I2C总线的C语言实现
- [C语言]模拟用注册表实现自启动
- 用AJAX实现google输入自动完成的简单模拟
- 用AJAX实现google输入自动完成的简单模拟
- 用AJAX实现google输入自动完成的简单模拟
- C#三种模拟自动登录和提交POST信息的实现方法