#include#include #include #include #include #define header1 " --------------------------------学生--------------------------------- n" #define header2 " | 学号 | 班级 | 姓名 | 语文 | 数学 | 英语 | 总分 | 平均成绩 |n" #define header3 " |----------|------|----------|------|------|------|------|----------|n" int saveflag=0; //表示是否需要对数据进行存盘 struct student //表示学生的相关信息 { char num[10]; //学号 char name[10]; //姓名 char grade[5]; //班级 int chinesemark; //语文成绩 int mathmark; //数学成绩 int englishmark; //英语成绩 int totalmark; //总成绩 double averagemark; //平均分 }; typedef struct node //创建链表结点 { struct student data; struct node *next; }node,*link; void gotoxy(int x,int y) //设置光标的位置 { coord c; c.x=x-1; c.y=y-1; setconsolecursorposition(getstdhandle(std_output_handle),c); } void menu() //主菜单显示 { system("cls"); //清屏 system("color bd"); //设定字体和背景颜色 gotoxy(15,4); printf(" 学生成绩管理信息系统"); gotoxy(14,7); printf("************************菜单***************************"); gotoxy(14,9); printf("* 1 添加学生记录 2 删除学生记录 3 查找学生记录 *"); gotoxy(14,11); printf("* 4 修改学生记录 5 单科成绩排名 6 总成绩排名 *"); gotoxy(14,13); printf("* 7 信息预览 8 不及格人数统计 9 最高分统计 *"); gotoxy(14,15); printf("* 10 保存数据 0 退出本系统 *"); gotoxy(14,17); printf("*******************************************************nn"); } node* locate(link l,char findness[],char nameornum[]) //查找记录定位 { node *r; if(strcmp(nameornum,"num")==0) //按学号查找 { r=l->next; while(r) { if(strcmp(r->data.num,findness)==0) return r; r=r->next; //如果找到,则返回结点 } } else if(strcmp(nameornum,"name")==0) //按姓名查找 { r=l->next; while(r) { if(strcmp(r->data.name,findness)==0) return r; r=r->next; } } return 0; //如果没有找到,则返回null } void printfheader() //打印表头 { printf(header1); printf(header2); printf(header3); } void printdata(node *p) //打印一个记录信息 { printf(" |%10s|%6s|%10s| %3d | %3d | %3d | %3d |%10.2f|n",p->data.num,p->data.grade,p->data.name, p->data.chinesemark,p->data.mathmark,p->data.englishmark,p->data.totalmark,p->data.averagemark); } void stringinput(char *t,unsigned int lens,char *notice) //输入字符串 { char s[20]; do { printf(notice); //输出提示信息 scanf("%s",s); if(strlen(s)>lens-1) printf("========>您输入的信息长度超出范围!n"); }while(strlen(s)>lens); strcpy(t,s); } int numinput(char *notice) { int num; do { printf(notice); //输出提示信息 scanf("%d",&num); if(num>100||num<0) printf("========>您输入的分数有误!,请重新输入n"); }while(num>100||num<0); return num; } void display(link l) //预览打印信息 { node *p,*r; int choice,select; char grade[5]; char ch='y'; char findness[20]; int flag; p=l->next; if(p==null) //如果没有学生记录 { printf("n============>没有学生记录!n"); getchar(); printf("请按任意键返回主菜单n"); system("pause"); return; } printf("nn"); printf(" 学生信息预览nn"); while(ch=='y'||ch=='y') { printf(" 1 按班级对学生信息预览 2 对个人进行信息预览n"); printf(" 请输入您的选择:(1-2):"); scanf("%d",&choice); getchar(); p=l->next; flag=0; if(choice==1) { printf("=========>请输入班级(1-?):"); scanf("%s",grade); while(p) //检测输入的班级是否存在学生记录 { if(strcmp(p->data.grade,grade)==0) { flag++; } p=p->next; } if(flag==0) { printf("========>没有该班学生的记录!n"); } else { p=l->next; printfheader(); while(p) { if(strcmp(p->data.grade,grade)==0) { printdata(p); printf(header3); } p=p->next; } } getchar(); printf("n========>是否继续进行预览?(y/n):"); scanf("%c",&ch); getchar(); } else { printf("==========>1 按学号进行预览 2 按姓名进行预览n"); printf(" 请输入您的选择:(1-2):"); scanf("%d",&select); getchar(); if(select==1) //学号查找 { printf("========>请输入学号:"); scanf("%s",findness); r=locate(l,findness,"num"); //记录查找定位 if(r==null) //如果该学生记录不存在 { printf("========>该学生记录不存在!n"); } else { printfheader(); printdata(r); printf(header3); } } else //姓名查找 { printf("========>请输入姓名:"); scanf("%s",findness); r=locate(l,findness,"name"); if(r==null) { printf("========>该学生记录不存在!n"); } else { printfheader(); printdata(r); printf(header3); } } getchar(); printf("n========>是否继续进行预览?(y/n):"); scanf("%c",&ch); } } } void add(link l) //添加学生记录 { node *p,*r,*s; char ch1,ch2,flag=0,num[10]; r=l; s=l->next; system("cls"); while(r->next!=null) //让r指向链表结尾,以添加记录 { r=r->next; } ch2='y'; while(ch2=='y'||ch2=='y') { while(1) { stringinput(num,10,"请输入学生的学号(输入0表示返回主菜单):"); flag=0; if(strcmp(num,"0")==0) //如果输入0,则返回主菜单 { return; } s=l->next; while(s) //检测输入的学号是否已存在 { if(strcmp(s->data.num,num)==0) { flag=1; break; } s=s->next; } if(flag==1) //输入的学号已存在 { getchar(); printf("此学号已存在,是否重新输入?(y/n):"); scanf("%c",&ch1); if(ch1=='y'||ch1=='y') continue; else return; } else { break; } } p=(node *)malloc(sizeof(node)); //输入相关信息,建立学生记录结点 strcpy(p->data.num,num); stringinput(p->data.grade,5,"请输入学生的班级(1-?):"); stringinput(p->data.name,10,"请输入学生的姓名:"); p->data.chinesemark=numinput("请输入语文成绩(0-100):"); p->data.mathmark=numinput("请输入数学成绩(0-100):"); p->data.englishmark=numinput("请输入英语成绩(0-100):"); p->data.totalmark=p->data.chinesemark+p->data.mathmark+p->data.englishmark; p->data.averagemark=p->data.totalmark/3.0; p->next=null; r->next=p; r=p; saveflag=1; getchar(); printf("n是否继续添加学生记录?(y/n):"); scanf("%c",&ch2); } return; } void delete(link l) //删除学生记录 { int select; node *p,*r; char findness[15]; char ch; p=l->next; ch='y'; system("cls"); if(p==null) //如果不存在学生记录 { printf("n没有学生信息记录!请按任意键返回主菜单.....n"); system("pause"); return; } printfheader(); while(p) { printdata(p); printf(header3); p=p->next; } printf(" 删除学生记录n"); while(ch=='y'||ch=='y') { printf("=============>1 通过学号删除 2 通过姓名删除n"); printf("请输入您的选择(1-2):"); scanf("%d",&select); if(select==1) //学号删除 { stringinput(findness,10,"请输入要删除学生的学号:"); r=locate(l,findness,"num"); if(r) { p=l; while(p->next!=r) p=p->next; p->next=r->next; //合并节点来删除学生记录 } else { printf("n您的输入有误,该学生记录不存在!n"); printf("=====>是否继续删除?(y/n):"); getchar(); scanf("%c",&ch); continue; } free(r); printf("=====>是否继续删除?(y/n):"); getchar(); scanf("%c",&ch); saveflag=1; } else if(select==2) //姓名删除 { stringinput(findness,10,"请输入要删除学生的姓名:"); r=locate(l,findness,"name"); if(r) { p=l; while(p->next!=r) p=p->next; p->next=r->next; } else { printf("n您的输入有误,该学生记录不存在!n"); printf("=====>是否继续删除?(y/n):"); getchar(); scanf("%c",&ch); continue; } free(r); printf("=====>是否继续删除?(y/n):"); getchar(); scanf("%c",&ch); saveflag=1; } else { printf("n您的输入有误!n"); printf("=====>是否继续删除?(y/n):"); getchar(); scanf("%c",&ch); } } } void search(link l) //查找学生记录 { node *p,*r; int select; char ch; char findness[15]; ch='y'; p=l->next; system("cls"); //清屏 if(p==null) { printf("=========>没有学生记录!请按任意键返回主菜单......n"); getchar(); system("pause"); return; } while(ch=='y'||ch=='y') { printf(" 查找学生记录nn"); printf(" 1 按学号查找 2 按姓名查找n"); printf("请输入您的选择(1-2):"); scanf("%d",&select); getchar(); if(select==1) //按学号进行查找 { stringinput(findness,10,"请输入你要查找学生的学号:"); r=locate(l,findness,"num"); if(r==null) //如果该学生记录不存在 { printf("您的输入有误!该学生记录不存在!n"); } else { printfheader(); printdata(r); printf(header3); } printf("======>是否继续进行查找?(y/n):"); getchar(); scanf("%c",&ch); } else if(select==2) //按姓名查找 { stringinput(findness,10,"请输入你要查找学生的姓名:"); r=locate(l,findness,"name"); if(r==null) //如果该学生记录不存在 { printf("您的输入有误!该学生记录不存在!n"); } else { printfheader(); printdata(r); printf(header3); } printf("======>是否继续进行查找?(y/n):"); getchar(); scanf("%c",&ch); } else { printf("您的输入有误!n"); printf("======>是否继续进行查找?(y/n):"); scanf("%c",&ch); } } } void modify(link l) //修改学生记录 { node *p,*r; char ch='y'; char findness[15]; p=l->next; system("cls"); if(p==null) { printf("n========>没有学生记录nn请按任意键返回主菜单....."); getchar(); getchar(); return; } printf(" 修改学生记录nn"); while(ch=='y'||ch=='y') { stringinput(findness,10,"请输入要修改学生的学号:"); r=locate(l,findness,"num"); //根据学号找出该学生记录的结点 if(r==null) { printf("========没有该学生记录!是否继续修改?(y/n):"); getchar(); scanf("%c",&ch); continue; } else //进行修改,重新输入数据 { printf("请重新输入姓名: "); scanf("%s",r->data.name); printf("请重新输入班级: "); scanf("%s",r->data.grade); printf("请重新输入语文成绩: "); scanf("%d",&r->data.chinesemark); printf("请重新输入数学成绩: "); scanf("%d",&r->data.mathmark); printf("请重新输入英语成绩: "); scanf("%d",&r->data.englishmark); r->data.totalmark=r->data.chinesemark+r->data.mathmark+r->data.englishmark; r->data.averagemark=r->data.totalmark/3.0; saveflag=1; printf("========>是否继续修改?(y/n):"); getchar(); scanf("%c",&ch); } } } void sort1(link l) //单科成绩排名 { node *p,*r,*s; link l; int select; char ch='y'; p=l->next; system("cls"); if(p==null) { printf("n========>没有学生记录!nn请按任意键返回主菜单.....n"); getchar(); getchar(); return; } printf(" 单科成绩排名nn"); printf(" 1 按语文成绩排名 2 按数学成绩排名 3 按英语成绩排名n"); while(ch=='y'||ch=='y') { printf("======>请输入您的选择(1-3):"); scanf("%d",&select); l=(node *)malloc(sizeof(node)); l->next=null; //新的链表头结点 if(select==1) //插入法进行排序,语文成绩排名 { p=l->next; while(p) { s=(node *)malloc(sizeof(node)); //申请结点存放取出的学生记录 s->data=p->data; s->next=null; r=l; while(r->next&&r->next->data.chinesemark>s->data.chinesemark) //查找 { r=r->next; } if(r->next==null) //如果所有的学生成绩比取出的低 { r->next=s; } else { s->next=r->next; r->next=s; } p=p->next; } } else if(select==2) //数学成绩排名 { p=l->next; while(p) { s=(node *)malloc(sizeof(node)); s->data=p->data; s->next=null; r=l; while(r->next&&r->next->data.mathmark>s->data.mathmark) { r=r->next; } if(r->next==null) { r->next=s; } else { s->next=r->next; r->next=s; } p=p->next; } } else //英语成绩排名 { p=l->next; while(p) { s=(node *)malloc(sizeof(node)); s->data=p->data; s->next=null; r=l; while(r->next&&r->next->data.englishmark>s->data.englishmark) { r=r->next; } if(r->next==null) { r->next=s; } else { s->next=r->next; r->next=s; } p=p->next; } } l->next=l->next; p=l->next; printfheader(); while(p) { printdata(p); printf(header3); p=p->next; } printf("========>是否继续?(y/n):"); getchar(); scanf("%c",&ch); getchar(); } return; } void sort2(link l) //总成绩排名 { node *p,*r,*s; link l; p=l->next; system("cls"); if(p==null) { printf("========>没有学生记录!n请按任意键返回主菜单......"); getchar(); getchar(); return; } l=(node *)malloc(sizeof(node)); l->next=null; p=l->next; while(p) { s=(node *)malloc(sizeof(node)); //申请结点存放取出的学生记录 s->data=p->data; s->next=null; r=l; while(r->next&&r->next->data.totalmark>s->data.totalmark) //查找 { r=r->next; } if(r->next==null) { r->next=s; } else { s->next=r->next; r->next=s; } p=p->next; } l->next=l->next; p=l->next; printf(" 综合成绩排名n"); printfheader(); while(p) { printdata(p); printf(header3); p=p->next; } printf("n========>请按任意键返回主菜单......."); getchar(); getchar(); } void topmark(link l) //最高分统计 { node *topchinese,*topmath,*topenglish,*toptotal; node *p; int topchinesemark=0,topmathmark=0,topenglishmark=0,toptotalmark=0; p=l->next; system("cls"); if(p==null) { printf("n======>没有学生记录!n请按任意键返回主菜单.....n"); getchar(); getchar(); return; } while(p) //查找最高分 { if(p->data.chinesemark>=topchinesemark) { topchinese=p; topchinesemark=p->data.chinesemark; } if(p->data.mathmark>=topmathmark) { topmath=p; topmathmark=p->data.mathmark; } if(p->data.englishmark>=topenglishmark) { topenglish=p; topenglishmark=p->data.englishmark; } if(p->data.totalmark>=toptotalmark) { toptotal=p; toptotalmark=p->data.totalmark; } p=p->next; } gotoxy(24,8); printf(" 最高分统计nn"); printf(" 语文最高分: %3d 姓名: %-10s 学号: %-10sn",topchinese->data.chinesemark, topchinese->data.name,topchinese->data.num); printf(" 数学最高分: %3d 姓名: %-10s 学号: %-10sn",topmath->data.mathmark, topmath->data.name,topmath->data.num); printf(" 英语最高分: %3d 姓名: %-10s 学号: %-10sn",topenglish->data.englishmark, topenglish->data.name,topenglish->data.num); printf(" 综合最高分: %3d 姓名: %-10s 学号: %-10sn",toptotal->data.totalmark, toptotal->data.name,toptotal->data.num); printf("nn请按任意键返回主菜单......"); getchar(); getchar(); return; } void count(link l) //统计各科不及格人数以及总不及格人数 { int chinesecount=0; int mathcount=0; int englishcount=0; int totalcount=0; node *p; p=l->next; system("cls"); if(p==null) //如果没有学生记录 { printf("n没有学生记录!n"); printf("请按任意键返回主菜单.....n"); getchar(); getchar(); return; } while(p) { if(p->data.chinesemark<60) //统计语文不及格人数 chinesecount++; if(p->data.englishmark<60) //统计英语不及格人数 englishcount++; if(p->data.mathmark<60) //统计数学不及格人数 mathcount++; if(p->data.chinesemark<60||p->data.englishmark<60||p->data.mathmark<60) //统计总不及格人数 totalcount++; p=p->next; } gotoxy(24,8); printf(" 不及格人数统计nn"); printf(" 语文不及格人数: %dnn",chinesecount); printf(" 数学不及格人数: %dnn",mathcount); printf(" 英语不及格人数: %dnn",englishcount); printf(" 总的不及格人数: %dnn",totalcount); printf("n请按任意键返回主菜单.....n"); getchar(); getchar(); return; } void save(link l) //保存数据到磁盘文件 { file *fp; node *p; fp=fopen("d:student.txt","wt"); //只写打开文件 if(fp==null) { printf("n打开数据文件失败!n"); getchar(); return; } p=l->next; while(p) { if(fwrite(p,sizeof(node),1,fp)==1) //将数据写入文件 { p=p->next; } else { break; } } printf("保存数据成功!n"); fclose(fp); } void wrong() //报错处理 { printf("============>错误提示:您的输入有误!n"); getchar(); } int main(void) { link l,p,r; //链表 file *fp; //文件指针 int select; //表示选择 char ch; //输入字符 l=(node*)malloc(sizeof(struct node)); //为链表申请头结点 if(!l) { printf("n 链表结点申请失败!n"); return 0; } l->next=null; r=l; fp=fopen("d:student.txt","at+"); //以追加方式打开一个文本文件,可读可写,若此文件不存在,则建立此文件 if(fp==null) { printf("n无法打开数据文件!n"); exit(0); } while(!feof(fp)) { p=(node*)malloc(sizeof(node)); if(!p) { printf("内存申请失败!n"); exit(0); } if(fread(p,sizeof(node),1,fp)==1) //一次从文件中读取一个学生信息记录 { p->next=null; r->next=p; r=p; } } fclose(fp); //关闭文件 menu(); while(1) { system("cls"); //清屏 menu(); p=r; printf("n 请选择操作(0-10):"); scanf("%d",&select); if(select==0) { if(saveflag==1) { getchar(); printf("n=========>是否保存数据?(y/n):"); scanf("%c",&ch); if(ch=='y'||ch=='y') save(l); } getchar(); break; } switch(select) { case 1: add(l);break; //添加学生记录 case 2: delete(l);break; //删除学生记录 case 3: search(l);break; //查找学生记录 case 4: modify(l);break; //修改学生记录 case 5: sort1(l);break; //按单科为学生进行成绩排名 case 6: sort2(l);break; //按总成绩为学生进行成绩排名 case 7: system("cls");display(l);break; //对学生信息进行预览打印 case 8: count(l);break; //对每科不及格的人数以及总不不及格人数进行统计 case 9: topmark(l);break; //对数据进行保存 case 10: save(l);break; default: wrong();getchar();break; } } return 0; }