
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define N 100               /*定义100个学生*/
struct student
{
	int num;                /*学号*/
	char name[10];          /*姓名*/
	float score[4];         /*数学、英语、C语言、总分*/
};
void main()
{
	int cjsr(struct student stu[],int);       /*键盘输入学生成绩数据函数*/
	void cjxs(struct student stu[],int);      /*屏幕显示学生成绩数据函数*/
	void xrwj(struct student stu[],int);      /*写文件调度函数*/
	void xejzwj(struct student stu[],int);    /*写二进制文件函数*/ 
	void xwbwj(struct student stu[],int);     /*写文本文件函数*/
	int  dcwj(struct student stu[]);          /*读文件调度函数*/
	int dejzwj(struct student stu[]);         /*读二进制文件函数*/
	int dwbwj(struct student stu[]);          /*读文本文件函数*/
	void cjtj(struct student stu[],int);      /*统计函数*/
	void cjpx(struct student stu[],int);      /*排序调度函数*/
	void cjcx(struct student stu[],int);      /*查询调度函数*/
    void cjxg(struct student stu[],int rec);  /*修改学生成绩函数*/
    int cjsc(struct student stu[],int rec);   /*删除学生成绩函数*/
    struct student stu[N];                    /*学生结构体数组*/
    int ch,rec=0;                             /*学生记录数*/
    while(1)
    {
		system("cls");
		printf("               学生成绩管理系统\n");
		printf("           -----------------------\n");
		printf("              1---学生成绩输入\n");
		printf("              2---学生成绩统计\n");
		printf("              3---学生成绩排序\n");
		printf("              4---学生成绩查询\n");
		printf("              5---数据写入文件\n");
		printf("              6---从文件读数据\n");
	    printf("              7---学生成绩修改\n");	
		printf("              8---学生成绩删除\n");
		printf("              0---退出系统\n");
		printf("           -----------------------\n");
		printf("           请选择0--8：");
	    scanf("%d",&ch);
		switch(ch)
			{
				case 0:printf("退出系统！\n"); exit(0);
				case 1:rec=cjsr(stu,rec);break;   /*rec存放学生记录个数*/
				case 2:cjtj(stu,rec);break;
				case 3:cjpx(stu,rec);break;
				case 4:cjcx(stu,rec);break;
				case 5:xrwj(stu,rec);break;
				case 6:rec=dcwj(stu);break;
				case 7:cjxg(stu,rec);break;
				case 8:rec=cjsc(stu,rec);break;
				default: printf("菜单选择错误！\n");
			}
	    printf("按任意键继续...");
	    getch();
	}
}

int cjsr(struct student stu[],int rec)  /*键盘输入学生成绩数据*/
{ 
	struct student *p=stu+rec;  /*指向新录入的学生记录*/
    int xh;  
    do
	{
		system("cls");
		printf("                     请录入学生成绩\n");
        printf("--------------------------------------------------------\n");	  
        printf("第%3d位同学：\n",rec+1);
        printf("请输入学号（负数结束输入）：");
        scanf("%d",&xh);
        if (xh<0) break;        /*学号为负数时结束输入*/
        rec++;
        p->num=xh;
        printf("请输入姓名：");
        getchar();              /*吸收缓冲区回车符*/
        gets(p->name);
        printf("请输入数学成绩：");;
        scanf("%f",&p->score[0]);
        printf("请输入英语成绩：");
        scanf("%f",&p->score[1]);
        printf("请输入C语言成绩：");
        scanf("%f",&p->score[2]);
        p->score[3]=p->score[0]+p->score[1]+p->score[2];
        printf("    ");
        printf("总成绩%.2f\n",p->score[3]);
        p++;
	}while(1);
    cjxs(stu,rec);       /*调用显示函数*/
    return rec;
}

void cjxs(struct student stu[],int rec)  /*屏幕显示学生成绩数据*/
{
	struct student *p=stu;
    system("cls");
    printf("共有%3d条记录！\n",rec);
    printf("----------------------------------------------------------\n");
    printf("学号    姓名          数学      英语      C语言    总分  \n");
    printf("----------------------------------------------------------\n");
    for(p=stu;p<=stu+rec-1;p++)
		printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2],p->score[3]);
    printf("----------------------------------------------------------\n"); 
    getch();
}
void xrwj(struct student stu[],int rec)  /*写文件调度函数*/
{   char ch;
	while(1)
    {
		system("cls");
		printf("               学生成绩写入文件\n");
		printf("           ----------------------\n");
		printf("              1---写入二进制文件\n");
		printf("              2---写入文本文件\n");
		printf("              0---返回上级菜单\n");
		printf("           ----------------------\n");
		printf("           请选择0--2：");
        scanf("%d",&ch);
		switch(ch)
		{
			case 0:printf("退出写入！\n"); return;
			case 1:xejzwj(stu,rec);break;
			case 2:xwbwj(stu,rec);break;
			default: printf("菜单选择错误！\n");
		}
        printf("按任意键继续...");
        getch();
	}
}

void xejzwj(struct student stu[],int rec)  /*写二进制文件函数*/ 
{
	FILE *fp;
	char f1[10];
	struct student *p=stu;
    system("cls");
	printf("请输入文件名：\n");
	scanf("%s",f1);
	if ((fp=fopen(f1,"ab"))==NULL)
		{
			printf("打开文件出错！");
			exit(0);
		}
	fwrite(p,sizeof(struct student),rec,fp);
	fclose(fp);
}

void xwbwj(struct student stu[],int rec)  /*写文本文件函数*/
{   FILE *fp;
	char f1[10];
	int i=0;
	struct student *p=stu;
    system("cls");
	printf("请输入文件名：\n");
	scanf("%s",f1);
	if ((fp=fopen(f1,"a"))==NULL)
		{
			printf("打开文件出错！");
			exit(0);
		}
	for(p=stu;p<=stu+rec-1;p++)
		fprintf(fp,"%4d %-10s %9.2f %9.2f %9.2f %9.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2],p->score[3]);/*4+10+36+5+2=57字节*/
	fclose(fp);
}

int  dcwj(struct student stu[])  /*读文件调度函数*/
{
	char ch;
	int rec;
	while(1)
   {
		system("cls");
		printf("               从文件读出学生成绩\n");
		printf("           ----------------------\n");
		printf("              1---读二进制文件\n");
		printf("              2---读文本文件\n");
		printf("              0---返回上级菜单\n");
		printf("           ----------------------\n");
		printf("           请选择0--2：");
	    scanf("%d",&ch);
		switch(ch)
		{
			case 0:printf("退出读文件！\n"); return rec;
			case 1:rec=dejzwj(stu);break;
			case 2:rec=dwbwj(stu);break;
			default: printf("菜单选择错误！\n");
		}
	    printf("按任意键继续...");
	    getch();
	}
    return rec;
}

int dejzwj(struct student stu[])   /*读二进制文件函数*/
{   
	FILE *fp;
	int rec=0;
    char f1[10];
	struct student *p=stu;
    system("cls");
	printf("请输入文件名：\n");
	scanf("%s",f1);
	if ((fp=fopen(f1,"rb"))==NULL)
		{
			printf("打开文件出错！");
			exit(0);
		}
	while(!feof(fp))
		{
			fread(p,sizeof(struct student),1,fp);
			rec++;
			p++;
		}
    printf("读出%3d条记录！\n",--rec);
	getch();
	cjxs(stu,rec);
	fclose(fp);
	return rec;
}
int dwbwj(struct student stu[])   /*读文本文件函数*/
{   FILE *fp;
	int rec=0;
    char f1[10];
	struct student *p=stu;
    system("cls");
	printf("请输入文件名：\n");
	scanf("%s",f1);
	if ((fp=fopen(f1,"r"))==NULL)
		{printf("打开文件出错！");
		exit(0);}
    while(!feof(fp))
		{  
			fseek(fp,57*rec,0);        /*一条记录占57字节长，与写入文件时保持一致！*/
			fscanf(fp,"%4d %10s %9f %9f %9f %9f",&p->num,p->name,&p->score[0],&p->score[1],&p->score[2],&p->score[3]);
			rec++;
			p++;
		}
	printf("读出%3d条记录！\n",--rec);
	getch();
	cjxs(stu,rec);
	fclose(fp);
	return rec;
}

void cjtj(struct student stu[],int rec)  /*统计函数*/
{

  int i,j;
  float tj[4]={0};
  for(i=0;i<=3;i++)
	 for (j=0;j<=rec-1;j++)
	    tj[i]=tj[i]+stu[j].score[i];
  system("cls"); 
  printf("共有学生%3d人\n",rec);
  printf("------------------------------------------------------------\n");
  printf("                     数学       英语       C语言     总分  \n");
  printf("------------------------------------------------------------\n");
  printf("单科总分：         %9.2f  %9.2f  %9.2f  %9.2f\n ",tj[0],tj[1],tj[2],tj[3]);
  printf(" 平均分：         ");
  for(i=0;i<=3;i++)
	 printf("%9.2f  ",tj[i]/rec);
  printf("\n");
  getch();
}

void cjpx(struct student stu[],int rec)  /*排序调度函数*/
{
 void xhpx(struct student stu[],int rec);
 void xmpx(struct student stu[],int rec);
 void kcpx(struct student stu[],int rec,int);
 int ch;
 while(1)
	{
	 system("cls");
     printf("               学生成绩排序\n");
	 printf("           ----------------------\n");
	 printf("              1---按学号排序\n");
	 printf("              2---按姓名排序\n");
     printf("              3---按数学成绩排序\n");
	 printf("              4---按英语成绩排序\n");
	 printf("              5---按C语言成绩排序\n");
 	 printf("              6---按总分排序\n");	
	 printf("              0---退出排序\n");
 	 printf("           ----------------------\n");
	 printf("           请选择0--6：");
     scanf("%d",&ch);
	 switch(ch)
		{
		case 0:printf("退出排序！\n"); return;
		case 1:xhpx(stu,rec);break;
		case 2:xmpx(stu,rec);break;
		case 3:kcpx(stu,rec,0);break;
		case 4:kcpx(stu,rec,1);break;
		case 5:kcpx(stu,rec,2);break;
		case 6:kcpx(stu,rec,3);break;
		default: printf("菜单选择错误！\n");
		}
	 printf("按任意键继续...");
     getch();
	} 
}

void xhpx(struct student stu[],int rec)  /*按学号排序函数*/
{
  int i,j;
  struct student temp;
  for(i=0;i<=rec-2;i++)
	for(j=0;j<=rec-2-i;j++)
		if(stu[j].num>stu[j+1].num)
		{
		  temp=stu[j];
		  stu[j]=stu[j+1];
		  stu[j+1]=temp;
		}
  cjxs(stu,rec);
}

void xmpx(struct student stu[],int rec)  /*按姓名排序函数*/
{
  int i,j;
  struct student temp;
  for(i=0;i<=rec-2;i++)
	for(j=0;j<=rec-2-i;j++)
		if(strcmp(stu[j].name,stu[j+1].name)<0)
		{
		  temp=stu[j];
		  stu[j]=stu[j+1];
		  stu[j+1]=temp;
		}
  cjxs(stu,rec);
}

void kcpx(struct student stu[],int rec,int kh)  /*按成绩排序函数*/
{
  int i,j;
  struct student temp;
  for(i=0;i<=rec-2;i++)
	for(j=0;j<=rec-2-i;j++)
		if(stu[j].score[kh]<stu[j+1].score[kh])
		{
		  temp=stu[j];
		  stu[j]=stu[j+1];
		  stu[j+1]=temp;
		}
  cjxs(stu,rec);
}


void cjcx(struct student stu[],int rec)  /*查询调度函数*/
{
	void zgf(struct student stu[],int rec);
	void zdf(struct student stu[],int rec);
	void xhcx(struct student stu[],int rec);
	int ch;
	while(1)
		{
			system("cls");
			printf("               学生成绩查询\n");
			printf("           ----------------------\n");
			printf("              1---查询最高总分\n");
			printf("              2---查询最低总分\n");
			printf("              3---按学号查询\n");
			printf("              0---退出查询\n");
			printf("           ----------------------\n");
			printf("           请选择0--3：");
		    scanf("%d",&ch);
			switch(ch)
				{
					case 0:printf("退出查询！\n"); return;
					case 1:zgf(stu,rec);break;
					case 2:zdf(stu,rec);break;
					case 3:xhcx(stu,rec);break;
					default: printf("菜单选择错误！\n");
				}
		    printf("按任意键继续...");
	        getch();
		}
}

void zgf(struct student stu[],int rec)  /*查询最高总分函数*/
{	
	int i,k;
    float max;
    max=stu[0].score[3];
    k=0;
    for(i=0;i<=rec-1;i++)
		if(max<stu[i].score[3])
			{
			  max=stu[i].score[3];
			  k=i;
			}
	system("cls");
    printf("----------------------------------------------------------\n");
    printf("学号    姓名          数学      英语      C语言    总分  \n");
    printf("----------------------------------------------------------\n");
    printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",stu[k].num,stu[k].name,stu[k].score[0],stu[k].score[1],stu[k].score[2],stu[k].score[3]);
    getch();
}

void zdf(struct student stu[],int rec)  /*查询最低总分函数*/
{
	int i,k;
	float min;
    min=stu[0].score[3];
    k=0;
    for(i=0;i<=rec-1;i++)
		if(min>stu[i].score[3])
			{
			  min=stu[i].score[3];
			  k=i;
			}
	system("cls");
    printf("----------------------------------------------------------\n");
    printf("学号    姓名          数学      英语      C语言    总分  \n");
    printf("----------------------------------------------------------\n");
    printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",stu[k].num,stu[k].name,stu[k].score[0],stu[k].score[1],stu[k].score[2],stu[k].score[3]);
    getch();
}

void xhcx(struct student stu[],int rec)  /*按学号查询函数*/
{
	int i,xh;
    printf("请输入学号：");
    scanf("%d",&xh);
    for(i=0;i<=rec-1;i++)
		if(xh==stu[i].num)
			{
				system("cls");
				printf("----------------------------------------------------------\n");
				printf("学号    姓名          数学      英语      C语言    总分  \n");
				printf("----------------------------------------------------------\n");
				printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3]);
				getch();
				return;
			}
    printf("查无此人！");
    getch();
}

void cjxg(struct student stu[],int rec)  /*修改学生成绩函数*/
{
	int i,xh;
    printf("请输入学号：");
    scanf("%d",&xh);
    for(i=0;i<=rec-1;i++)
		if(xh==stu[i].num)
			{
				system("cls");
				printf("----------------------------------------------------------\n");
				printf("学号    姓名          数学      英语      C语言    总分  \n");
				printf("----------------------------------------------------------\n");
				printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3]);
				getch();
				printf("请输入学号：");
			    scanf("%d",&stu[i].num);
		        printf("请输入姓名：");
			    getchar();             /*吸收回车符*/
			    gets(stu[i].name);
			    printf("请输入数学成绩：");;
			    scanf("%f",&stu[i].score[0]);
			    printf("请输入英语成绩：");
			    scanf("%f",&stu[i].score[1]);
			    printf("请输入C语言成绩：");
			    scanf("%f",&stu[i].score[2]);
			    stu[i].score[3]=stu[i].score[0]+stu[i].score[1]+stu[i].score[2];
			    cjxs(stu,rec);
				return;
			}
    printf("查无此人！");
    getch();
}

int cjsc(struct student stu[],int rec)  /*删除学生成绩函数*/
{
	int i,j,xh;
    printf("请输入学号：");
    scanf("%d",&xh);
    for(i=0;i<=rec-1;i++)
		if(xh==stu[i].num)
			{
				system("cls");
				printf("----------------------------------------------------------\n");
				printf("学号    姓名          数学      英语      C语言    总分  \n");
				printf("----------------------------------------------------------\n");
				printf("%4d   %-10s %9.2f %9.2f %9.2f %9.2f\n",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3]);
				getch();
				if (i==rec-1)
					return --rec;          /*删除的是最后一条，直接删除！*/
				else
					for(j=i;j<=rec-2;j++)  /*删除的不是最后一条，后续记录依次向前移动！*/
						stu[j]=stu[j+1];
			    return --rec;
			}
    printf("查无此人！");
    getch();
    return rec;
}