贴学生成绩管理系统(VC测试通过)
#include<stdio.h>#include<stdlib.h>
#include<string.h>
#include<malloc.h>
//***********************函数声明*********************
int menu(); //菜单
struct scorenode *create(void); //创建链表,并返回链表的头指针
struct scorenode *load(); //调用导入学生记录函数
struct scorenode *search(struct scorenode *); //成绩查询函数
struct scorenode *del(struct scorenode *); //删除学生资料
struct scorenode *add(struct scorenode *); //追加学生资料
void print_s(struct scorenode *); //显示学生资料
void statistics(struct scorenode *); //统计学生成绩函数
void save(struct scorenode *); //保存学生资料
void sort(struct scorenode *); //排序函数
//*******************数据定义*************************
struct scorenode
{
int number; //学号
char name[10]; //姓名
float physics; //物理成绩
float english; //英语成绩
float maths; //数学成绩
struct scorenode *next; //存储下一个结点的地址
};
int n; //n为全局变量,存储录入的人数
//*********************主程序*************************
void main()
{
struct scorenode *head=NULL,*stu=NULL; //定义链表头指针为空
int k;
while(1)
{
k=menu();
switch(k)
{
case 1:head=create();break; //创建链表,录入数据
case 2:head=load();break; //调用导入学生函数
case 3:head=search(head);break; //成绩查询函数函数
case 4:head=del(head);break; //删除学生资料函数
case 5:head=add(head);break; //追加学生资料函数
case 6:print_s(head);break; //显示学生资料函数
case 7:statistics(head);break; //统计学生成绩函数
case 8:save(head);break; //保存学生的资料
case 9:sort(head);break; //排序函数
case 0:exit(0);
default:printf("输入错误,请重试!\n");
}
}
}
//*********************菜单选择界面**********************
int menu()
{
int i,k;
printf("\n\t\t\t欢迎进入成绩管理系统\n\n");
printf("\t\t\t 04电子应用\n");
for(i=0;i<80;i++)
printf("*");
printf("1.输入学生的资料\t 2.从文件调入资料\t 3.查询学生的成绩\n");
printf("4.删除学生的资料\t 5.追加学生的资料\t 6.显示学生的成绩\n");
printf("7.统计学生的成绩\t 8.保存输入的资料\t 9.对成绩进行排序\n");
printf("0.退出\n");
for(i=0;i<80;i++)
printf("*");
printf("请选择您的操作:");
scanf("%d",&k); //读取输入的选择
getchar(); //吸收回车符
return(k);
}
//***************创建链表,并返回链表的头指针******************
struct scorenode *create(void)
{
struct scorenode *head=NULL; //定义链表头指针为空
struct scorenode *p1,*p2,*p3;
int i;
n=0;
p1=p2=p3=(struct scorenode*)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
while(1)
{
printf("请输入学生资料,输(0)退出!\n");
repeat:
printf("请输入学号(学号应大于0):");
scanf("%d",&p1->number);
while(p1->number<0) //判断输入学号是否正确
{
printf("输入错误,请重新输入学号:");
scanf("%d",&p1->number);
}
getchar(); //吸收回车符
if(p1->number==0) //输入为0,退出
goto endd;
else
{
p3=head;
if(n>0)
{
for(i=0;i<n;i++)
{
if(p1->number!=p3->number) //判断输入的学号是否重复
p3=p3->next;
else
{
printf("学号重复,请重输!\n");
goto repeat;
}
}
}
}
printf("请输入姓名:");
scanf("%s",&p1->name);
printf("请输入物理,英语,数学成绩(0-100):");
scanf("%f,%f,%f",&p1->physics,&p1->english,&p1->maths);
while(p1->physics<0||p1->physics>100||p1->english<0||p1->english>100
||p1->maths<0||p1->maths>100) //判断输入的成绩数据是否正确
{
printf("输入错误,请重新输入成绩:");
scanf("%f,%f,%f",&p1->physics,&p1->english,&p1->maths);
}
getchar(); //吸收回车符
n=n+1; //录入的人数加1
if(n==1)
head=p1;
else
{
p2->next=p1;
p2=p1; //存储此次录入的数据
}
p1=(struct scorenode*)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
}
endd:
p2->next=NULL;
save(head);
return(head); //返回此次录入的链表值
}
//***********************保存学生资料************************
void save(struct scorenode *p1)
{
FILE *fp;
if((fp=fopen("scroce.txt","w"))==NULL)
{
printf("不能打开文件!\n");
}
while(p1!=NULL)
{
fprintf(fp,"%d\t%s\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths);
p1=p1->next; //下移一个结点
}
fclose(fp);
printf("文件已保存!\n");
}
//****************调用导入学生记录函数********************
struct scorenode *load()
{
FILE *fp;
struct scorenode *p1,*p2,*head;
int m=0;
if((fp=fopen("scroce.txt","r"))==NULL) //打开文件
{
printf("不能打开文件!\n");
return 0;
}
printf("\n\t\t成绩管理系统\n\n");
printf("\t\t 04电子应用\n");
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
head=NULL;
p1=p2=(struct scorenode*)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
while(!feof(fp)) //文件是否结束
{
fscanf(fp,"%d%s%f%f%f",&p1->number,&p1->name,&p1->physics,
&p1->english,&p1->maths); //从文件中读入数据
printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths); //打印数据
m=m+1;
if(m==1)
head=p1;
else
{
p2->next=p1; //指向下一个节点
p2=p1;
}
p1=(struct scorenode*)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
}
p2->next=NULL;
printf("---------------------------------------------------------\n");
fclose(fp);
return head;
}
//**********************成绩查询函数*****************************
struct scorenode *search(struct scorenode *head)
{
int number;
struct scorenode *p1,*p2;
printf("\n请输入要查询的学生的学号(0)退出:");
scanf("%d",&number); //读取输入的学号
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
while(number!=0) //输入是0,退出
{
getchar(); //吸收回车符
if(head==NULL) //判断链表中是否有数据
{
printf("\n没有任何学生资料!\n");
return(head);
}
p1=head;
while(number!=p1->number&&p1->next!=NULL) //判断链表中数据是否结束
{
p2=p1;
p1=p1->next; //指向链表下一个结点
}
if(number==p1->number)
{
printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->physics,
p1->english,p1->maths); //打印数据
printf("---------------------------------------------------------\n");
}
else
printf("%d号学生不存在!\n",number);
printf("输入要查询的学生的学号(0)退出:");
scanf("%d",&number);
}
printf("退出查询!\n");
return(head);
}
//*************************删除学生资料***********************************
struct scorenode *del(struct scorenode *head)
{
struct scorenode *p1,*p2;
int number;
printf("\n请输入要删除的学生的学号(0)退出:");
scanf("%d",&number); //读取输入的学号
while(number!=0) //输入是0,退出
{
if(head==NULL) //判断链表中是否有数据
{
printf("\n没有任何学生资料!\n");
return(head);
}
p1=head;
while(number!=p1->number&&p1->next!=NULL) //判断链表中数据是否结束
{
p2=p1;
p1=p1->next; //指向链表下一个结点
}
if(number==p1->number)
{
if(p1==head) //判断链表是否是头指针
head=p1->next;
else
p2->next=p1->next; //删除链表
n=n-1; //学生人数减一
}
printf("输入要删除的学生的学号(0)退出:");
scanf("%d",&number);
}
printf("现在的学生数为:%d个!\n",n);
save(head); //保存资料
return(head);
}
//*******************追加学生资料****************************
struct scorenode *add(struct scorenode *head)
{
struct scorenode *p0,*p3,*stu;
int i;
while(1)
{
stu=(struct scorenode*)malloc(sizeof(struct scorenode)); //开辟一个新的存储单元
printf("\n输入要增加的学生资料!\n");
repeat2:
printf("请输入学号(学号应大于0):");
scanf("%d",&stu->number);
while(stu->number<0) //判断输入学号是否正确
{
printf("输入错误,请重新输入学号:");
scanf("%d",&stu->number);
}
if(stu->number==0) //输入为0,退出
goto end2;
else
{
p3=head;
if(n>0)
{
for(i=0;i<n;i++)
{
if(stu->number!=p3->number) //判断输入的学号是否重复
p3=p3->next;
else
{
printf("学号重复,请重输!\n");
goto repeat2;
}
}
}
}
printf("请输入姓名:");
scanf("%s",&stu->name);
printf("请输入物理,英语,数学成绩(0-100):");
scanf("%f,%f,%f",&stu->physics,&stu->english,&stu->maths);
while(stu->physics<0||stu->physics>100||stu->english<0||stu->english>100
||stu->maths<0||stu->maths>100) //判断输入的成绩数据是否正确
{
printf("输入错误,请重新输入成绩:");
scanf("%f,%f,%f",&stu->physics,&stu->english,&stu->maths);
}
getchar(); //吸收回车符
stu->next=NULL;
p0=head;
if(p0==NULL) //都没数据
{
head=stu; //存储新追加的数据
head->next=NULL;
}
else
{
while(p0->next!=NULL)
p0=p0->next;
p0->next=stu; //存储新追加的数据
}
n=n+1; //学生个数加1
}
end2:
printf("现在的学生数为:%d个!\n",n);
//sort(head);
save(head); //保存资料
return(head); //返回此次录入的链表值
}
//***********************显示学生资料**************************
void print_s(struct scorenode *head)
{
struct scorenode *p;
if(head==NULL)
printf("\n没有任何学生资料!\n");
else
{
printf("总人数:%d\n",n); //显示总人数
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t\n");
printf("---------------------------------------------------------\n");
p=head;
while(p!=NULL)
{
printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",p->number,p->name,p->physics,
p->english,p->maths); //打印数据
p=p->next; //指向下一结点
}
printf("---------------------------------------------------------\n");
}
}
//*****************统计学生成绩函数************************
void statistics(struct scorenode *head)
{
float sum,sum1=0,sum2=0,sum3=0,ave,ave1=0,ave2=0,ave3=0,max=0,min=0;
struct scorenode *p;
int y=0,i=0;
p=head;
if(head==NULL)
printf("\n没有任何学生资料!\n");
else
{
printf("---------------------------------------------------------\n");
printf("学号\t姓名\t物理\t英语\t数学\t总分\t平均分\n");
printf("---------------------------------------------------------\n");
while(p!=NULL)
{
sum=p->physics+p->english+p->maths; //计算个人总分
ave=sum/3; //计算个人平均分
printf("%d\t%s\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p->number,p->name,p->physics,
p->english,p->maths,sum,ave); //打印数据
sum1=sum1+p->physics; //累加物理分数
sum2=sum2+p->english; //累加英语分数
sum3=sum2+p->maths; //累加数学分数
y=y+1; //计算人数
if(max<sum)
max=sum; //计算最高分
else if(min>sum)
min=sum; //计算最低分
p=p->next; //指向下一结点
}
ave1=sum1/y; //计算物理平均分
ave2=sum2/y; //计算英语平均分
ave3=sum3/y; //计算数学平均分
printf("物理平均分:%.1f\n",ave1);
printf("英语平均分:%.1f\n",ave2);
printf("数学平均分:%.1f\n",ave3);
printf("总分最高分:%.1f\n",max);
printf("总分最低分:%.1f\n",min);
printf("\n");
}
}
//******************结点中数据交换*******************
void swap(struct scorenode *max,struct scorenode *p)
{
int k;
char t[10];
float temp;
k=max->number;
max->number=p->number;
p->number=k;
strcpy(t,max->name);
strcpy(max->name,p->name);
strcpy(p->name,t);
temp=max->physics;
max->physics=p->physics;
p->physics=temp;
temp=max->english;
max->english=p->english;
p->english=temp;
temp=max->maths;
max->maths=p->maths;
p->maths=temp;
}
//*****************排序函数***************************
void sort(struct scorenode *head)
{
struct scorenode *p,*max;
int i,j,x;
if(head==NULL)
{
printf("\n没有任何学生资料,请先建立链表!\n");
}
for(i=0;i<80;i++)
printf("*");
printf("1.按学生学号排序\t2.按学生姓名排序\t3.按物理成绩排序\n");
printf("4.按英语成绩排序\t5.按数学成绩排序\n");
printf("请选择操作(0)退出:");
scanf("%d",&x); //读取输入的选择
getchar();
for(i=0;i<80;i++)
printf("*");
switch(x)
{
case 1: //学号排序
for(i=1;i<n;i++)
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->number>p->number)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break; //打印数据
case 2:
for(i=1;i<n;i++) //姓名排序(冒泡方式)
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(strcmp(max->name,p->name)>0)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 3:
for(i=1;i<n;i++) //按物理成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->physics>p->physics)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 4:
for(i=1;i<n;i++) //按英语成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->english>p->english)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 5:
for(i=1;i<n;i++) //按数学成绩排序
{
max=p=head;
p=p->next;
for(j=0;j<n-i;j++)
{
if(max->maths>p->maths)
swap(max,p);
p=p->next;
max=max->next;
}
}
print_s(head);break;
case 0:
break;
}
save(head); //保存排序后的数据
}