C语言实现学生管理系统(新版)

一、前言

时光匆匆,当年在实验室苦逼的敲代码的小学弟已经成了现在的大四老学长o(╥﹏╥)o,经过四年的洗礼,依然是个菜鸡。不过技术还是有所精进,最近考研复习数据结构又翻到了这个大一时候写的项目,然后发现有点小bug当时没有解决,于是强迫症又犯了,决定给它修好。现在针对第一版修复了以下功能:
1、增强了系统的安全性
2、修复了文件读取的错误
3、将冒泡排序修改为快速排序

如有问题可以在评论区反馈,有时间我会在修改。后续可能也会尝试使用其它数据结构来重构系统或者使用java来重写项目。

二、代码实现

#include<stdio.h>                    // bug    成绩输入时输入字母或者特殊字符会使程序崩溃 
#include<string.h>
#include <stdlib.h>
struct student                    //结构体 
{
	char ID[20];
	char name[20];
	int eng,chn,cop;          //英语 思修 体育 
    float ave;               //用来对成绩排序 
};
struct student st[10000];  //定义结构体变量 
int num=0;                //全局变量 
void  display()          //主菜单 
{
	system("color 0");
	printf("                    *欢迎使用学生成绩管理系统*                           \n");
	printf("********************************************************************************\n");
	printf("  *请用户根据以下提示进行操作(温馨提示:请在成绩录入后再使用其它功能)*    \n");
	printf("*******************************************************************************\n"); 
	printf("0.退出系统                 1.成绩录入        2.计算平均成绩        3.成绩输出\n");
	printf("4.成绩排序(按平均成绩)   5.成绩查找        6.成绩修改            7.成绩追加\n");
	printf("8.删除成绩                 9.成绩分段       10.文件存储           11.文件输出\n");
	printf("*******************************************************************************\n");
	printf("                       *如需退出系统请按0*                                      \n" );
}
void entry()         //成绩录入 
{
	int i=0;
	char a;
	while(1)
	{
		printf("请输入学号:");
		scanf("%s",st[num].ID );
		printf("请输入姓名:");
		scanf("%s",st[num].name );
		printf("请输入英语成绩:");
		scanf("%d",&st[num].eng );
		
		printf("请输入思修成绩:");
		scanf("%d",&st[num].chn );
		printf("请输入体育成绩:");
		scanf("%d",&st[num].cop );
		num++;
		printf("任意键继续,n退出:");
		getchar();
		if(getchar()=='n')
		{
			break;
		 } 
	}
	for(i=0;i<num;i++)                                //计算平均成绩 (个人) 
	{
		st[i].ave=(st[i].chn+st[i].cop+st[i].eng)/3.0;  
	}
}
void average()          //平均分(班级) 
{
	system("cls");
	display();
	float socer=0,s1=0,s2=0,s3=0;
	float aver,aver1,aver2,aver3;
	int i;
    for(i=0;i<num;i++)
    {
    	socer=socer+st[i].ave; 
	}
	aver=socer/num;
	for(i=0;i<num;i++)
	{
		s1=s1+st[i].eng; 
	}
	aver1=s1/num;
	for(i=0;i<num;i++)
	{
		s2=s2+st[i].chn; 
	}
	aver2=s2/num;
	for(i=0;i<num;i++)
	{
		s3=s3+st[i].cop; 
	}
	aver3=s3/num;
	printf("班级平均分	英语平均分	思修平均分	体育平均分\n");
	printf("------------------------------------------------------------\n"); 
	printf("%.2f		",aver);
	printf("%.2f		",aver1);
	printf("%.2f		",aver2);
	printf("%.2f		\n",aver3);
}
void OUTPUT()         //成绩输出 
{
	 system("cls");
	 display();
     int i;
     printf("%s	%s	%s	%s	%s	%s\n","学号","姓名","思修","体育","英语","平均分");
     printf("--------------------------------------------------------\n");
     for (i=0;i<num;i++)
     {
         printf("%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
     }
}
void sort(student arr[],int left,int right)              //快速排序      
{
	
	if(left>right){
		return;
	}
	student baseStu = arr[left];
	double base = arr[left].ave;
	int i = left;
	int j = right;
	student temp;
	while(i != j){
		while(arr[j].ave >= base && i<j){
			j--;
		}
		while(arr[i].ave <= base && i < j){
			i++;
		}
		if(i < j){
			temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;  
		}
	}
	arr[left] = arr[i];
	arr[i] = baseStu;
	sort(arr,left,i-1);
	sort(arr,i+1,right);
}
void displaySort(){
	system("cls");
	display();
	printf("按平均成绩排序后的结果为:\n");
	printf("----------------------------------------------------------------------\n");
	printf("%s	%s	%s	%s	%s	%s\n","学号","姓名","思修","体育","英语","平均分");
	for(int i=num-1;i>=0;i--)
	{
	  printf("%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
	}        
	printf("\n");
}
int findname(char name[])        //返回数组下标的函数         返回值为int型 
{
	int i;
	for(i=0;i<num;i++)
	{
		if(strcmp(st[i].name,name)==0)         //比较原数据与传入的数据是否相等,若相等则返回姓名下标 
		{
			return i;
		}
		else if(strcmp(st[i].ID,name)==0)     //返回ID下标 
		{
			return i;
		}
	}
	return -1;                             //若姓名和ID均没有相同的,则返回-1 
}
void display1(int a);
void find1()       //按姓名或者学号查找学生 
{
	system("cls");
    display();
    int i,t=0;
    printf("学生名单:\n");
    printf("****************************************************************************\n");
    for(i=0;i<num;i++)
    {
    	printf("%s %s\t",st[i].ID,st[i].name);
    	t++;
    	if(t==5)
    	{
    		printf("\n");
    		t=0;
    	}
    }
    printf("\n");
	while(1)
	{
	  char name[20];
	  int a;
	  printf("请输入要查询的学生信息:");
	  scanf("%s",name);
	  printf("\n");
	  getchar();                         //不可省略 
	  a=findname(name);
	  if(a==-1)
	  {
	  	printf("学生信息有误,请重新输入!\n");
	  }
	  else
	  {
	  	printf("您要查询的学生信息为:\n");
	  	printf("****************************************************************************\n");
	  	display1(a);
	  }
	  printf("任意键继续,n退出:");
	  if(getchar()=='n')
	  {
	  	break;
	  }
    }
}
void display1(int a)           //单一学生信息显示 
{
	printf("%s	%s	%s	%s	%s	%s\n","学号","姓名","思修","体育","英语","平均分");
    printf("----------------------------------------------------------------------------\n");
    printf("%s	%s	%d	%d	%d	%.2f\n",st[a].ID,st[a].name,st[a].chn,st[a].cop,st[a].eng,st[a].ave);
}
void subsection()           //成绩分段            
{
	system("cls");          //清屏函数 
    display();              //使菜单始终显示在顶端 
	int i;
	int b=0;
	int t1=0,t2=0,t3=0;
	printf("优秀学生名单:\n");       //通过三个循环将优秀、优良、差生分别累加并分类显示 
	printf("--------------------------------------------------------------------\n");
	for(i=0;i<num;i++)
	{
		b=b+st[i].chn+st[i].cop+st[i].eng;
		if(b>=211&&b<=300)
		{
			t1++;
			printf("%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
		}
		b=0;
	}
	b=0;
	printf("--------------------------------------------------------------------\n");
	printf("优良学生名单:\n");
	printf("--------------------------------------------------------------------\n");
	for(i=0;i<num;i++)
	{
		b=b+st[i].chn+st[i].cop+st[i].eng;
		if(b>=180&&b<=210)
		{
			t2++;
			printf("%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
		}
		b=0;
	}
	b=0;
	printf("--------------------------------------------------------------------\n");
	printf("差生名单:\n");
	printf("--------------------------------------------------------------------\n");
	for(i=0;i<num;i++)
	{
		b=b+st[i].chn+st[i].cop+st[i].eng;
		if(b>=0&&b<=179)
		{
			t3++;
			printf("%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
		}
		b=0;
	}
	b=0;
	    printf("\n");
		printf("********************************************************************\n");
		printf("\n");
		printf("优等生	优良生	差生\n");
		printf("--------------------------------------------------------------------\n");
		printf("%d个	%d个	%d个\n",t1,t2,t3);
		printf("\n"); 
}
void output()       //文件输出或者存储 
{
	system("cls");
    display();
	int i;
	FILE *fp;
	fp=fopen("student.txt","w+");
	if(fp==NULL)
	{
		printf("文件打开错误!");
		exit(0);
	}
	for(i=0;i<num;i++)
	{
		fprintf(fp,"%s	%s	%d	%d	%d	%.2f\n",st[i].ID,st[i].name,st[i].chn,st[i].cop,st[i].eng,st[i].ave);
		//fprintf(fp,"\n");
	}
	fclose(fp);
}
void modify()              //学生成绩修改 
{
	system("cls");
    display();
	int a;
	int i;
	char name[20];
	printf("学生名单:\n");             //显示学生的姓名以备教师查看 
	printf("**************************************************************************\n");
	for(i=0;i<num;i++)                 
	{
        printf("%s\t",st[i].name);
    }
    printf("\n");
    printf("\n");
	while(1)
	{
	printf("请输入要修改的学生的姓名:");
	scanf("%s",&name);
	a=findname(name);                //通过姓名找到数组下标 
	if(a==-1)                     //如果没找到就接收到-1,从而报错 
	{
		printf("学生信息有误!!!");
	}
	else
	{
		printf("需要修改的信息为:\n");
		display1(a);                                                             //将需要修改的学生信息显示出来 
			int q;
			printf("请输入要修改成绩的序号(1.英语 2.思修 3.体育):");         //选择要修改的科目 
			scanf("%d",&q);
			if(q==1)                                                          //判断要修改的科目 
			{
		       printf("请输入要修改的英语成绩:");
		       scanf("%d",&st[a].eng);                                      //重新输入要修改的成绩(将原先覆盖) 
		       st[a].ave=(st[a].chn+st[a].cop+st[a].eng)/3.0;              //对已修改的学生的平均分进行重新计算 
		       getchar();                                                 
		       printf("任意键继续修改,n退出:");
		       if(getchar()=='n')
		       {
			      break;
		       }
			}
			if(q==2)
			{
		       printf("请输入要修改的思修成绩:");
		       scanf("%d",&st[a].chn);                                            
		       st[a].ave=(st[a].chn+st[a].cop+st[a].eng)/3.0;
		       getchar();
		       printf("任意键继续修改,n退出:");
		       if(getchar()=='n')
		       {
			       break;
		       }
		    }
		    if(q==3)
		    {
		       printf("请输入要修改的体育成绩:");
		       scanf("%d",&st[a].cop);
		       st[a].ave=(st[a].chn+st[a].cop+st[a].eng)/3.0;
		       getchar(); 
            }
            printf("任意键继续修改,n退出:");
	        if(getchar()=='n')
	        {
	            break;
	        }
	}
	} 
}
void write()  
{
     FILE *fp;
     int i;
     if ((fp=fopen("student.txt","rb"))==NULL)
     {
         printf("不能打开文件!\n");
         return;
     }
     fseek(fp, 0, SEEK_END);
	 int nFileSize = ftell(fp);
	 fseek(fp, 0, SEEK_SET);
	 char *buf = new char[nFileSize +1+1];
	 memset(buf, 0, nFileSize +1+1);
	 fread(buf, nFileSize, 1, fp);
	 fclose(fp);
	 char *p1, *p2;
	 p2 = buf;
	 int nRet;
	 int counts = 0;
	 for(nRet = 0; nRet < 10000;nRet++)
	 {
	 	p1 = p2;
	 	while(*p2 != '\n' && *p2 != 0)
	 	{
	   		p2++; 
	    }
	 	p2[0] = 0;
	 	p2++;
	    if(sscanf(p1, "%s	%s	%d	%d	%d", &st[i].ID,&st[i].name,&st[i].chn,&st[i].cop,&st[i].eng) != 5)// num name a b c : 5
        {
        	//st[i] = st[i-1];
        	counts++;
			break;
	    }
	    i++;
	    counts++;
	 }
	num = counts - 1;
	delete buf;
    for(int i=0;i<num;i++){
     	st[i].ave = (st[i].chn+st[i].cop+st[i].eng)/3.0;
	}
	OUTPUT();
    fclose(fp);
}
void Delete()             //删除学生信息 
{
	 system("cls");
     display();
     int i;
     printf("学生名单:\n");
     printf("*************************************************\n");
     for(i=0;i<num;i++)
	 {
	 	printf("%s\t",st[i].name);
	 }
	 printf("\n");
	 printf("*************************************************\n"); 
     while(1)
     {
         char name[20];
         int a;
         printf("请输入要删除的学生姓名:");      //ID也可以实现,原理类似 
         scanf("%s",name);
         a=findname(name);                     //确定数组下标 
         if(a==-1)                            //如果返回值为-1,提醒出错 
         {
              printf("学生不存在!\n");
         }
         else
         {
              printf("你要删除的学生信息为:\n");
              display1(a);                                    //显示要删除的学生信息 
              printf("是否删除(确认请按y):");
              getchar();
              if(getchar()=='y')
              {
                   for(i=a;i<num-1;i++)
                   {
                       st[i]=st[i+1];                   //把后边的对象都向前移动
                   }
                   num--;                               //学生人数减去一,最后一位(即要删除的学生)就不会被显示了 
              }
         }
         getchar();
         printf("任意键继续,n退出:");
         if (getchar()=='n')
         {
              break;
         }
     }
}
void isEmptyWarming(){
	if(num <= 0){
		printf("请先输入学生信息!");
	}
}
int main()                 //主函数 
{
	display();                                                                                              
	char i[200];                                                                                            
	int b;                                                                                                 
	char p[30];                                                                                        
	char a[60]; 
	int flag = 0;                                                                                        
	while(1)                                                                                           
	{
		printf("请输入密码:");                     //密码   zhang                                        中国智造2025 
		scanf("%s",a);
		
		if(strcmp(a,"zhang")==0)      //设置简单的密码,如果输入的与设置的一致则程序继续运行,否则报错。 
		{
		   system("cls");
		   display();
	       while(1)
	       {
	       	   if(num <= 0){
				 printf("%s","学生信息为空,是否从文件读取(1/0):");
				 scanf("%d",&flag);
				 if(flag){
				 	printf("\n");
				 	write();
				 }else{
				 	system("cls");
				 	display(); 
				 	printf("请先输入学生信息。\n");
				 	entry();
				 }	  	
			   }else{
	           		printf("\n请选择功能:");
		       		scanf("%s",i);                                   //判断用户输入的是否在0-11数字范围内,若输入字母或特殊符号则报错!
		       		printf("\n"); 
		       		if(strcmp(i,"1")==0)b=1;
		       		else if(strcmp(i,"0")==0)b=0;                    //起 
		       		else if(strcmp(i,"2")==0)b=2;
		       		else if(strcmp(i,"3")==0)b=3;
		       		else if(strcmp(i,"4")==0)b=4;
		       		else if(strcmp(i,"5")==0)b=5;
		       		else if(strcmp(i,"6")==0)b=6;                                      
		       		else if(strcmp(i,"7")==0)b=7;
		       		else if(strcmp(i,"8")==0)b=8;
		       		else if(strcmp(i,"9")==0)b=9;
		       		else if(strcmp(i,"10")==0)b=10;
		       		else if(strcmp(i,"11")==0)b=11;                   // 终 
		       		else 
		       		{
		  	     		b=-1;
		       		}
		       		if(b>=0&&b<=11)            //b的范围在0-11之间 
		       		{
		         		switch(b)
		         		{                                                     
			        		case 1:entry();break;                              //录入信息
			        		case 2:                                            //求班级总体的平均分 
							{
								isEmptyWarming();
								average();
								break;
							}                   
			        		case 3:                                            //输出学生信息
							{
								isEmptyWarming();
								OUTPUT();break;		
							}		                            
			        		case 4:                                           //排序
							{
								isEmptyWarming();
								sort(st,0,num-1);displaySort();break;
							}                            
			        		case 5:                                          //按学号或者姓名查找
							{
								isEmptyWarming();
								find1();break;
			        		}                          
			        		case 6:                                          //修改
							{
								isEmptyWarming();
								modify();break;
							}                       
			        		case 7:entry();break;                        //追加/
			        		case 8:                                       //删除
							{
								isEmptyWarming();
								Delete();break;
							}                      
			        		case 9:                                        //成绩分段
							{
								isEmptyWarming();
								subsection();break;
							}                  
			        		case 10:                                      //输出到文件 
							{
								isEmptyWarming();
								output();break;
							}                   
			        		case 11:write();break;                   //从文件读取信息
			        		case 0:exit(0);break;                   //退出系统 
		         		}                                          
	           		}
	           		else if(b=-1)            //如果b=-1,则报错 
		       		{
	               		printf("暂未建设此功能,请重新选择!\n");
	           		}
			   	}
	       }
        }
        else
        {
    	   printf("密码错误请重新输入!\n");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

索半斤_suobanjin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值