方雪黛

导航

作业三

课程 软件工程
作业要求 实现ATM管理系统
作业目标 提高代码的编写能力
学号 3180701106

一、题目要求

编写一个ATM管理系统,语言不限,要求应包括以下主要功能:

(1)开户,销户

(2)查询账户余额

(3)存款

(4)取款

(5)转账(一个账户转到另一个账户)等...

允许网上查询参考,但请注意不要直接抄袭,可以理解看懂别人的代码,再自己编写

二、代码分析及运行截图

主函数

int main()
{
	char x;
	char choose; //choose为定义输入选择的变量
	int flag=1;
	struct person *Phead=NULL; //Phead为定义二层头指针
	struct per *head=NULL;    //head为定义一层头指针
	printf("*****************************\n");
	printf("**欢迎使用ATM自动取款机系统**\n");
	printf("*****************************\n");
    printf("——————————————\n");
	printf("|    1  开户                |\n");
    printf("——————————————\n");
	printf("|    2  登陆                |\n");
    printf("——————————————\n");
	printf("|    3  前台客户信息查询中心|\n");
    printf("——————————————\n");
	printf("|    4  请选择您的需求      |\n");
    printf("——————————————\n");
	scanf("%s",&x);
	system("cls");
 
	switch(x)
	{
	case '1':system("cls");
	         kaihu(head);   //调用开户函数
			 break;
 
	case '2':system("cls");
	         denglu(head);   //调用登陆函数
			 break;
 
	case '3':system("cls");
	         menu();   //调用后台菜单函数
			 break;
	}
	while(flag)
	{
		system("cls");
		menu();       //调用后台菜单函数
		choose=getchar();
		switch(choose)
		{
		case '1':chuangjian(&Phead);
			     shuchu(Phead); //调用后台输出函数
				 system("pause");
				 system("cls");
				 break;
    	case '2':chaxun1(Phead); //调用后台卡号查询函数
				 system("pause");
				 system("cls");
				 break;
    	case '3':chaxun2(Phead); //调用后台姓名查询函数
				 system("pause");
				 system("cls");
				 break;
    	case '4':
			     chaxun3(Phead); //调用后台余额查询函数
				 system("pause");
				 system("cls");
				 break;
    	case '5':shanchu(&Phead); //调用后台删除用户函数
				 system("pause");
				 system("cls");
				 break;
	    case '6':
			     zengjia(&Phead); //调用后台增加用户函数
				 system("pause");
				 system("cls");
				 break;
	    case '7':shuchu(Phead); //调用后台输出函数函数
				 system("pause");
				 system("cls");
				 break;
	    case '8':shuchu(Phead); 
				 system("pause");
				 system("cls");
				 break;
    	case '0':flag=0;
			     printf("The end.\n");
				 break;
		}
	}
	return 0;
}

开户

void kaihu(struct per *head)
{
	head=NULL;
	FILE *fp;   //定义文件指针
	struct per *p1=NULL,*p2=NULL;   //p1,p2为定义链表指针
	p1=(struct per*)malloc(sizeof(struct per));  //开辟内存单元
	      printf("请输入您的姓名:\n");  //请数据输入链表中
		  scanf("%s",p1->name);
		  printf("请设置您的卡号:\n");
		  scanf("%s",p1->ID);
		  printf("请设置您银行卡密码:\n");
		  scanf("%s",p1->mima);
		  p1->money=0;
		  p1->next=NULL;
		  printf("您的个人信息为");
		     printf("姓名:%s \n卡号:%s \n余额:%4d\n",p1->name,p1->ID,p1->money);
          if(NULL==head)           //为新用户开辟内存单元
		  {
			  head=(struct per *)malloc(sizeof(struct per));
			  head->next=p1;    //进行头插法,将其作为第一个节点
		  }
		  else    //为新增客户开辟内存单元
		  {
			  for(p2=head;p2->next!=NULL;p2=p2->next); //进行尾插
			  p2->next=p1;
		  }
		  if((fp=fopen("save.txt","ab+"))==NULL) //打开文件
		  {
			  printf("cannot poen file\n");
			  return;
		  }
		  if(fwrite(p1,sizeof(struct per),1,fp)!=1)  //将链表信息写入文件中
			  printf("file write error\n");
		      fclose(fp);
			  printf("\n");
			  printf("恭喜您开户成功,请登录\n");
			  system("pause");
			  system("cls");
			  denglu(head);
}

登录

void denglu(struct per *head)
{
	char d[20];
	char mima[20];
	int i,j;
	FILE *fp;     //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)   //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");   //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));   //申请空间
	head=p;
	while(!feof(fp))       //循环读数据直到文件尾结束
 
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;   //如果没读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;  //保存当前节点的指针,作为下一结点的前驱
		p=p->next;  //指针后移,新读入数据链到当前表尾
		
	}
	q->next=NULL;  //最后一个结点的后继指针为空
	fclose(fp);
	printf("  **********************\n");
	printf("  ***欢迎来都建设银行***\n");
	printf("  **********************\n");
	for(j=1;j<4;j++)      //限制卡号输入的次数的循环
	{
		printf("请输入您的卡号\n");
		scanf("%s",d);
		for(q=head;q!=NULL;q=q->next)   //遍历链表
		{
			if(strcmp(q->ID,d)!=0)  //核对账号
			{
			continue;   //跳出循环
			}
					else
		{
			for(i=1;i<4;i++)   //限制密码输入的次数的循环
			{
				printf("\n\n请输入您的密码\n");
				scanf("%s",mima);
				if(strcmp(q->mima,mima)!=0)      //核对密码
				{
					printf("密码不正确。请重新输入密码\n");
					system("pause");
					system("cls");
					continue;    //若密码不对,跳出循环
				}
				else
				{
					system("cls");
					caidan(head);   //调用菜单函数
				}
			}
			printf("\n\n\n您输入密码三次错误,谢谢光临\n");
			system("pause");
			system("cls");
			exit(0);
		}
	}
		
	
	printf("\n\n\n您输入的卡号有误,请重试\n");
	system("pause");
	system("cls");
}
printf("您的卡号三次输入错误,谢谢使用\n");
exit(0);
}

取款

void qukuan(struct per *head)
{
	head=NULL;   //head为链表头指针
	int i;
	FILE *fp;          //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL) //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");  //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));  //申请空间
	head=p;
	while(!feof(fp))   //循环读数据直到文件尾结束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;   //如果没有读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;   //保存当前结点的指针,作为下一个结点的前驱
		p=p->next;  //指针后移,新读入数据链到当前表尾
	}
	q->next=NULL;  //最后一个结点的后继指针为空
	fclose(fp);
	system("cls");
	printf("************************************\n");
    printf("**  1: 100元    *****    2:200元  **\n");
	printf("************************************\n");
    printf("**  3: 300元    *****    4:400元  **\n");
	printf("************************************\n");
    printf("**  5: 500元    *****    6:600元  **\n");
	printf("************************************\n");
    printf("请按要求选择您要取款的金额\n");
	scanf("%d",&i);
	if(i>6||i<=0)    //限制输入范围
	{
		printf("对不起,您的输入有误\n\n");
		return;
	}
	else
	{
		i=100*i;  //对应选项乘以一百为取款金额
		if(i>q->money)
		{
			printf("对不起,您的金额不足\n");
			system("pause");
			system("cls");
			caidan(head);   //调用取款机菜单函数
		}
		else
		{
			q->money-=i;  //对金额进行处理
			if((fp=fopen("save.txt","wb+"))==NULL)  //打开文件
			{
				printf("cannot open file\n");
				return;
			}
			if(fwrite(q,sizeof(struct per),1,fp)!=1) //将修改的信息重新写入文件
				printf("file write error\n");
			printf("您已经成功取走%d元\n",i);
			q->next=NULL;
			fclose(fp);    //关闭文件
		}
		
	}
}

存款

void cunkuan(struct per *head)
{
	int i;
	head=NULL;   //链表头指针
	FILE *fp;  //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");  //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));   //申请空间
	head=p;
	while(!feof(fp))    //循环读数据直到文件尾结束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果没读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;   //保存当前结点的指针,作为下一个结点的前驱
		p=p->next;   //指针后移,新读入数据链到当前表尾
	}
	q->next=NULL;   //最后一个结点的后继指针为空
	fclose(fp);
	system("cls");
	printf("您卡上原有余额%d元\n",q->money);   
	printf("************************************\n");
    printf("**  1: 100元    *****    2:200元  **\n");
	printf("************************************\n");
    printf("**  3: 300元    *****    4:400元  **\n");
	printf("************************************\n");
    printf("**  5: 500元    *****    6:600元  **\n");
	printf("************************************\n");
    printf("请选择您要存入的余额\n");
	scanf("%d",&i);
	if(i>6||i<=0)
	{
		printf("对不起,您的输入有误\n\n");
		return;
	}
	else
	{
		i=100*i;
		q->money+=i;
		if((fp=fopen("save.txt","wb+"))==NULL)   //打开文件
		{
			printf("cannot open file\n");
		}
		if(fwrite(q,sizeof(struct per),1,fp)!=1)  //将修改的密码重新写入文件
			printf("file write error\n");
	    	printf("您已经成功存取%d元\n",i);
			q->next=NULL;
			fclose(fp);
			system("pause");
			system("cls");
	}
}

转账

void zhuanzhang(struct per *head)
{
	head=NULL;
	FILE *fp;  //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");  //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));   //申请空间
	head=p;
	while(!feof(fp))    //循环读数据直到文件尾结束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果没读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;   //保存当前结点的指针,作为下一个结点的前驱
		p=p->next;   //指针后移,新读入数据链到当前表尾
	}
	q->next=NULL;   //最后一个结点的后继指针为空
	fclose(fp);
	int i,j,k;
	printf("请输入帐号号码\n");
	scanf("%d",&i);
	printf("请再次输入帐号号码\n");   //核对卡号
	scanf("%d",&j);
	if(i!=j)
	{
		printf("两次账号不同,请重新输入\n");
		zhuanzhang(head);
	}
	else
	{
		system("cls");
	printf("************************************\n");
    printf("**  1: 100元    *****    2:200元  **\n");
	printf("************************************\n");
    printf("**  3: 300元    *****    4:400元  **\n");
	printf("************************************\n");
    printf("**  5: 500元    *****    6:600元  **\n");
	printf("************************************\n");
    printf("请输入转账金额\n");
	scanf("%d",&k);
	if(k>6||k<=0)
	{
		printf("对不起,您的输入有误\n\n");
		return;
	}
	else
	{
		k=k*100;
		if(k>q->money)    //对余额进行判断
		{
			printf("对不起,您的余额不足\n");
			system("pause");
			system("cls");
			caidan(head);
		}
		else
		{
			printf("您已成功转账%d元\n",k);
			q->money-=k;
			if((fp=fopen("save.txt","wb+"))==NULL)
			{
				printf("cannot open file\n");
				return;
			}
			if(fwrite(q,sizeof(per),1,fp)!=1)  //将数据重新写入文件
				printf("file write error\n");
			q->next=NULL;
			fclose(fp);
			system("pause");
			system("cls");
		}
	}
	}
}

查询

void chaxun(struct per *head)
{
	head=NULL;  //链表头指针
	FILE *fp;  //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");  //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));   //申请空间
	head=p;
	while(!feof(fp))    //循环读数据直到文件尾结束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果没读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;   //保存当前结点的指针,作为下一个结点的前驱
		p=p->next;   //指针后移,新读入数据链到当前表尾
	}
	q->next=NULL;   //最后一个结点的后继指针为空
	fclose(fp);
	printf("您卡上原有余额%d元\n\n",q->money);
	system("pause");
	system("cls");
}

☆修改密码☆

void xgmm(struct per *head)
{
	head=NULL;          //链表头指针
	char mima[20];
	FILE *fp;  //定义文件指针
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //打开一个二进制文件,为读方式
	{
		printf("不能打开文件\n");  //如不能打开,则结束程序
	}
	p=(struct per*)malloc(sizeof(struct per));   //申请空间
	head=p;
	while(!feof(fp))    //循环读数据直到文件尾结束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果没读到数据,跳出循环
		p->next=(struct per *)malloc(sizeof(struct per));  //为下一个结点申请空间
		q=p;   //保存当前结点的指针,作为下一个结点的前驱
		p=p->next;   //指针后移,新读入数据链到当前表尾
	}
	q->next=NULL;   //最后一个结点的后继指针为空
	fclose(fp);
	printf("请输入您的原密码\n");
	scanf("%s",mima);
	if(strcmp(q->mima,mima)==0)   //核对密码
	{
		{
			printf("密码正确\n");
			printf("请输入您的新密码:\n");
			scanf("%s",q->mima);
			if((fp=fopen("save.txt","wb+"))==NULL)  //文件头指针
			{
				printf("cannot open file\n");
			}
			if(fwrite(q,sizeof(struct per),1,fp)!=1)    //将修改的密码重新写入文件
				printf("file write error\n");
			fclose(fp);
			printf("修改密码成功\n\n\n\n\n");
		}
	}
	else
	{
		printf("您输入的密码与原密码不同\n");
		return;
		system("pause");
	}
	q->next=NULL;
}

主菜单

void caidan(struct per *head)
{
	head=NULL;
	int i;      //i为客户选择输入的变量
	while(1)
	{
		printf("请选择您需要的业务\n");      //银行业务菜单
		printf("*********************************\n");
		printf("**  1 取款   *****   2 查询    **\n");
		printf("*********************************\n");
		printf("**  3 转账   *****   4 修改密码**\n");
		printf("*********************************\n");
		printf("**  5 存款   *****   6 退出    **\n");
		printf("*********************************\n");
		scanf("%d",&i);
		if(i<6||i>0)
		{
			switch(i)
			{
			case 1:qukuan(head);       //调用银行取款函数
			       system("pause");
				   system("cls");
				   break;
			case 2:system("cls");
				   chaxun(head);  //调用银行查询函数
				   break;
            case 3:system("cls");
				   zhuanzhang(head);  //调用银行转账函数
				   break;
            case 4:system("cls");
				   xgmm(head);  //调用银行修改密码函数
				   break;
            case 5:system("cls");
				   cunkuan(head);  //调用银行存款函数
				   break;
            case 6:system("cls");
				   tuichu();  //调用银行退出函数
				   break;
			}
		}
		else
		{
			printf("您的输入有误\n");
			system("pause");
			system("cls");
		}
	}
}

运行截图

主菜单

开户

登录


存款

取款

转账


修改密码

★个人小结

1)在软件开发中,掌握时间是一个很重要的技能,请通过psp表格做到:

a.理清开发的完整环节,争取在每个环节都有实际的工作,一开始边界不清楚是正常的,但请尝试按照自己的理解努力对应每个环节的实际工作

b.预估每个环节的时间,并真实统计这些环节的耗时,在完成后填写完整的psp耗时表

c.这些表格是给自己看的,请不要伪造数据

d.psp表格模板如下,表格里的时间只是示意

psp2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 25 30
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 25 10
Development 开发 200 400
Analysis 需求分析(包括学习新技术) 25 30
Design Spec 生成设计文档 40 30
Design Review 设计复审 40 35
Coding Standard 代码规范 15 20
Design 具体设计 15 10
Coding 具体编码 120 150
Code Review 代码复审 20 10
Test 测试(自我测试,修改代码,提交修改) 30 30
Reporting 报告 15 10
Test Report 测试报告 20 15
Size Measurement 计算工作量 20 15
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 20 25
2)当你完成所有工作,你可以把你遇到的问题,如何解决变成经验与大家分享,共同进步
本次作业让我复习了一遍以前学过的编程知识,受益良多

posted on 2020-11-17 22:45  方雪黛  阅读(111)  评论(0编辑  收藏  举报