2020-11-25

自动存取款机模拟系统
模拟实现一个自动存取款的系统,系统以文本菜单形式工作,要求具备以下功能:
登录功能:用户输入账户名和密码,可以登录ATM。

查询功能:登陆后,可以查询存款余额。

取款功能:登陆后,可以取款。注意:取款额不能超过存款余额。

转账功能:登陆后,可以向其他账户转账。

存款功能:登陆后,可以向账户中存款。
1.系统以文本菜单的形式显示

2.数据存储采用文件形式

3.标准的C输入输出

4.功能完善

代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<time.h> 
#define N sizeof(struct Account)
#define M sizeof(struct Money)
struct Account       //账户信息 
{
	char name[10];       //账号昵称 
	char password[18];       //密码 
	struct Account *next;   //指针域 
};
typedef struct Account Acc;
typedef Acc *Accp;
struct Money     //钱 
{
	float money;
	char time[10];//时间
	char date[10];//日期 
	struct Money *next;
};
typedef struct Money mon;
typedef mon *monp;
//函数声明区 
void HideCursor();          //隐藏光标
void color(short x);     //设置颜色
void menu();               //菜单 
Accp ff();                 //将文件中的内容读出  
void signin();               //登陆或注册 
void login();                 // 注册账号 
void logon();                  // 账号登陆   
void amend_password();      //修改密码
void add_money();     //存款 
void find_money();   //查询 
void get_money();    //取款
void transfer_money();   //转账
void save_account(Accp p);  //将p所指向的内容存入文件中
void save_money(monp p);     //将p所指向的内容存入文件中 
float Sum();          //求余额 
monp ss();
char _name[20],_password[18];       //全局变量记住当前登陆账户 
void color(short x)
{
	if(x>=0&&x<=15)
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x);
	}
	else
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x);
	}
} 
void HideCursor()     //隐藏光标
{
 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
Accp ff()               //将存账号的文件里的内容输出到链表中
{
	FILE *fp;       //文件指针 
	int n=0;
	Accp head=NULL;
	Accp p2,p;
	fp=fopen("account","a+");     //以只读的方式打开文件 
	if(fp==NULL)
	{
		printf("cannot open file\n");
	}
	else
	{
		while(!feof(fp))        //判断文件位置标志是否移动到文件末尾 
		{
		   n++;
		   	p=(Accp)malloc(N); //向内存申请一段空间 
		   fread(p,N,1,fp);     //将fp所指向的文件中的内容赋给p 
		   if(n==1)
		   {
		      head=p;
		      p2=p;
		    }
		    else             //创建链表 
		    {
		    	p2->next=p;
		    	p2=p;
			}
	    }
	    p2->next=NULL;
	}
    fclose(fp);    //关闭文件 
    return head;   //返回头指针 
}
void menu()     //菜单 
{
	system("cls");    //清屏  
	do{
		color(14);     //看着舒服的颜色
		char t;
		printf(" 自动存取款机模拟系统\n");
		printf("当前账户为:%s\n",_name);
		printf("|     1.取款          |\n");
		printf("|     2.转账          |\n");
		printf("|     3.余额          |\n");
		printf("|     4.存款          |\n");
		t=getch();                    //利用不回显函数,输入t,可以不用手动按回车键 
		switch(t)
		{
			case '1':get_money();break; 
			case '2':transfer_money();break;
			case '3':find_money();break;
			case '4':add_money();break;
			default :;break;
		}
    }while(1);       //永远为真 
}
void signin()       //登陆或注册 
{
	system("cls");
	color(12); 
	HideCursor();    //隐藏光标
	char t;
	printf("----------------------------\n");
	printf("请输入(1:登陆;2:注册.\n)");
	printf("----------------------------");
	while(1)
	{
		t=getch();
		switch(t)
		{
			case '1':logon();break;
			case '2':login();break;
			default :break;
		}
	}
}
void logon()      // 账号登陆 
{ 
	system("cls");   //清屏 
	color(10);     //设置颜色 
	Accp p,head;    
	head=ff();    //调用函数 ,返回值为头结点的指针 
    do{
	    p=head;
	    char t,c,k;
	    int i=0;;
		printf("***************************");
		printf("     登陆状态       ");
		printf("*  请输入您的账号:");
		gets(_name);
		printf("*  请输入您的密码:");
		for(;;)              //此处为输入密码不回显操作 
		{
			k=getch();       //输入k 
			if(k=='\r')      //如果输入k为回车,则跳出循环 
			{
				break;
			}
			else if(k=='\b')  //如果输入k为删除键 
			{
				if(i>0)       //如若密码还没完全删除 
				{
					printf("\b");
					printf(" ");
					printf("\b");
					i--;
				}
			}
			else              //如果输入的k既不是删除键,也不是回车键 
			{
				_password[i]=k;   //把k的值赋给_password[i]; 
				printf("*");      //输出*号,保护用户隐私 
				i++;              //密码位数加1 
			}
		}
		_password[i]='\0';
		while(p!=NULL&&strcmp(p->name,_name)!=0)   //遍历链表,寻找当前输入的账户的账号 
		{
			p=p->next;
		}
		if(p!=NULL)   //如果p不为空 
		{
	    	if(strcmp(p->password,_password)==0)     //如果输入的密码正确 
			{
				printf("正在登陆....");
				Sleep(500);      //暂停0.5秒
				system("cls");
				color(10);
				printf("登陆成功!");
				break;    //跳出循环
			}
			else      //如果输入的密码错误
			{ 
				printf("正在登陆....");
				Sleep(500);
				system("cls");
				color(10);
				printf("-------------------------\n");
				printf("| 密码错误!是否继续?  |\n");
				printf("| 1.是             2.否 |\n");
				printf("-------------------------");
				while(1)
				{
					t=getch();  //输入t    
					if(t=='1')          
					{
						system("cls");  //清屏 
						color(10); 
						break;
					}
					else if(t=='2')     //如果输入t为n,进入开始界面 
					{
						signin();break;
					}
				}
			} 
	   }
	   else              //如果p为空,即输入的账号不正确 
	   {
	   	    printf("正在登陆....");
	   	    Sleep(500);
	   	    system("cls");
	   	    color(10);
	   	    printf("-------------------------\n");
			printf("|  账号错误!是否继续? |\n");
			printf("|  1.是            2.否 |\n"); 
			printf("-------------------------");
			while(1)      //死循环防止其他按键干扰 
			{
				c=getch();
				if(c=='1')
				{  
					system("cls");
					color(10);
					break;
				}
				else if(c=='2')
				{
					signin();break;
				}
			}
	   }
    }while(1);      //永远为真 
   Sleep(500);      //暂停0.5秒 
   menu();         //账号密码均正确,进入主菜单 
}
void login()        //注册账号 
{
	
	system("cls");
	color(10); 
	Accp p1;
	p1=(Accp)malloc(N);     //向内存申请一段空间 
	do{
		color(10);
		char name[20],password[18],againpassword[18],c,k;
		int i=0;; 
		printf("**************************\n");
		printf("   正在注册\n");
		printf("*  请输入账号:");
		gets(name);
		printf("\n*  请输入密码:");
		for(;;)              //此处为输入密码不回显操作 
		{
			k=getch();       //输入k 
			if(k=='\r')      //如果输入k为回车,则跳出循环 
			{
				break;
			}
			else if(k=='\b')  //如果输入k为删除键 
			{
				if(i>0)       //如若密码还没完全删除 
				{
					printf("\b");
					printf(" ");
					printf("\b");
					i--;
				}
			}
			else              //如果输入的k既不是删除键,也不是回车键 
			{
				password[i]=k;   //把k的值赋给_password[i]; 
				printf("*");      //输出*号,保护用户隐私 
				i++;              //密码位数加1 
			}
		}
		password[i]='\0';
		i=0;
		printf("\n*  请确认您的密码:");
		for(;;)              //此处为输入密码不回显操作 
		{
			k=getch();       //输入k 
			if(k=='\r')      //如果输入k为回车,则跳出循环 
			{
				break;
			}
			else if(k=='\b')  //如果输入k为删除键 
			{
				if(i>0)       //如若密码还没完全删除 
				{
					printf("\b");
					printf(" ");
					printf("\b");
					i--;
				}
			}
			else              //如果输入的k既不是删除键,也不是回车键 
			{
				againpassword[i]=k;   //把k的值赋给_password[i]; 
				printf("*");      //输出*号,保护用户隐私 
				i++;              //密码位数加1 
			}
		}
		againpassword[i]='\0';
		if(strcmp(password,againpassword)==0)        //如果输入的两次密码均正确 
		{
			strcpy(p1->name,name);
			strcpy(p1->password,password);
			printf("正在注册....\n");
			Sleep(500);
			system("cls");
			color(12);
			printf("注册成功!\n");
			Sleep(500);         //暂停0.5秒 
			break;              //跳出循环 
		}
		else    //如果输入的两次密码不同 
		{
			printf("正在注册....");
			Sleep(500);
			system("cls");
			color(12);
			printf("|  注册失败!是否继续注册? |\n");
			printf("|  1.是               2.否  |\n"); 
			printf("-----------------------------\n");
			while(1)
			{
				c=getch();
				if(c=='1')
				{
					system("cls");
					color(12);
					break;
				}
				else if(c=='2')
				{
					signin();
					break;
				}
			}
		}
	}while(1);    //永远为真 
	save_account(p1);     //调用函数,将p1所指向的内容存储到文件中 
	printf("正在自动为您登陆....\n");
	Sleep(500);
	menu();    //注册成功后进入主菜单 
}
void save_account(Accp p1)     //将p1所指向的内容存储到文件中 
{
	FILE *fp;       //文件指针 
	fp=fopen("account","a");    //以追加的方式打开文件 
	if(fp==NULL)
	{
		printf("cannot open file\n");
	}
	if(fwrite(p1,N,1,fp)!=1)    //将p1所指向的1个大小为N的数据结构写入fp所指向的文件中 
	{
		printf("file write error\n");
	}
	fclose(fp);        //关闭文件 
}
void add_money()       //存款 
{
	do
	{
		system("cls");   //清屏 
		color(11);
		monp p;
		char t; 
		char time[10],date[10];
		p=(monp)malloc(M);   //向内存申请一段空间 
		printf("请输入您需要存入的金额:\n");
		scanf("%f",&p->money);
		getchar(); //吸收回车键 
		_tzset(); 
        _strtime(time);      
        strcpy(p->time,time);
        _strdate(date);
		strcpy(p->date,date);   
		printf("正在操作,请稍后....\n");
		Sleep(500);
		save_money(p);
		system("cls");
		printf("| 存入成功!是否继续?  |\n");
		printf("| 1.是             2.否 |\n");
		while(1)
		{
			t=getch();
			if(t=='1')
			{
				break;
			}
			else if(t=='2')
			{
				menu();
			}
		}
	}while(1);
} 
void find_money()     //查询余额 
{
	system("cls");
	color(13);
	float sum=0;
	sum=Sum();
	printf("余额为:%f\n",sum);
	printf("按任意键回到主菜单");
	getch();
	menu(); 
} 
void get_money()      //取款 
{
	do
	{
		system("cls");
		color(11);
		monp p;
		float money,sum;
		char t;
		char time[10],date[10];
		printf("请输入您要取的金额:\n");
		scanf("%f",&money); 
		getchar();//吸收回车键 
		sum=Sum();
		if(money>sum)   //如果要取的金额大于余额 
		{
			printf("余额不足,请重新输入!\n");
			Sleep(500);
			continue;    //结束本次循环 
		}
		p=(monp)malloc(M);    //向内存申请一段空间 
		_tzset(); 
        _strtime(time);      
        strcpy(p->time,time);
        _strdate(date);
		strcpy(p->date,date);  
		p->money=-money;
		save_money(p);      
		printf("正在操作,请稍后....\n");
		Sleep(500);
		system("cls");
		printf("| 取款成功!是否继续?  |\n");
		printf("| 1.是             2.否 |\n");
		while(1)
		{
			t=getch();
			if(t=='1')
			{
				break;
			}
			else if(t=='2')
			{
				menu();break;
			}
		}
	}while(1);
	
}
void transfer_money()     //转账 
{
	do
	{
		system("cls");
		color(10);
		FILE *fp1;
		monp p,head,p1;
		float money,sum=0;
		char name[20],t;
		char time[10],date[10];
		printf("请输入您要转入的账号:\n");
		gets(name);
		printf("请输入您要转出的金额:\n");
		scanf("%f",&money);
		getchar();   //吸收回车键 
		sum=Sum();
		if(money>sum)   //如果要转出的金额大于余额 
		{
			printf("余额不足!\n");
			Sleep(500);
			continue;   //结束本次循环 
		 } 
		fp1=fopen(name,"rb");    //以只读的方式打开名字为name的二进制文件  
		if(fp1==NULL)    //如果文件不存在 
		{
			printf("账户不存在!\n");
			fclose(fp1);
			Sleep(500);
			continue;
		}
		fp1=fopen(name,"ab");    //以追加的方式打开名字为name的二进制文件  
		p=(monp)malloc(M);  //向内存申请一段空间 
		p->money=-money;
		_tzset(); 
        _strtime(time);      
        strcpy(p->time,time);
        _strdate(date);
		strcpy(p->date,date);  
		save_money(p);
		p1=(monp)malloc(M);
		p1->money=money;
		strcpy(p1->time,time);
		strcpy(p1->date,date);
		if(fwrite(p1,M,1,fp1)!=1)    //将p1所指向的一个大小为M的节点 存入fp1所指向的文件中 
		{
			printf("转账失败,请重试!");
			continue;
		}
		fclose(fp1);
		printf("正在操作,请稍后....\n");
		Sleep(500);
		system("cls");
		printf("| 转账成功!是否继续?  |\n");
		printf("| 1.是             2.否 |\n");
		while(1)
		{
			t=getch();
			if(t=='1')
			{
				break;
			}
			else if(t=='2')
			{
				menu(); 
			}
		}
 
	}while(1);
}
float Sum()
{
	monp head=NULL,p;
	float sum=0;
	head=ss();
	p=head;
	while(p!=NULL)
	{
		sum+=p->money;    //求和 
		p=p->next;
	}
	if(head==NULL)
		sum=0;
	return sum;
}
monp ss()    //求余额 
{
	FILE *fp;   //文件指针 
	monp p,head=NULL,p2,pre=NULL;
	int n=0;
	//float sum=0;
	fp=fopen(_name,"ab+");   //以只读的方式打开名字为_name的二进制文件 
	if(fp==NULL)
	{
		printf("cannot open file");
	}
	else
	{
		while(!feof(fp))  //判断标记是否移动到文件末尾 
		{
			n++;
			p=(monp)malloc(M);   //向内存申请一段空间 
			fread(p,M,1,fp);     //将fp所指向的文件中的一段大小为M的 内容赋给p 
			if(n==1)
			{
				head=p;
				p2=p;
			}
			else                //创建链表 
			{
				pre=p2;
				p2->next=p;
				p2=p;
			}
			p2->next=NULL;
		}
	}
	fclose(fp);     //关闭文件 
	if(pre!=NULL)
		pre->next=NULL;
	return(head);    //返回sum值 
}
void save_money(monp p)    //将p所指向的内容存入文件中 
{
	FILE *fp;    //文件指针 
	fp=fopen(_name,"ab");   //以追加的方式打开名字为_name的二进制文件 
	if(fp==NULL)
	{
		printf("cannot open file");
	}
	if(fwrite(p,M,1,fp)!=1)   //将p所指向的一段大小为M的内容存入fp所指向的文件中 
	{
		printf("write error");
	}
	fclose(fp);    //关闭文件  
}
main()    //简洁明了的主函数~~~ 
{
	signin();   //调用函数 
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值