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

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);
	  }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值