输完数据返回的时候出错了,不知怎么回事,求解答
/*C语言学生成绩管理系统*/#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#define LEN sizeof(stu)
typedef struct student{
long number;
char name[10];
char sex[3];
char major; //////////////////////
int cla; ////////////////////////
float cyuyan; /////////////////////////////////
float math;
float english;
float sum;
float average;
struct student *next;
}stu;
stu *creat(void);
stu *creat1(void);
stu *creat2(void);
stu *changes(stu *head);
stu *modify(stu *head,long num);
stu *del(stu *head,long num);
stu *insert(stu *head,stu *stud);
stu *input(stu *head,stu *p1);
void sort(stu *head);
void total_average_sort(stu *head);
void chinese_sort(stu *head);
void math_sort(stu *head);
void english_sort(stu *head);
void print(stu *head);
void Statistics(stu *head);
void search(stu *head);
void numsearch(stu *head,long num);
void namesearch(stu *head,char name[]);
int n;/*定义一个全局变量*/
stu *creat(void)/*新建学生信息函数*/
{
stu *head;/*定义一个指向链表的头指针*/
int k;/*定义一个整形变量*/
head=NULL;/*将头指针指向空*/
printf("输入学生信息的方式:1.从键盘输入 2.从文件读入 0.退出\n");/*提示选择用不同的方法读入学生信息*/
printf("请选择:");/*提示请作出选择*/
scanf("%d",&k);/*从键盘输入选择的方式*/
switch(k)/*根据选择的不同来执行不同的操作*/
{
case 1:head=creat1();break;
case 2:head=creat2();break;
case 0:break;
default:printf("输入错误,请重新输入!\n");/*提示重新输入*/
}
return (head);/*返回一个指向链表的头指针*/
}
stu *creat1(void)/*新建学生信息函数(从键盘输入)*/
{
stu *head,*p1;/*定义几个指向链表的指针*/
n=0;/*将全局变量设置为0*/
p1=(stu *)malloc(LEN);/*分配一个内存单元,将其转换成链表型,并让p1,p2指向该内存空间*/
printf("请输入学生信息!\n");/*提示输入学生的信息*/
head=NULL;/*将头指针指向空*/
p1=input(head,p1);/*调用输入学生信息函数,用p1指向所新建的学生信息的单元*/
while(p1->number!=0)/*如果学生的学号不等于0时,才建立新的学生信息接入链表*/
{
head=insert(head,p1);/*调用插入函数*/
p1=(stu *)malloc(LEN);/*再次分配一个内存空间,并将其进行类型转换,让p1指向刚分配的内存*/
p1=input(head,p1);/*调用输入学生信息函数,用p1指向所新建的学生信息的单元*/
}
return(head);/*用头指针返回*/
}
stu *creat2(void)/*新建学生信息函数(从文件读入)*/
{
FILE *fp;/*定义一个指向文件的指针*/
stu *head,*p1;/*定义两个指向结构体的指针*/
n=0;/*将全局变量设为0*/
head=NULL;/*让头指针指向空*/
if((fp=fopen("1.txt","r"))==NULL)/*打开文件,如果不能打开就提示*/
{
printf("打开文件失败!\n");
exit(0);
}
p1=(stu *)malloc(LEN);/*开辟一个空间,让p1指向这个空间*/
while(!feof(fp))/*如果不是文件的末尾,就读取文件的内容*/
{
fscanf(fp,"%ld%s%s%s%d%f%f%f%f%f\n",&p1->number,p1->name,p1->sex,p1->major,&p1->cla,&p1->cyuyan,&p1->math,&p1->english,&p1->sum,&p1->average);/*将从文件读取的数据存入到p1指向的空间中*/
head=insert(head,p1);/*调用插入函数*/
p1=(stu *)malloc(LEN);/*分配内存空间*/
};
fclose(fp);/*关闭文件*/
return (head);/*返回头指针*/
}
stu *input(stu *head,stu *p1)/*输入学生的信息*/
{
int i,f,k;/*定义一个整形变量*/
stu *p2;/*定义一个指向链表的指针*/
loop:printf("学号(为整数,输入0时返回上一级):");/*提示学生输入学号*/
scanf("%ld",&p1->number);/*从键盘输入学生的学号*/
if(p1->number<0){/*如果学号为负数,则提示错误,并要求重新输入*/
printf("学号不能为负数,请重新输入!\n");
goto loop;
}
else{
if(p1->number==0)/*如果学生的学号为0,则表示要退出*/
return(p1);
else{
p2=head;/*将P2指向链表的头部*/
f=0;/*将f的初值设为0*/
for(i=1;i<=n;i++){/*遍历链表找出是否有学号重复的现象*/
if(p1->number==p2->number)
{f=1;break;}/*如果有学号重复的情况,则将f的值设为1,并跳出*/
p2=p2->next;}/*如果暂时没有学号重复的情况,就将指针指向下一个节点,继续查找*/
}
if(f)/*如果有学号重复的现象,则提示学号重复,并要求重新输入学生的学号*/
{printf("学号不能重复,请重新输入!\n");goto loop;}
}
printf("姓名:");/*提示输入学生的姓名*/
scanf("%s",p1->name);/*从键盘输入学生的姓名*/
loop1:printf("性别: 1.男 2.女\n");/*打印学生的性别选择情况*/
printf("请选择性别:");/*提示选择性别*/
scanf("%d",&k);/*从键盘输入选择性别*/
switch(k)/*根据选择的值的不同执行不同的操作*/
{
case 1:strcpy(p1->sex,"男");break;/*如果选择的是“男”,则将“男”写入该学生的性别单元*/
case 2:strcpy(p1->sex,"女");break;/*如果选择的是“女”,则将“女”写入该学生的性别单元*/
default:printf("性别只能是“男”或“女”,请重新输入!\n");goto loop1;}/*如果性别即不是“男”又不是“女”,则提示错误,并要求重新输入*/
printf("班级:");/*提示输入班级*/
scanf("%d",&p1->cla);/*从键盘输入班级*/
while(p1->cla<0||p1->cla>120){/*如果学生的年龄小于0或大于120岁,则提示于实际情况不符,并要求重新输入,直到输入正确为止*/
printf("你输入的年龄不符合实际情况,请重新输入!\n");
printf("年龄:");
scanf("%d",&p1->cla);
}
printf("c语言成绩:");/*提示输入c语言成绩*/
scanf("%f",&p1->cyuyan);/*从键盘输入c语言成绩*/
while(p1->cyuyan<0||p1->cyuyan>100){/*如果输入的成绩小于0或大于100,则提示输入与实际情况不符,并要求重新输入,直到达到要求为止*/
printf("你输入的c语言成绩不符合实际情况,请重新输入!\n");
printf("c语言成绩:");
scanf("%f",&p1->cyuyan);}
printf("数学成绩:");/*提示输入数学成绩*/
scanf("%f",&p1->math);/*从键盘输入数学成绩*/
while(p1->math<0||p1->math>100){/*如果输入的成绩小于0后大于100,则提示输入与实际情况不符,并要求重新输入,直到达到要求为止*/
printf("你输入的数学成绩不符合实际情况,请重新输入!\n");
printf("数学成绩:");
scanf("%f",&p1->math);}
printf("英语成绩:");/*提示输入英语成绩*/
scanf("%f",&p1->english);/*从键盘输入英语成绩*/
while(p1->english<0||p1->english>100){/*如果输入的成绩小于0或大于100,则提示输入与实际情况不符,并要求重新输入,直到达到要求为止*/
printf("你输入的英语成绩不符合实际情况,请重新输入!\n");
printf("英语成绩:");
scanf("%f",&p1->english);}
p1->sum=p1->cyuyan+p1->math+p1->english;/*计算学生的总分*/
p1->average=p1->sum/3;/*计算学生的平均分*/
return(p1);/*用p1返回*/
}
void search(stu *head)/*查找学生信息函数*/
{
int k;/*定义一个整形变量,用来记录选择查询的方式*/
long num;/*定义一个长整形变量,用来记录输入的学生的学号*/
char name[10];/*定义一个字符型变量,用来记录输入的学生的姓名*/
if(n==0)/*如果链表为空,则输出提示信息,并跳出*/
{printf("数据库为空,没有学生的记录!\n");return;}
else{
do{/*如果链表不为空,则循环执行以下的操作*/
printf("1. 按学号查找 2. 按姓名查找 0. 返回上一级\n");/*输出可以进行查询的方式*/
printf("请选择:");/*提示选择要查询的方式*/
scanf("%d",&k);/*从键盘输入k,选择查询方式*/
switch(k)/*根据k值的不同选择不同的查询方式*/
{
case 1:do{/*用该循环来实现多个学号的查询*/
printf("学号(为整数,输入0时跳出按学号查找):");/*提示输入学生的学号*/
scanf("%ld",&num);/*从键盘输入学生的学号*/
if(num>0)/*如果学号为正整数,则执行查询操作*/
numsearch(head,num);/*调用按学号查找的函数*/
if(num<0)/*如果学号为负数,则提示错误,并要求重新输入*/
printf("输入错误,请重新选择!\n");
}while(num!=0);
break;
case 2:do{/*用该循环来实现多个姓名的查询*/
printf("姓名(输入0时跳出按姓名查找):");/*提示输入要查找的学生的姓名*/
scanf("%s",name);/*从键盘输入学生的姓名*/
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");/*打印头部*/
namesearch(head,name);/*调用按姓名查找函数*/
}while(strcmp(name,"0")!=0);/*如果输入的学生姓名为0,则表示跳出该循环*/
break;
case 0:break;/*如果选择的是0,则跳出*/
default:printf("输入错误,请重新选择!\n");/*如果输入的不是能够选择的功能,则提示错误*/
}
}while(k!=0);/*如果选择的是0,则跳出循环*/
}
}
void numsearch(stu *head,long num)/*按学号查找函数*/
{
stu *p1;/*定义一个指向链表的指针*/
p1=head;/*让p1指向链表的头部*/
while(p1!=NULL)/*如果链表不为空,则执行以下操作*/
{
if(num==p1->number){/*如果找到了要查找的学号,则输出该学生的信息*/
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");/*打印头部*/
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
return;}
p1=p1->next;/*如果暂时没有找到要查找的学生信息,则将指针后移,继续查找*/
}
printf("没有找到你要查找的学生信息!\n");/*如果没有找到该学号,则提示没有找到学生的信息*/
}
void namesearch(stu *head,char name[])/*按姓名查找函数*/
{
int a=1;/*定义一个整形变量,并将其设为1*/
stu *p1;/*定义一个指向链表的指针*/
p1=head;/*将p1指向链表的头部*/
while(p1!=NULL)/*如果链表不为空,则进行下列操纵*/
{
if(strcmp(name,p1->name)==0){/*如果找到了要查找到的姓名,则输出该学生的信息*/
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);a=0;}
p1=p1->next;/*如果暂时没有找到要查找的学生的信息,则将指针后移,继续查找*/
}
if(a)/*如果没有找到该姓名得学生,则提示没有找到该学生的信息*/
printf("没有找到你要查找的学生信息!\n");
}
stu *changes(stu *head)/*更新学生信息函数*/
{
stu *p1;/*定义一个指向链表的指针*/
int k;/*定义一个整形变量,用来记录要进行的选择*/
long num;/*定义一个长整形变量,用来记录学生的学号*/
do{/*用该循环来重复进行更改操作*/
printf("1. 修改 2. 删除 3. 插入 0. 返回上一级\n");/*打印更新的几种功能*/
printf("请选择:");/*提示选择更新的功能*/
scanf("%d",&k);/*从键盘输入选择*/
switch(k)/*根据不同的k值执行不同的操作*/
{
case 1:if(n==0){/*如果链表为空,则直接跳出*/
printf("数据库为空,没有学生的记录!\n");break;}
else
do{/*该循环可以修改多个学生的记录*/
printf("请输入学生的学号(学号应为整数,输入0时跳出修改数据):");/*提示输入学生的学号*/
scanf("%ld",&num);/*从键盘输入学生的学号*/
if(num>0)/*如果输入的学号大于0,则执行修改学生记录的操作*/
head=modify(head,num);/*调用修改学生记录额操作*/
if(num<0)
printf("学号不能为负数,请重新输入!\n");/*如果学号为负数,则提示输入错误,并要求重新输入*/
}while(num!=0);/*如果学号为0,则表示跳出该循环*/
break;
case 2:if(n==0){printf("数据库为空,没有学生信息!\n");break;}/*如果链表为空表,则提示为空表,并跳出*/
else
do{/*该循环可以实现对多个学生记录的删除*/
printf("请输入要删除的学生的学号(学号应为整数,输入0时跳出删除元素):");/*提示输入要删除的学生的学号*/
scanf("%ld",&num);/*从键盘输入要删除的学生的学号*/
if(num>0)/*如果输入的学号大于0,则执行以下操作*/
head=del(head,num);/*调用删除记录函数*/
if(num<0)/*如果学号小于0,则提示输入的学号不正确,并要求重新输入*/
printf("学号不能为负数,请重新输入!\n");
}while(num!=0);/*当输入的学号为0时,表示跳出该循环*/
break;
case 3:printf("请输入学生信息!\n");/*提示输入学生的信息*/
p1=(stu *)malloc(LEN);/*分配一个内存单元,并让p1指向该单元*/
p1=input(head,p1);/*调用输入学生信息函数*/
while(p1->number!=0)/*如果学号不为0,则执行以下操作否则跳出*/
{head=insert(head,p1);/*调用插入学生信息函数*/
print(head);/*打印插入新记录后的链表*/
printf("请输入学生信息!\n");/*提示输入学生的信息*/
p1=(stu *)malloc(LEN);/*分配一个内存空间,并让p1指向该单元*/
p1=input(head,p1);/*调用输入学生信息函数*/
}
break;
case 0:break;/*当选择为0时,跳出*/
default:printf("输入错误,请重新输入!\n");/*当选择不当时,提示输入错误,并要求重新输入*/
}
}while(k!=0);/*当选择为0时,跳出循环*/
return(head);/*返回头指针*/
}
void sort(stu *head)/*排序函数*/
{
int k;/*定义一个整形变量,用来记录所选择的功能*/
if(n==0){printf("数据库为空,没有学生记录!\n");return;}/*如果链表为空,则提示并直接挑出*/
do{/*该循环可以实现按多种不同的方法排序*/
printf("1.按学号排序 2.按总分和平均分排序 3.按c语言成绩排序 4.按数学成绩排序 5.按英语成绩排序 0.返回上一级\n");/*打印该函数的各项功能*/
printf("请选择:");/*提示选择要进行的操作*/
scanf("%d",&k);/*从键盘输入所做的选择*/
switch(k)/*根据选择的不同,调用不同的函数*/
{
case 1:print(head);break;/*由于在建立链表的时候已经对链表进行了按学号排序,故这里可直接调用打印学生信息的函数*/
case 2:total_average_sort(head);break;/*调用按总分和平均分排序的函数*/
case 3:chinese_sort(head);break;/*调用按语文成绩排序的函数*/
case 4:math_sort(head);break;/*调用按数学成绩排序的函数*/
case 5:english_sort(head);break;/*调用按英语成绩排序的函数*/
case 0:break;/*如果选择0,则跳出*/
default:printf("输入错误,请重新输入!\n");/*如果输入错误,则提示出错*/
}
}while(k!=0);/*当k为0时,表示跳出该循环*/
}
void total_average_sort(stu *head)/*按总成绩和平均成绩排序函数*/
{
stu *p1,*p2;/*定义两个指向链表的指针,下同*/
int j=0;/*定义一个整型变量,用来记录输出的学生的个数,下同*/
float max,k=301;/*定义两个单精度浮点型变量,分别用来记录最高分,下同*/
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");/*打印头部,下同*/
do{
max=0;
for(p1=head;p1;p1=p1->next)/*遍历整个链表,下同*/
if(p1->sum>max&&p1->sum<k){/*如果找到的值比以前的最大值要大且此时的最大值小于以前的最大值,则执行下列操作,下同*/
max=p1->sum;/*用max记录最大值,下同*/
p2=p1;}/*记录下最大值的位置,下同*/
k=max;/*将最大值负值给k,下同*/
for(p1=p2;p1;p1=p1->next)/*从找到的最大值处开始遍历,输出和最大值相等的学生的信息,下同*/
if(p1->sum==max){
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
j++;}/*记录输出的学生的个数,下同*/
}while(j<n);/*当所有的学生的信息都输出时,结束该循环,下同*/
}
void chinese_sort(stu *head)/*按c语言成绩排序函数*/
{
int j=0;
float k=101,max;
stu *p1,*p2;
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");
do{
max=0;
for(p1=head;p1;p1=p1->next)
if(p1->cyuyan>max&&p1->cyuyan<k){
max=p1->cyuyan;
p2=p1;}
k=max;
for(p1=p2;p1;p1=p1->next)
if(p1->chinese==max){
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
j++;}
}while(j<n);
}
void math_sort(stu *head)/*按数学成绩排序函数*/
{
int j=0;
float k=101,max;
stu *p1,*p2;
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");
do{
max=0;
for(p1=head;p1;p1=p1->next)
if(p1->math>max&&p1->math<k){
max=p1->math;
p2=p1;}
k=max;
for(p1=p2;p1;p1=p1->next)
if(p1->math==max){
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
j++;}
}while(j<n);
}
void english_sort(stu *head)/*按英语成绩排序函数*/
{
int j=0;
float k=101,max;
stu *p1,*p2;
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");
do{
max=0;
for(p1=head;p1;p1=p1->next)
if(p1->english>max&&p1->english<k){
max=p1->english;
p2=p1;}
k=max;
for(p1=p2;p1;p1=p1->next)
if(p1->english==max){
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
j++;}
}while(j<n);
}
stu *modify(stu *head,long num)/*修改学生信息函数*/
{
stu *p1;/*定义一个指向链表的指针*/
int k,m;
p1=head;/*让p1指向链表的头部*/
while(p1->next!=NULL)/*遍历整个链表*/
{
if(p1->number==num)/*如果找到要修改的学生,则跳出停止继续遍历*/
break;
p1=p1->next;/*如果暂时没有找到,则让p1指向下一个节点,继续遍历,直到找到为止*/
}
if(p1->number==num)/*如果找到要修改的学生,则进行下面的操作*/
{
do{
printf("1.姓名 2.性别 3.专业 4.班级 5.c语言成绩 6.数学成绩 7.英语成绩 0.返回上一级\n");/*输出可以修改的信息*/
printf("请选择:");/*提示选择要修改的项目*/
scanf("%d",&k);/*从键盘输入选择*/
switch(k)/*根据选择的不同进行执行不同的操作*/
{
case 1:printf("姓名:");scanf("%s",p1->name);printf("修改成功!\n");break;/*修改姓名,成功修改提示成功*/
case 2:loop2:printf("性别: 1.男 2.女\n");/*输出性别的选择*/
printf("请选择性别:");/*提示选择性别*/
scanf("%d",&m);/*从键盘输入选择*/
switch(m)/*根据选择的不同执行不同的操作*/
{
case 1:strcpy(p1->sex,"男");break;/*如果选择1,则将“男”赋值给要修改的学生的性别*/
case 2:strcpy(p1->sex,"女");break;/*如果选择2,则将“女”赋值给要修改的学生的性别*/
default:printf("性别只能是“男”或“女”,请重新输入!\n");goto loop2;}/*如果输入错误,则输出提示*/
printf("修改成功!\n");/*修改成功后输出提示信息*/
break;
case 3:printf("专业:");scanf("%s",p1->major);printf("修改成功!\n");break;/*修改专业,成功修改提示成功*/
case 4:printf("班级:");/*提示输入班级*/
scanf("%d",&p1->cla);/*从键盘输入班级*/
while(p1->cla<0||p1->cla>120){/*当输入的班级不符合实际的时候,提示输入错误,并要求重新输入*/
printf("你输入的班级不符合实际情况,请重新输入!\n");
printf("班级:");
scanf("%d",&p1->cla);
}
printf("修改成功!\n");/*修改成功后输出提示信息*/
break;
case 5:printf("c语言成绩:");/*提示输入成绩,下同*/
scanf("%f",&p1->cyuyan);/*从键盘输入成绩,下同*/
while(p1->cyuyan<0||p1->cyuyan>100){/*当输入的成绩不符合实际情况时,提示出错,并要求重新输入,下同*/
printf("你输入的c语言成绩不符合实际情况,请重新输入!\n");
printf("c语言成绩:");
scanf("%f",&p1->cyuyan);}
p1->sum=p1->cyuyan+p1->math+p1->english;/*由于单科成绩改变了,故要修改总分,下同*/
p1->average=p1->sum/3;/*由于单科成绩改变了,故要修改平均分,下同*/
printf("修改成功!\n");/*修改成功后输出提示信息,下同*/
break;
case 6:printf("数学成绩:");
scanf("%f",&p1->math);
while(p1->math<0||p1->math>100){
printf("你输入的数学成绩不符合实际情况,请重新输入!\n");
printf("数学成绩:");
scanf("%f",&p1->math);}
p1->sum=p1->chinese+p1->math+p1->english;
p1->average=p1->sum/3;
printf("修改成功!\n");
break;
case 7:printf("英语成绩:");
scanf("%f",&p1->english);
while(p1->english<0||p1->english>100){
printf("年输入的英语成绩不符合实际情况,请重新输入!\n");
printf("英语成绩:");
scanf("%f",&p1->english);}
p1->sum=p1->chinese+p1->math+p1->english;
p1->average=p1->sum/3;
printf("修改成功!\n");break;
case 0:break;
default:printf("输入错误,请重新选择!\n");
}
}while(k!=0);
print(head);/*打印修改后的学生信息*/
}
else
printf("没有找到你要修改的学生的信息!\n");/*如果没有找到要修改的学生,则提示没有找到*/
return(head);/*返回头指针*/
}
stu *del(stu *head,long num)/*删除学生信息函数*/
{
stu *p1,*p2;/*定义两个指向链表的指针*/
if(head==NULL){printf("数据库为空,没有学生记录! \n");goto end;}/*如果链表为空,则输出提示信息,并直接跳出*/
p1=head;/*让p1指向链表的头部*/
while(num!=p1->number&&p1->next!=NULL)/*遍历链表直到最后一个节点(不包括最后一个节点),如果找到要删除的学生,则直接跳出*/
{
p2=p1;p1=p1->next;
}
if(num==p1->number)/*如果找到了要删除的学生的学号,就删除,并提示删除成功,将记录学生节点数目的变量减一*/
{
if(p1==head){head=p1->next;printf("删除成功!\n");}
else {p2->next=p1->next;printf("删除成功!\n");}
n=n-1;
print(head);/*打印删除后的学生信息*/
}
else printf("没有找到你要删除的学生信息!\n",num);/*如果没有找到要删除的学生,则提示*/
end:;
return(head);/*返回头指针*/
}
stu *insert(stu *head,stu *stud)/*插入学生信息函数*/
{
stu *p0,*p1,*p2;/*定义三个指向链表的指针*/
p1=head;/*让p1指向链表的头部*/
p0=stud;/*让p0指向要插入的节点*/
if(head==NULL)/*如果头指针为空,则直接将要插入的节点视作第一个节点*/
{head=p0;p0->next=NULL;}
else
{while((p0->number>p1->number)&&(p1->next!=NULL))/*遍历链表(最多直到倒数第二个元素),当要插入的节点的学生的学号大于链表中的某个学生的学号时,停止指针向后移动*/
{
p2=p1;
p1=p1->next;
}
if(p0->number<=p1->number)/*当找到要插入学生的适当位置后,将该学生的节点插入其中,并将记录节点个数的变量加一*/
{
if(head==p1)head=p0;
else p2->next=p0;
p0->next=p1;
}
else
{
p1->next=p0;p0->next=NULL;
}
}
n=n+1;
return(head);/*返回头指针*/
}
void Statistics(stu *head)/*统计学生信息的函数*/
{
stu *p1;
int i,c=0,m=0,e=0;
float cmax=0,mmax=0,emax=0,summax=0,averagemax=0;
if(n==0){printf("数据库为空,没有学生的信息!\n");return;}
p1=head;
for(i=1;i<=n;i++){/*遍历链表*/
if(p1->cyuyan>=cmax)/*找出语文成绩最高分*/
cmax=p1->cyuyan;
if(p1->math>=mmax)/*找出数学成绩最高分*/
mmax=p1->math;
if(p1->english>=emax)/*找出英语成绩最高分*/
emax=p1->english;
if(p1->sum>=summax)/*找出总分最高分*/
summax=p1->sum;
if(p1->average>=averagemax)/*找出平均成绩最高分*/
averagemax=p1->average;
if(p1->chinese<60)/*记录语文成绩不及格的人数*/
c++;
if(p1->math<60)/*记录数学成绩不及格的人数*/
m++;
if(p1->english<60)/*记录英语成绩不及格的人数*/
e++;
p1=p1->next;/*将指针后移*/
}
/*以下是打印统计的结果*/
printf("总成绩最高分:%5.1f\n",summax);
printf("平成绩最高分:%5.1f\n",averagemax);
printf("语文成绩最高粉:%5.1f\n",cmax);
printf("数学成绩最高分:%5.1f\n",mmax);
printf("英语成绩最高分:%5.1f\n",emax);
printf("语文成绩没有及格的人数:%d\n",c);
printf("数学成绩没有及格的人数:%d\n",m);
printf("英语成绩没有及格的人数:%d\n",e);
printf("\n");
}
void print(stu *head)/*打印学生信息的函数*/
{
stu *p1;
if(n==0){printf("数据库为空,没有学生信息!\n");return;}
printf("\n现在的%d个学生记录为:\n",n);/*输出现有的学生的人数*/
p1=head;
if(head!=NULL){
printf("学号\t姓名\t性别\t专业\t班级\tc语言\t数学\t英语\t总分\t平均分\n");/*打印头部*/
do {
printf("%ld\t%s\t%s\t%s\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
p1=p1->next;
}while(p1!=NULL);
}
}
void save(stu *head)/*将数据存入文件中*/
{
FILE *fp;/*定义一个指向文件的指针*/
stu *p1;/*定义一个指向链表的指针*/
if(n==0){printf("你还没有建立数据库!请先建立数据库!\n");return;}
if((fp=fopen("1.txt","w+"))==NULL)/*以写的方式打开文件,如果没有打开,则提示*/
{
printf("不能打开文件!\n");
exit(0);
}
for(p1=head;p1!=NULL;p1=p1->next)/*遍历链表,让每一个数都存入文件中*/
fprintf(fp,"%ld\t%s\t%s\t%s\t%d\t%5.1f\t%5.1f\t%5.1f\t%5.1f\t%5.1f\n",p1->number,p1->name,p1->sex,p1->major,p1->cla,p1->cyuyan,p1->math,p1->english,p1->sum,p1->average);
printf("保存成功!\n");/*提示保存文件成功*/
fclose(fp);/*关闭文件*/
}
void main()/*主函数*/
{
int choice;/*定义一个整形变量,用来记录所要进行的选择*/
stu *head;/*定义一个头指针*/
head=NULL;
do{/*使用循环使下面的操作可以重复进行*/
/*打印表头*/
printf("*******************************************************************************\n");
printf("^_^_^_^_^_^_^_^_^_^_^_^_^_^欢迎来到学生成绩管理系统!^_^_^_^_^_^_^_^_^_^_^_^_^_^\n");
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(" 0. 跳出; \n");
printf(" \n");
printf(" 按键选择,回车确定! \n");
printf(" \n");
printf("^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^\n");
printf("*******************************************************************************\n");
printf("请选择:");/*提示用户选择操作功能*/
scanf("%d",&choice);
while(getchar()!='\n');/*接收回车符*/
switch(choice)/*根据choice值的不同选择不同的操作*/
{
case 1:head=creat();print(head);break;/*新建链表函数,并用head指向链表的头部,并输出所建立的链表*/
case 2:search(head);break;/*查找学生信息函数*/
case 3:head=changes(head);break;/*更新学生信息函数,修改后学生的信息会改变,故将head指针重新指向修改后的链表头部*/
case 4:sort(head);break;/*排序学生信息函数*/
case 5:Statistics(head);break;/*统计学生信息函数*/
case 6:print(head);break;/*打印学生信息函数*/
case 7:save(head);break;
case 0:break;/*输入0时跳出*/
default:printf("输入错误,请重新选择!\n");/*当输入错误时提示输入错误*/
}
}while(choice!=0);/*当输入为0时跳出本函数*/
}