#include <stdio.h>
#include <malloc.h>
#include <conio.h>
#include <string.h>
enum studentcategory { UNDERGRADUATE,POSTGRADUATE };
struct node * create_ _table(enum studentcategory category);
typedef struct node{
int id; //学号:主键,唯一
char name[10]; //姓名
char sex[3]; //性别:男或女
char specialty[20]; //专业
int classes; //班级
enum studentcategory category; //枚举型学生类别;本科生、研究生
int math; //高数
int english; //英语
int clanguage; //C语言
int comprehensive; //课程综合
int thesis; //毕业论文
int totalscore; //总成绩
int classrank; //班级排名
int schoolrank; //校级排名
struct node * next;
}Student;
//声明全局变量
Student * myHead=NULL;
int schoolCount[2];
char tmp;
FILE * fp=NULL;
char boy[]=\"男\";
char girl[]=\"女\";
//函数声明
void Input(void);
void query_all(); //查询所有学生成绩信息
void inquire(void); //查询界面
void insert_node0(); //获取用户要插入的学生成绩信息
void insert_node(Student *student); //插入学生信息到链表中
void edit_node(); //修改学生成绩信息
Student * query_node(int cate,int id); //根据学生种类和学生学号查询
void delete_node(); //删除链表中的节点
void updateRank(); //更新链表中所有学生的排名
void queryByClassAndCategory(); //根据班级和学生种类查询学生成绩信息
void queryFailByClassAndCategory(); //查询不及格的学生成绩信息
void queryByName(); //根据姓名查询学生成绩信息
void count_analysis(); //统计模块
void queryById(); //根据ID查询学生成绩信息
FILE * openfile(char * openmode);
void saveData(); //将链表中的数据保存到本地
void initData(); //插入节点
int isCateAndIdViable(int cate,int id); //查询插入的学生学号和学生种类是否已经被保存
Student * findPre(Student *student); //查找某节点的前一个学生信息
void updateSchoolCount(); //更新学校排名
void release(); //退出系统的时候释放链表所占的内存空间
void stampscore(); //打印报表
//主函数
void main()
{
char ch;
initData(); //插入节点
while(1)
{
system(\"cls\");//清屏
//系统主页显示好看的布局
printf(\"\\n\");
printf(\" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\");
printf(\"\\n * *\");
printf(\"\\n * 学生成绩管理系统V1.0 *\");
printf(\"\\n * *\\n\");
printf(\" * 【功能菜单】 *\\n\");
printf(\" * [1].录入信息 [2].修改信息 *\\n\");
printf(\" * *\\n\");
printf(\" * [3].删除信息 [4].查询成绩 *\\n\");
printf(\" * *\\n\");
printf(\" * [5].打印信息 [6].统计信息 *\\n\");
printf(\" * *\\n\");
printf(\" * [esc].退出 *\\n\");
printf(\" * *\\n\");
printf(\" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\");
printf(\" 请输入操作编号(1~5):\");
sta:
ch=getch();//获取用户输入的指令
//判断用户输入的指令
switch(ch)
{
case \'1\': insert_node0(); break;
case \'2\': edit_node(); break;
case \'3\': delete_node(); break;
case \'4\': inquire(); break;
case \'5\': stampscore(); break;
case \'6\': count_analysis(); break;
case 27:
//系统退出的时候,保存数据,释放链表的内存空间,然后清屏
saveData(); //将链表中的数据保存到本地
release(); //退出系统的时候释放链表所占的内存空间
system(\"cls\");
exit(0);
}
}
}
//插入节点
void initData(){
long data_size=sizeof(Student);
Student *p1=NULL;
if((p1=(Student *)malloc(sizeof(Student)))==NULL){
printf(\"不能成功分配存储块\");
exit(0);
}
fp=openfile(\"ab+\");
fseek(fp,0L,SEEK_SET);
fread(p1,data_size,1,fp);
while(!feof(fp)){
insert_node(p1);
if((p1=(Student *)malloc(sizeof(Student)))==NULL){
printf(\"不能成功分配存储块\");
exit(0);
}
if(fread(p1,data_size,1,fp)==EOF){
break;
}
}
if(fclose(fp)){
printf(\"未能正常关闭文件!\");
}
}
//将链表中的数据保存到本地
void saveData(){
Student * p1=myHead;
Student data;
if(myHead==NULL){
return;
}
fp=openfile(\"wb\");
rewind(fp);
while(p1!=NULL){
fwrite(p1,sizeof(Student),1,fp); //将p1这个指针所指向的内容输出到fp这个文件中,每次输出的数据单元占sizeof(Student)个字节,总共输出1次
p1=p1->next;
}
if(fclose(fp)){
printf(\"未能正常关闭文件!\");
}
}
//打开文件,返回文件指针
FILE *openfile(char * openmode){
FILE *f1=NULL;
if((f1=fopen(\"student.txt\",openmode))==NULL){
printf(\"无法打开student.txt文件!\\n\");
exit(0);
}
return(f1);
}
//统计模块
void count_analysis(){
int res[6]={0,0,0,0,0,0};
float ave=0.0;
int count=0;
int sum=0;
int min=0;
int max=0;
Student * p1=myHead;
int cate=-1;
int score=0;
int clazz=-1;
int course=0;
system(\"cls\");
if(p1==NULL)
{
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');//EOF是个宏,在stdil.h中定义,值为-1,也称结束标志
while(cate<0||cate>1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');//当输入 ctrl+z 或 ctrl+c等组合键,getchar返回结束标志
}
printf(\"请输入班级:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');//当程序从键盘获得了字符并且字符不是回车符的话,执行循环里的操作。
while(clazz<=0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');//\\n回车(剔除了回车字符)
}
switch(cate){
case UNDERGRADUATE: //本科生
printf(\"1.c语言 2.高数 3.英语\\n\");
printf(\"请输入课程编号:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(course>3||course<1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
break;
case POSTGRADUATE: //研究生
printf(\"1.课程综合 2.论文\\n\");
printf(\"请输入编号:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(course>2||course<1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
break;
}
while(p1!=NULL){ //循环,遍历链表里所有数据
if((p1->category==cate)&&(p1->classes==clazz)){
switch(cate){
case UNDERGRADUATE: //本科生
switch(course){ //课程
case 1:
score=p1->clanguage;
break;
case 2:
score=p1->math;
break;
case 3:
score=p1->english;
break;
}
break;
case POSTGRADUATE: //研究生
switch(course){ //课程
case 1:
score=p1->comprehensive;
break;
case 2:
score=p1->thesis;
break;
}
break;
}
if(score<=100&&score>=0){
count++;
sum+=score; //确定所要统计的班级的科目的总成绩
if(count==1){
max=score;
}
min=score;
if(score<60){
res[0]++; //统计不及格人数
}else{
res[score/10-5]++; //90~100为优;80~90为良;70~80为中;60~70为及格
}
}
}
p1=p1->next; //跟踪链表增长
}
if(count!=0){
ave=sum*1.0/count;
}
else{
ave=0.0;
}
printf(\"\\n-----------------------------------------\\n\");
printf(\"平均分:%.2f\\t\\t\",ave);
printf(\"最高分:%d\\n\",max);
printf(\"最低分:%d\\n\",min);
printf(\"优:%d人\\t\\t\",res[5]+res[4]);
printf(\"良:%d人\\n\",res[3]);
printf(\"中:%d人\\t\\t\",res[2]);
printf(\"及格:%d人\\n\",res[1]);
printf(\"不及格:%d人\\n\",res[0]);
printf(\"\\n*****************************************\\n\");
printf(\"超过平均分的学生名单:\\n\");
printf(\"\\t姓名\\t\\t学号\\n\");
p1=myHead;
while(p1!=NULL){
if(p1->category==cate&&p1->classes==clazz){
switch(cate){
case UNDERGRADUATE:
switch(course){
case 1:
score=p1->clanguage;
break;
case 2:
score=p1->math;
break;
case 3:
score=p1->english;
break;
}
break;
case POSTGRADUATE:
switch(course){
case 1:
score=p1->comprehensive;
break;
case 2:
score=p1->thesis;
break;
}
break;
}
if(score>=ave){
printf(\"\\t%s\\t\\t%d\\n\",p1->name,p1->id);
}
}
p1=p1->next;
}
printf(\"\\n*****************************************\\n\");
printf(\"不及格的学生名单:\\n\"); //打印不及格学生名单
printf(\"\\t姓名\\t\\t学号\\n\");
p1=myHead;
while(p1!=NULL){
if(p1->category==cate&&p1->classes==clazz){
switch(cate){
case UNDERGRADUATE:
switch(course){
case 1:
score=p1->clanguage;
break;
case 2:
score=p1->math;
break;
case 3:
score=p1->english;
break;
}
break;
case POSTGRADUATE:
switch(course){
case 1:
score=p1->comprehensive;
break;
case 2:
score=p1->thesis;
break;
}
break;
}
if(score<60&&score>=0){
printf(\"\\t%s\\t\\t%d\\n\",p1->name,p1->id);
}
}
p1=p1->next;
}
printf(\"\\n*****************************************\\n\");
printf(\"\\n查询结束,任意键继续...\");
getch();
}
}
//删除链表中的节点
void delete_node(){
Student * p1=myHead,* p2=myHead;
int cate=-1;
int id=-1;
system(\"cls\");
if(myHead==NULL){
printf(\"没有学生记录,无法进行删除操作!任意键继续...\\n\");
getch();
return;
}
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(cate<0||cate>1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入学号:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(id<0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
while(((p1->category!=cate)||(p1->id!=id))&&(p1->next!=NULL)){
p2=p1;
p1=p1->next;
}
if((p1->category==cate)&&(p1->id==id)){
if(p1==myHead){
myHead=p1->next;
}else{
p2->next=p1->next;
}
free(p1);//释放储存空间
updateRank(); //更新链表中的排名
printf(\"删除成功,任意键继续...\");
getch();
}else{
printf(\"删除失败,任意键继续...\");
getch();
}
}
//查询界面
void inquire(void)
{
char ch;
while(1)
{
system(\"cls\");
printf(\"\\n\");
printf(\" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\");
printf(\"\\n * *\");
printf(\"\\n * 查询学生成绩 *\");
printf(\"\\n * *\\n\");
printf(\" * 【功能菜单】 *\\n\");
printf(\" * [1].查询全部 [2].查询班级 *\\n\");
printf(\" * *\\n\");
printf(\" * [3].姓名查询 [4].学号查询 *\\n\");
printf(\" * *\\n\");
printf(\" * [5].查询不及格 [esc].返回首页 *\\n\");
printf(\" * *\\n\");
printf(\" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\");
printf(\" 请输入操作编号(1~5):\");
ch=getch();
switch(ch){
case \'1\':
query_all();
break;
case \'2\':
queryByClassAndCategory();
break;
case \'3\':
queryByName();
break;
case \'4\':
queryById();
break;
case \'5\':
queryFailByClassAndCategory();
break;
case 27:
return;
}
}
}
//查询不及格的学生成绩信息
void queryFailByClassAndCategory(){
Student * p1=myHead;
int cate=-1;
int score=0;
int clazz=-1;
int course=0;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(cate<0||cate>1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入班级:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(clazz<=0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
switch(cate){
case UNDERGRADUATE: //本科生
printf(\"1.c语言 2.高数 3.英语\\n\");
printf(\"请输入课程编号:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(course<1||course>3){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
break;
case POSTGRADUATE: //研究生
printf(\"1.课程综合 2.论文\\n\");
printf(\"请输入课程编号:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(course<1||course>2){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&course);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
break;
}
while(p1!=NULL){
if(p1->category==cate&&p1->classes==clazz){
switch(cate){
case UNDERGRADUATE:
switch(course){
case 1:
score=p1->clanguage;
break;
case 2:
score=p1->math;
break;
case 3:
score=p1->english;
break;
}
break;
case POSTGRADUATE:
switch(course){
case 1:
score=p1->comprehensive;
break;
case 2:
score=p1->thesis;
break;
}
break;
}
if(score<60&&score>=0){
printf(\"****************************************\\n\");
printf(\"学号:%d\\t\\t\",p1->id);
printf(\"姓名:%s\\n\",p1->name);
printf(\"性别:%s\\t\\t\",p1->sex);
printf(\"班级:%d\\n\",p1->classes);
printf(\"专业:%s\\n\",p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"类型:本科生\\n\");
printf(\"高数成绩:%d\\t\\t\",p1->math);
printf(\"英语成绩:%d\\n\",p1->english);
printf(\"c语言成绩:%d\\n\",p1->clanguage);
break;
case POSTGRADUATE :
printf(\"类型:研究生\\n\");
printf(\"课程论文成绩:%d\\t\\t\",p1->comprehensive);
printf(\"毕业论文成绩:%d\\n\",p1->thesis);
break;
}
printf(\"总成绩:%d\\n\",p1->totalscore);
printf(\"班级排名:%d\\t\\t\",p1->classrank);
printf(\"年级排名:%d\\n\",p1->schoolrank);
printf(\"****************************************\\n\");
}
break;
}
p1=p1->next;
}
printf(\"****************************************\\n\");
printf(\"查询结束,任意键继续...\");
getch();
}
}
//根据ID查询学生成绩信息
void queryById(){
Student * p1=myHead;
int id=-1;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入学号:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(id<0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"****************************************\\n\");
while(p1!=NULL){
if(id==p1->id){
printf(\"学号:%d\\t\\t\",p1->id);
printf(\"姓名:%s\\n\",p1->name);
printf(\"性别:%s\\t\\t\",p1->sex);
printf(\"班级:%d\\n\",p1->classes);
printf(\"专业:%s\\n\",p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"类型:本科生\\n\");
printf(\"高数成绩:%d\\t\\t\",p1->math);
printf(\"英语成绩:%d\\n\",p1->english);
printf(\"c语言成绩:%d\\n\",p1->clanguage);
break;
case POSTGRADUATE :
printf(\"类型:研究生\\n\");
printf(\"课程论文成绩:%d\\t\\t\",p1->comprehensive);
printf(\"毕业论文成绩:%d\\n\",p1->thesis);
break;
}
printf(\"总成绩:%d\\n\",p1->totalscore);
printf(\"班级排名:%d\\t\\t\",p1->classrank);
printf(\"年级排名:%d\\n\",p1->schoolrank);
printf(\"****************************************\\n\");
break;
}
p1=p1->next;
}
printf(\"查询结束,任意键继续...\");
getch();
}
}
//根据姓名查询学生成绩信息
void queryByName(){
Student * p1=myHead;
char name[10];
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入名字:\");
gets(name);
printf(\"****************************************\\n\");
while(p1!=NULL){
if(strcmp(name,p1->name)==0){
printf(\"学号:%d\\t\\t\",p1->id);
printf(\"姓名:%s\\n\",p1->name);
printf(\"性别:%s\\t\\t\",p1->sex);
printf(\"班级:%d\\n\",p1->classes);
printf(\"专业:%s\\n\",p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"类型:本科生\\n\");
printf(\"高数成绩:%d\\t\\t\",p1->math);
printf(\"英语成绩:%d\\n\",p1->english);
printf(\"c语言成绩:%d\\n\",p1->clanguage);
break;
case POSTGRADUATE :
printf(\"类型:研究生\\n\");
printf(\"课程论文成绩:%d\\t\\t\",p1->comprehensive);
printf(\"毕业论文成绩:%d\\n\",p1->thesis);
break;
}
printf(\"总成绩:%d\\n\",p1->totalscore);
printf(\"班级排名:%d\\t\\t\",p1->classrank);
printf(\"年级排名:%d\\n\",p1->schoolrank);
printf(\"****************************************\\n\");
}
p1=p1->next;
}
}
printf(\"查询结束,任意键继续...\");
getch();
}
//根据班级和学生种类查询学生成绩信息
void queryByClassAndCategory(){
Student * p1=myHead;
int cate=-1;
int clazz=-1;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(cate<0||cate>1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入班级:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(clazz<=0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&clazz);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
while(p1!=NULL){
if(p1->category==cate&&p1->classes==clazz){
printf(\"****************************************\\n\");
printf(\"学号:%d\\t\\t\",p1->id);
printf(\"姓名:%s\\n\",p1->name);
printf(\"性别:%s\\t\\t\",p1->sex);
printf(\"班级:%d\\n\",p1->classes);
printf(\"专业:%s\\n\",p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"类型:本科生\\n\");
printf(\"高数成绩:%d\\t\\t\",p1->math);
printf(\"英语成绩:%d\\n\",p1->english);
printf(\"c语言成绩:%d\\n\",p1->clanguage);
break;
case POSTGRADUATE :
printf(\"类型:研究生\\n\");
printf(\"课程论文成绩:%d\\t\\t\",p1->comprehensive);
printf(\"毕业论文成绩:%d\\n\",p1->thesis);
break;
}
printf(\"总成绩:%d\\n\",p1->totalscore);
printf(\"班级排名:%d\\t\\t\",p1->classrank);
printf(\"年级排名:%d\\n\",p1->schoolrank);
}
p1=p1->next;
}
printf(\"****************************************\\n\");
printf(\"查询结束,任意键继续...\");
getch();
}
}
//查询所有学生成绩信息
void query_all(){
char c1;
int count=0;
int tmp=0;
Student * p1=myHead;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
while(1){
while(p1!=NULL){
count++;
printf(\"学号:%d\\t\\t\",p1->id);
printf(\"姓名:%s\\n\",p1->name);
printf(\"性别:%s\\t\\t\",p1->sex);
printf(\"班级:%d\\n\",p1->classes);
printf(\"专业:%s\\n\",p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"类型:本科生\\n\");
printf(\"高数成绩:%d\\t\\t\",p1->math);
printf(\"英语成绩:%d\\n\",p1->english);
printf(\"c语言成绩:%d\\n\",p1->clanguage);
break;
case POSTGRADUATE :
printf(\"类型:研究生\\n\");
printf(\"课程论文成绩:%d\\t\\t\",p1->comprehensive);
printf(\"毕业论文成绩:%d\\n\",p1->thesis);
break;
}
printf(\"总成绩:%d\\n\",p1->totalscore);
printf(\"班级排名:%d\\t\\t\",p1->classrank);
printf(\"年级排名:%d\\n\",p1->schoolrank);
printf(\"****************************************\\n\");
p1=p1->next;
if(count%10==0&&p1!=NULL){
if(count==10){
printf(\"[n]下一页 [e]尾页 [esc]退出\");
getch4: c1=getch();
if(c1==27){
return;
}else if(c1==\'e\'){
system(\"cls\");
updateSchoolCount(); //更新学校排名
tmp=(schoolCount[0]+schoolCount[1])/10*10;
for(;count<tmp;count++){
p1=p1->next;
}
}else if(c1==\'n\'){
system(\"cls\");
}
else{
goto getch4;
}
}else{
printf(\"[f]首页 [l]上一页 [n]下一页 [e]尾页 [esc]退出\");
getch3: c1=getch();
if(c1==27){
return;
}else if(c1==\'e\'){
system(\"cls\");
updateSchoolCount();
tmp=(schoolCount[0]+schoolCount[1])/10*10;
for(;count<tmp;count++){
p1=p1->next;
}
}else if(c1==\'f\'){
system(\"cls\");
count=0;
p1=myHead;
}else if(c1==\'l\'){
system(\"cls\");
count=(count-1)/10*10-10;;
p1=myHead;
for(tmp=0;tmp<count;tmp++){
p1=p1->next;
}
}else if(c1==\'n\'){
system(\"cls\");
}
else{
goto getch3;
}
}
}
}
printf(\"没有更多的数据录了!\\n\");
if(count>10){
printf(\"[f]首页 [l]上一页 [esc]退出\");
getch2: c1=getch();
if(c1==\'f\'){
system(\"cls\");
count=0;
p1=myHead;
}else if(c1==\'l\'){
system(\"cls\");
count=(count-1)/10*10-10;;
p1=myHead;
for(tmp=0;tmp<count;tmp++){
p1=p1->next;
}
}else if(c1==27){
return;
}
else{
goto getch2;
}
}else{
printf(\"[esc]退出\");
getch1: c1=getch();
if(c1==27){
return;
}else {
goto getch1;
}
}
}
}
}
//修改学生成绩信息
void edit_node(){
Student * p1=myHead;
Student * pre=NULL;
int cate=-1;
int id=-1;
int sum=0;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生信息,无法修改...\\n\");
getch();
return;
}
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(cate>1||cate<0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入学号:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(id<0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
p1=query_node(cate,id);//根据学生种类和学生学号查询
if(p1==NULL){
printf(\"无该学生记录!任意键继续...\\n\");
getch();
}
else{
printf(\"请输入该生的新数据\\n\");
printf(\"姓名:\");
scanf(\"%s\",&p1->name);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
printf(\"性别:\");
scanf(\"%s\",p1->sex);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(strcmp(p1->sex,boy)!=0&&strcmp(p1->sex,girl)!=0){
printf(\"输入有误,请重新输入:\");
scanf(\"%s\",p1->sex);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"班级:\");
scanf(\"%d\",&p1->classes);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->classes<=0){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->classes);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"专业:\");
gets(p1->specialty);
switch(p1->category){
case UNDERGRADUATE:
printf(\"高数成绩:\");
scanf(\"%d\",&p1->math);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->math<-1||p1->math>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->math);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->math!=-1)
sum+=p1->math;
printf(\"英语成绩:\");
scanf(\"%d\",&p1->english);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->english<-1||p1->english>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->english);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->english!=-1)
sum+=p1->english;
printf(\"c语言成绩:\");
scanf(\"%d\",&p1->clanguage);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->clanguage<-1||p1->clanguage>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->clanguage);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->clanguage!=-1)
sum+=p1->clanguage;
break;
case POSTGRADUATE :
printf(\"课程论文成绩:\");
scanf(\"%d\",&p1->comprehensive);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->comprehensive<-1||p1->comprehensive>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->comprehensive);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->comprehensive!=-1)
sum+=p1->comprehensive;
printf(\"毕业论文成绩:\");
scanf(\"%d\",&p1->thesis);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->thesis<-1||p1->thesis>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->thesis);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->thesis!=-1)
sum+=p1->thesis;
break;
}
p1->totalscore=sum;
pre=findPre(p1);//查找节点的前一个学生信息
if(pre==NULL){
myHead=p1->next;
}else{
pre->next=p1->next;
}
p1->next=NULL;
insert_node(p1);//插入学生信息到链表中
updateRank();//更新链表中学生排名
printf(\"****************************************\\n\");
printf(\"修改完成!任意键继续...\\n\");
getch();
}
}
//查找某节点的前一个学生信息
Student * findPre(Student *student){
Student * p=myHead;
Student * pre=NULL;
if(p==NULL){
return NULL;
}
if(student==NULL||student==p){
return NULL;
}
while(p!=student){
pre=p;
p=p->next;
}
return pre;
}
//根据学生种类和学生学号查询
Student * query_node(int cate,int id){
Student * p=myHead;
if(p==NULL){
return NULL;
}
while(((p->id!=id)||(p->category!=cate))&&(p->next!=NULL)) p=p->next;
if((p->id!=id)||(p->category!=cate)) p=NULL;
return p;
}
//插入学生信息到链表中
void insert_node(Student *student){
Student *p0=NULL,*p1=NULL,*p2=NULL;
p1=myHead;
p0=student;
if(myHead==NULL){
myHead=p0;
p0->next=NULL;
}else{
while((p0->totalscore<p1->totalscore)&&(p1->next!=NULL)){
p2=p1;
p1=p1->next;
}
if(p0->totalscore>=myHead->totalscore){
p0->next=myHead;
myHead=p0;
}
else if(p0->totalscore<p1->totalscore){
p1->next=p0;
p0->next=NULL;
}
else{
p2->next=p0;
p0->next=p1;
}
}
}
//更新链表中所有学生的排名
void updateRank(){
int i=0;
int j=0;
int schoolRank[2]; //校级排名
int schoolLastScore[2]; //最后一个人的成绩
int classCount[2][100]; //总人数
int classLastScore[2][100]; //最后成绩
int classRank[2][100]; //班级排名
int cate=-1;
Student * p=myHead;
//初始化数组
for(i=0;i<2;i++){
for(j=0;j<100;j++){
classLastScore[i][j]=-1;
classRank[i][j]=0;
classCount[i][j]=0;
}
}
schoolRank[0]=0;
schoolRank[1]=0;
schoolCount[0]=0; //两种学生类型总人数
schoolCount[1]=0;
schoolLastScore[0]=-1;
schoolLastScore[1]=-1;
if(myHead==NULL){
return;
}
while(p!=NULL){
cate=p->category;
classCount[cate][(p->classes)]++;
schoolCount[cate]++;
if(schoolLastScore[cate]!=p->totalscore){
schoolLastScore[cate]=p->totalscore;
schoolRank[cate]=schoolCount[cate];
}
p->schoolrank=schoolRank[cate]; //校级排名
if(classLastScore[cate][(p->classes)]!=p->totalscore){
classLastScore[cate][(p->classes)]=p->totalscore;
classRank[cate][(p->classes)]=classCount[cate][(p->classes)];
}
p->classrank=classRank[cate][(p->classes)]; //班级排名
p=p->next;
}
}
//获取用户要插入的学生成绩信息
void insert_node0(){
int i=0;
int num=0;
int cate=-1;
int totalscore=0;
Student *p1=NULL;
system(\"cls\");
printf(\"请输入录入数量:\");
scanf(\"%d\",&num);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(num<0)
{
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&num);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
for(i=1;i<=num;i++)
{
totalscore=0;
if((p1=(Student *)malloc(sizeof(Student)))==NULL) //新节点
{
printf(\"不能成功分配存储块\");
exit(0);
}
//p1->next=NULL; //新节点指向空
repeinsert:
printf(\"请输入第%d个学生的学号:\",i);
scanf(\"%d\",&p1->id); //新节点指向id
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->id<0)
{
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->id);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入第%d个学生的类型(0:本科生,1:研究生):\",i);
scanf(\"%d\",&p1->category); //新节点指向category
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->category<0||p1->category>1)
{
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->category);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(!isCateAndIdViable(p1->category,p1->id)){ //查询插入的学生学号和学生种类是否已经被保存,函数返回为0,已存在
printf(\"所输入类型的学号已经存在,请重新输入,任意键继续...\\n\");
getch();
system(\"cls\");
goto repeinsert;
}
printf(\"请输入第%d个学生的姓名:\",i);
scanf(\"%s\",&p1->name);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
printf(\"请输入第%d个学生的性别(男、女):\",i);
scanf(\"%s\",p1->sex);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(strcmp(p1->sex,boy)!=0 && strcmp(p1->sex,girl)!=0) //对两个字符串自左至右逐个字符相比(按ASCII码值大小比较),=时返回0
{
printf(\"输入有误,请重新输入:\");
scanf(\"%s\",p1->sex);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入第%d个学生的班级:\",i);
scanf(\"%d\",&p1->classes);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->classes<=0)
{
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->classes);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
printf(\"请输入第%d个学生的专业:\",i);
gets(p1->specialty);
switch(p1->category){
case UNDERGRADUATE: //本科生
printf(\"请输入第%d个学生的高数成绩:\",i);
scanf(\"%d\",&p1->math);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->math<-1||p1->math>100)
{
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->math);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->math!=-1) totalscore+=p1->math; //总成绩里加高数成绩
printf(\"请输入第%d个学生的英语成绩:\",i);
scanf(\"%d\",&p1->english);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->english<-1||p1->english>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->english);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->english!=-1) totalscore+=p1->english; //总成绩里加英语成绩
printf(\"请输入第%d个学生的c语言成绩:\",i);
scanf(\"%d\",&p1->clanguage);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->clanguage<-1||p1->clanguage>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->clanguage);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->clanguage!=-1) totalscore+=p1->clanguage; //总成绩里加c语言成绩
break;
case POSTGRADUATE : //研究生
printf(\"请输入第%d个学生的课程论文成绩:\",i);
scanf(\"%d\",&p1->comprehensive);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->comprehensive<-1||p1->comprehensive>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->comprehensive);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->comprehensive!=-1) totalscore+=p1->comprehensive;
printf(\"请输入第%d个学生的毕业论文成绩:\",i);
scanf(\"%d\",&p1->thesis);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(p1->thesis<-1||p1->thesis>100){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&p1->thesis);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
if(p1->thesis!=-1) totalscore+=p1->thesis;
break;
}
p1->totalscore=totalscore;
insert_node(p1); //插入学生信息到链表中
updateRank(); //更新链表中学生的排名
printf(\"****************************************\\n\");
}
printf(\"录入成功,任意键继续...\");
getch();
return;
}
//查询插入的学生学号和学生种类是否已经被保存
int isCateAndIdViable(int cate,int id)
{
Student *p1=myHead;
if(p1==NULL) return 1;
while(p1!=NULL){
if(p1->category==cate&&p1->id==id){
return 0;
}
p1=p1->next; //跟踪链表增长
}
return 1;
}
//更新学校排名
void updateSchoolCount()
{
Student * student=myHead;
if(myHead==NULL){
schoolCount[0]=0;
schoolCount[1]=0;
return;
}
schoolCount[0]=0;
schoolCount[1]=0;
while(student!=NULL){
schoolCount[student->category]++;
student=student->next;
}
}
//退出系统的时候释放链表所占的内存空间
void release(){
Student * p=myHead;
Student * p1=NULL;
while(p!=NULL){
p1=p->next;
free(p);
p=p1;
}
myHead=NULL;
}
//打印报表
void stampscore(){
Student * p1=myHead;
int cate=-1;
system(\"cls\");
if(p1==NULL){
printf(\"没有学生记录,任意键继续...\\n\");
getch();
return;
}else{
printf(\"请输入类型(0:本科生,1:研究生):\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
while(cate<0||cate>1){
printf(\"输入有误,请重新输入:\");
scanf(\"%d\",&cate);
while ((tmp = getchar()) != EOF && tmp != \'\\n\');
}
system(\"cls\");
if (cate==0){
printf(\"*******************************本科生成绩报表**********************************\\n\");
printf(\"学号\\t姓名\\t性别\\t班级\\t专业\\t高数\\t英语\\tc语言\\t总成绩\\t校级排名\\n\");
}
else{
printf(\"*******************************研究生成绩报表**********************************\");
printf(\"学号\\t姓名\\t性别\\t班级\\t专业\\t课程论文 毕业论文 总成绩 校级排名\\n\");
}
while(p1!=NULL){
if(p1->category==cate){
switch(cate){
case UNDERGRADUATE:
printf(\"%d\\t%s\\t%s\\t%d\\t%s\\t%d\\t%d\\t%d\\t%d\\t%d\\n\",
p1->id,p1->name,p1->sex,p1->classes,p1->specialty,p1->math,p1->english,p1->clanguage,p1->totalscore,p1->schoolrank);
break;
case POSTGRADUATE :
printf(\"%d\\t%s\\t%s\\t%d\\t%s\\t%d\\t%5d\\t%8d\\t%d\\n\",
p1->id,p1->name,p1->sex,p1->classes,p1->specialty,p1->comprehensive,p1->thesis,p1->totalscore,p1->schoolrank);
break;
}
}
p1=p1->next;
}
printf(\"*******************************************************************************\\n\");
}
printf(\"查询结束,任意键继续...\");
getch();
}