rime的c语言笔记--图书管理系统测试解读以及分析

#include <stdio.h> 
#include <string.h>
#include <stdlib.h> 
#include <conio.h>  
#define M 3 //将m定义成3
#define N 100//n==100

typedef struct student
{
	char xuehao[20];//学号
	char xingming[20];//姓名
	int score[M];	//成绩
	int sum;
}STU;//结构体诞生
STU stu[N];//结构体的数组形态
int renshu=0;//人数,public
void menu();

void fhzjm()//返回主界面函数
{
	char biaozhi[20];
	printf("\n");
	printf("还需要操作么?如果需要操作请输入:yes,否则请输入:no\n");
	scanf("%s",biaozhi);//简单的检测用户输入代码
	if(strcmp(biaozhi,"yes")==0)
	{	
		menu();
	}
	else if(strcmp(biaozhi,"no")==0)
		exit(0);
	else 
	{
		printf("请输入正确的字符,谢谢!\n");
		fhzjm();
	}
}

//i这里是非常巧妙的做法,对删除数组帮助很大,借用i-1=真实的坐标!!!!!
void DengJi()//登记学生信息函数
{
	int rs;//
	int i,j,k=1;
	system("CLS");//清屏
	printf("请输入需要输入几个学生信息:");
	scanf("%d",&rs);
	
	for(i=renshu;i<renshu+rs;i++,k++)//可惜没有try,catch,这样输入会更加安全。如果输入字符会出现错误
	{
		printf("请输入第%d个学生的学号:",k);
		scanf("%s",stu[i].xuehao);//进行结构体的每个数组的储存,数组代表人数,每个结构体下细分内容
		printf("请输入学生的姓名:");
		scanf("%s",stu[i].xingming);
		
		printf("请输入学生%d门课的成绩",M);
		for(j=0;j<M;j++)
		{
			printf("请输入第%d门课的成绩:",j+1);
			scanf("%d",&stu[i].score[j]);
			stu[i].sum += stu[i].score[j];
		}
		
	}
	renshu=renshu+rs;//将输入的人数返回,相当于记录了人数
	
	fhzjm();//初始化软件,方便使用,当然是返回到对应的函数,不过这个确实是对用户体验很有好处
	
}


void ShanChu()//删除全部学生信息或者指定学生信息的函数
{	
	char shanchuinfo[10];
		system("CLS");
	printf("删除全部学生信息请输入\"all\",删除指定学号的学生信息请输入\"one\"\n");//简单的反转意
    scanf("%s",shanchuinfo);//将输入的字符储存进入
	if(strcmp(shanchuinfo,"all")==0)//假设为all,比较字符串,在strcmp下,相同返回0,否返回非零
	{
		renshu=0;//人数为零,他也就为零了,真是个聪明的做法,就是不知道内存怎么办
		printf("删除成功\n\n");
	}
	else if(strcmp(shanchuinfo,"one")==0)
	{
		struct student *p=NULL;//null初始化值
		char choice[20];
		int i,j,k=0;
		printf("请输入你要删除的人的学号:");
		scanf("%s",choice); 
		for(i=0;i<renshu;i++)
		{
			if(strcmp(choice,stu[i].xuehao)==0)//一个一个查下去,检查是否相同,相同则尽心
			{
				k=1;j=i;break;//j将i记录了
			}
		}
		
		if(k)//只是为了防止k没有被更新新的值
		{
			if(renshu==1)
			{
                p=&stu[0];
                free(p);//释放p的内存
                renshu=0;//变0
			}
			else
			{
				for(i=j;i<renshu;i++)
				{
					stu[i]=stu[i+1];//用前一个覆盖后一个,参考数据结构
				}
				renshu=renshu-1;//减去人数
			}
			printf("删除成功\n\n");
			
		}
		
	}
	else//检测错误代码
	{
		printf("输入数据错误!\n");
		ShanChu();
		
	}
	fhzjm();
}


void LiuLan()//查看所有学生的信息函数
{
	
	int i,j;
	system("CLS");
	if(renshu==0)
	{
		printf("系统里面没有任何学生的信息!\n");	//简单的防止报错问题,利用人数是否为0来做扳机	
		
	}
	else
	{
		for(i=0;i<renshu;i++)//简单的for循环打印
		{
			printf("第%d个学生的学号为:%s\n",i+1,stu[i].xuehao);
			printf("第%d个学生的姓名为:%s\n",i+1,stu[i].xingming);
			for(j=0;j<M;j++)
			{
				printf("第%d个学生的第%d门课的成绩:%d\n",i+1,j+1,stu[i].score[j]);
				
			}
         printf("第%d个学生的总成绩为:%d\n",i+1,stu[i].sum);
			
		}
	}
	fhzjm();//返回该函数,优化用户体验
	
	
}

void ChaZhao()//根据不同的方式查找学生信息函数
{
	char choice[10],xx[20];
	int i,j,k=0;
		system("CLS");

	if(renshu==0)
	{
		printf("系统里面没有任何学生的信息!\n");
		fhzjm();
		
	}
	printf("三种查找方式:学号,姓名,成绩,请输入查找方式:");
	scanf("%s",choice);
	 if(strcmp(choice,"学号")==0)
	{
		printf("请输入需要查找学生的学号:");
		scanf("%s",xx);
		for(i=0;i<renshu;i++)//靠学号检索
		{
			if(strcmp(xx,stu[i].xuehao)==0)
			{
				j=i;k=1;break;//提取j
			}
		}
		if(k==0)//简单的查找错误代码,不过k==0前写方便
        	printf("输入信息有误:\n");
		else//打印对的值
		{
			printf("您所查找的学生的信息为:\n");
			printf("----学号----姓名----英语成绩----高数成绩----计算机成绩\t\n");
			printf("------%s------%s-------%d---------%d-------------%d\t\n",stu[j].xuehao,stu[j].xingming,stu[j].score[0],stu[j].score[1],stu[j].score[2]);
		}
	
	}
	else if(strcmp(choice,"姓名")==0)//为什么不用swicth 
	{
		printf("请输入需要查找学生的姓名:\n");
		scanf("%s",xx);
		for(i=0;i<renshu;i++)//相同思路不多说
		{
			if(strcmp(xx,stu[i].xingming)==0)
			{
				j=i;k=1;break;
			}
		}
		if(k==0)
        	printf("输入信息有误:\n");
		else
		{
			printf("您所查找的学生的信息为:\n");
			printf("----学号-----姓名-----英语成绩-----高数成绩-------计算机成绩---\n");
			printf("----%s-----%s-----------%d-----------%d---------------%d---\n",stu[j].xuehao,stu[j].xingming,stu[j].score[0],stu[j].score[1],stu[j].score[2]);
		}
		
	}
	else if(strcmp(choice,"成绩")==0)//逻辑相同不多说
	{
		printf("请输入需要查找学生的成绩:\n");
		scanf("%s",xx);
		for(i=0;i<renshu;i++)
		{
			if(strcmp(xx,stu[i].xingming)==0)
			{
				j=i;k=1;break;
			}
		}
		if(k==0)
          printf("输入信息有误:\n");
		else
		{
			printf("您所查找的学生的信息为:\n");
			printf("----学号-----姓名-----英语成绩-----高数成绩-------计算机成绩---\n");
			printf("----%s-----%s-----------%d-----------%d---------------%d---\n",stu[j].xuehao,stu[j].xingming,stu[j].score[0],stu[j].score[1],stu[j].score[2]);
		}
	
	}

	
	fhzjm();
	
	
}
void PaiXu()//根据总成绩从高到底排序
{
	struct student *p1[N],**p2,*temp;
	int i,j;
	system("CLS");
	p2=p1;
	//将数组的初始地址赋给指针数组
	   for( i=0;i<renshu;i++)
	   {
           
		   p1[i]=stu+i;
	   }
	   
	   //冒泡法排序 
	   
	   for( i=0;i<renshu;i++)
	   {
		   for( j=i+1;j<renshu;j++)//申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到“->”。
		   {
			   if((*(p2+i))->sum<(*(p2+j))->sum)//第一眼仿佛来到了c++,访问符号
			   {
				   temp=*(p2+i);
				   *(p2+i)=*(p2+j);
				   *(p2+j)=temp;
			   }//交换内容
		   }
	   }
	   
	   
	   printf("按照总成绩排序之后的信息为:\n");
	   printf("----学号-----姓名------总成绩----\n");
	   for( i=0;i<renshu;i++)
	   {
           printf("----%s-----%s---------%d\n",(*(p2+i))->xuehao,(*(p2+i))->xingming,(*(p2+i))->sum);//同理,->取出对应数据
	   }
	   
	   fhzjm();
	   
	   
}


void CunChu()//size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)   源码
{
	int i;
	FILE *rs;//在stdio.h 头文件中,FILE类是一个结构体
	if((rs=fopen("card.dat","wb"))==NULL)
	{
		printf("not open");
		exit(0);//exit(0) 表示程序正常退出
	}
	for(i=0;i<renshu;i++)
	{
		fwrite(&stu[i], sizeof(stu[i]), 1, rs);//流向的指针,长度,按照什么长度进行分段,储存在哪里
	}
	if(ferror(rs))
	{
		fclose(rs);
		perror("写文件失败!\n");//错误进行的代码
		return;
	}
    printf("存储文件成功!\n");
    fclose(rs); //关闭文件
   	fhzjm();
	
}

void DaoChu()//没学过文件2333
{
	struct student t;//生成结构体 t
	int i=0;
	FILE* fp = fopen("card.dat", "rb");//打开文件,文件指针名=fopen(文件名,使用方法)
	renshu=0;//人数等于0
	if(NULL==fp)
	{
		perror("读取文件打开失败!\n");
		return;
	}
	memset(stu,0x0,sizeof(stu));//某个内存值变成ascll,内存的初始化工作
	
	while(1)//死循环,但if中有对应的
	{
		fread(&t,sizeof(t),1,fp);
		if(ferror(fp))
		{
			fclose(fp);//关闭一个打开的文件
			perror("读文件过程失败!\n");//错误了返回他
			return;
		}
		if(feof(fp))
		{
			break;
		}
		stu[i]=t;
		i++;
	}
	
	fclose(fp);
    renshu=i;
	printf("导出文件成功!\n");
	fhzjm();
	
}

void menu()//初始化阶段准备的函数,进行人机更好互动的东西
{
	
	int n;//生成数字空间,应该是为输入准备的
	system("CLS");//清屏,clearbackground
	printf("           学生信息管理系统\n");
	printf("                作者:****\n");
	printf("-------------------MENU-----------------\n");
	printf("         1.登记学生信息\n");
	printf("         2.删除学生信息\n");
	printf("         3.浏览所有已经登记的学生\n");
	printf("         4.查找\n");
	printf("           4.1.按学号查找\n");
	printf("           4.2按姓名查找\n");
	printf("           4.3按成绩查找\n");
	printf("         5.根据总成绩排序\n");
	printf("         6.存储到文件\n");
	printf("         7.从文件导出\n");
	printf("         8.退出系统\n");
	
a:	printf(" 请选择:");//goto 链接
    scanf("%d",&n);
	
	switch (n)//获取相对信息,转跳到对应部门处理
	{
	case 1:
		DengJi();break;
	case 2:
		ShanChu();break;
	case 3:
		LiuLan();break;
	case 4:
		ChaZhao();break;
	case 5:
		PaiXu();break;
	case 6:
		CunChu();break;
	case 7:
		DaoChu();break;
	case 8:
		exit(0);break;
	default:		
		{
			printf("请输入1-8之间的数字,谢谢!\n");//防止输入越界
			goto a;//跳转函数,这里可以改进,将判断代码封装,然后加入while循环,goto函数还是不太稳定
		}
		
	}
	
	
	
}

main()//c89/c99/c11没有要求,相等于void函数
{
	menu();//
	
}



//#include <stdio.h>
 
//int main()                         文件打开案例
//{
	//FILE* fp;  指针
	//int c;

	//fp = fopen("file.txt", "r");
	//while (1)
	//{
		//c = fgetc(fp);
		//if (feof(fp))
		//{
			//break;
		//}
		//printf("%c", c);
	//}
	//fclose(fp);
	//return(0);
//}

//#include<stdio.h>
 
//int main ()         生成文件方法示例   显示的内容就是This is runoob.com   创建了一个叫做file.text
//{
  // FILE *fp;
   //char str[] = "This is runoob.com";
 
   //fp = fopen( "file.txt" , "w" );
   //fwrite(str, sizeof(str) , 1, fp );
 
   //fclose(fp);
  
   //return(0);
//}

关于思路

如何优化使用者的用户体验是很重要的事情,分函数写清楚对应的功能,进行拼接和整合。

关于改进

代码还是没有接触面向对象的一点点思路,我更希望可以利用多种函数进行拼接处理

将函数方法化,减少与用户的互动,以提高代码整洁和干净程度。

关于待学习

file
一系列file用法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rime_neko

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值