历经一个星期的努力
打磨出一个较为完整的学生成绩管理系统
注意:本文实在文件中直接读取学生的数据
而不是手动添加
暂时没有增加添加学生的功能
后期更新(多添加一个函数的事情)
所有源代码在本文的末尾
运行环境:windows
由于使用了windows的一个库
所以在linux下会出错
稍微修改一下也是可以运行的
qq交流群:1046260719 进群可答疑以及课程设计报告等
效果图
先上结果图
界面
菜单
浏览所有信息
呈现出一个成绩表的效果
查询每一个人的数据
分两种查询方式:姓名和学号
修改学生数据
两种修改方式:姓名和学号
并能完成实时的更新总分和排名
删除学生数据
两种修改方式:姓名和学号
并显示删除学生的数据
计算各科成绩的等级
总数本来是30人
由于删除了一个人
所以是29
能完成实时的数据更新
各科成绩的最高分最低分和总分
退出系统
退出时将更新的数据写在一个新的文件当中
实现系统
搭建框架
三个文件
student.h 头文件function.cpp 函数文件main.cpp 主函数
####主函数实现菜单的选择
浏览学生信息查询学生信息修改学生信息删除学生信息各科成绩最高分最低分
#include"student.h"#define _CRT_SECURE_NO_WARNINGSint main(){char answer;int choice;struct student *head ;head = create(); sort(head);printf("\t\t\t学生成绩管理系统\n");printf("\n\t************STUDENT-SCORE-SYSTEM 5.0***************\n");printf("\n\t************powered by 信卓11801聂健***************\n");printf("\n\t\t\t按任意键登录系统\n");getchar();system("cls");do{printf("欢迎你,管理员!\n");printf("|---------------------------------------|\n");printf("|\t请输入选项编号(0-6):\t\t|");printf("\n|---------------------------------------|\n");printf("|\t1--浏览学生信息:\t\t|\n");printf("|\t2--查询学生信息:\t\t|\n");printf("|\t3--修改学生信息:\t\t|\n");printf("|\t4--删除学生信息:\t\t|\n");printf("|\t5--各科成绩:\t\t\t|\n");printf("|\t6--最高分:\t\t\t|\n");printf("|\t0--退出系统:\t\t\t|\n");printf("|---------------------------------------|\n");printf("请输入选项");scanf("%d",&choice);fflush(stdin);switch(choice){case 0:{printf("********退出系统*********\n");filein(head);//将修改后的成绩保存在data11.txt中printf("修改的数据已经保存在data11.txt中\n");printf("欢迎下次使用\n");exit(0);break;}case 1:{system("cls");printf("*************学生成绩一览表********************\n");printf("学号\t姓名\t课程1\t课程2\t课程3\t总分\t排名\n");print(head); //打印所有人的信息printf("\n按任意键继续回到菜单\n");getch();system("cls");break;}case 2:{while(1){printf("请选择查询方式\n");printf("1.姓名\n2.学号\n");scanf("%s",&answer);if( answer == '1' ){locatename(head);//查询信息}if(answer == '2' ){locatenum(head);}if(answer != '1' && answer!= '2'){printf("输入错误\n");}printf("1.按任意键回车后继续查询\n0.退出\n");scanf("%s",&answer);fflush(stdin);if(answer == '0' ){break;}}printf("\n按任意键回到菜单");getch();system("cls");break;}case 3:{while(1){printf("请选择修改成绩的方式\n");printf("1.姓名\n2.学号\n");scanf("%s",&answer);if(answer == '1'){changename(head);sort(head); //修改成绩后重新排序}if(answer == '2'){changenum(head);sort(head); //修改成绩后重新排序}if(answer != '1' && answer!= '2'){printf("输入错误\n");}printf("是否继续\n");printf("1.按任意键回车后继续修改\n0.退出\n");scanf("%s",&answer);if(answer=='0'){break;}}printf("\n按任意键回到菜单\n");getch();system("cls");break;}case 4:{while(1){printf("请选择删除学生的方式\n");printf("1.姓名\n2.学号\n");scanf("%s",&answer);if(answer=='1'){head= delname(head); //删除头时头要换sort(head); //删除学生后重新排序}if(answer=='2'){head= delnum(head); //删除头时头要换sort(head); //删除学生后重新排序}if(answer != '1' && answer!= '2'){printf("输入错误\n");}printf("是否继续\n");printf("1.继续删除\n0.退出\n");scanf("%s",&answer);if(answer=='0'){break;}}printf("\n按任意键继续执行你想要的操作");getch();system("cls");break;}case 5:{ABCD(head);//计算人数printf("\n按任意键继续执行你想要的操作");getch();system("cls");break;}case 6:{max(head);printf("\n按任意键继续执行你想要的操作");getch();system("cls");break;}default:{printf("********没有这个选项*********\n按任意键重新输入\n");getch();break;}} }while(1); return 0;}
在上述的case中加入函数即可完成整个系统
书写各个函数
首先创建一个链表
struct student * create()
在创建链表这个函数返回一个head
在主函数的开头为head开辟一个空间
并使
head = create()
那么在其他函数中调用这个head
就可以访问到这个链表中的所有元素
值得注意的是在删除元素后,因为可能会把头给删掉
所以我们同样要返回头
在其他函数中没有这个要求
使用void无返回值即可
当然也是可以的
//返回headstruct student * delname(struct student *head)//通过姓名删除学生
//返回headstruct student * delnum(struct student *head)//通过学号删除学生
void locatename(struct student *head)//通过姓名去查询数据//调用这个头指针//即可遍历这个链表中的所有数据
void locatenum(struct student *head)//通过学号去查询数据//调用这个头指针//即可遍历这个链表中的所有数据
void changename(struct student *head)//通过姓名去改变数据//调用这个指针//即可遍历这个链表中的所有数据
void changenum(struct student *head)//通过学号去改变数据//调用这个指针//即可遍历这个链表中的所有数据
void sort(struct student *head)//排名//为什么要单独写一个函数//老师在检查我的课设的时候我是这样回答的:因为删除学生或者修改学生数据后排名会大声变化,//所以写成一个函数,以实现每次的实时更新数据
void print(struct student *head)//打印所有的信息//实现菜单1的功能
void ABCD(struct student *head)//统计ABCD等级//并将此结果写进一个新的文件中设为abcd.txt
void max(struct student *head)//实现最高分以及最低分以及对应的姓名//并将此结果写进一个文件当中设为max.txt//老师在检查课设的时候现场让我添加的一个功能,所以写的有点仓促,并且用了很简单粗暴的方法
void fulein(struct student *head)//将更新后的数据写进文件中//将这个函数放在退出系统的那一个菜单//另外其他两个文件必须要进入那两个菜单中才能实现写进文件中//当然也可以放在退出系统的那一个菜单中,此时需要定义全局变量
实现各个函数的功能
由于每个函数中都传入了一个参数head
那么都可以访问到链表中的所有数据
这样的话就比较简单了
从一个比较难的系统到实现每个小的功能
所以我建议在做这样的系统的时候
首先要搭好框架
再逐步实现每个模块的功能
这样就变得很简单了
创建链表
struct student{char name[20];float s1;float s2;float s3;float sum;int rank;struct student *next;};//在头文件中定义
struct student * create()//建立基础的学生信息库 从文件中将学生信息读取出来{char title[100];FILE *fp;struct student *head, *p , *q;p = q = (struct student *)malloc(LEN);if( ( fp = fopen("data00.txt","r") ) == NULL ){printf( "can't open file\n" );exit(1);}fgets( title, 100, fp );head = p;fscanf( fp , "%ld%s%f%f%f\n",&q->num, p->name, &p->s1,&p->s2,&p->s3 );p->sum = p->s1 + p->s2 + p->s3;while(!feof(fp)){q = (struct student *)malloc(LEN);fscanf( fp,"%ld%s%f%f%f%\n", &q->num,q->name, &q->s1,&q->s2,&q->s3 );q->sum = q->s1 + q->s2 + q->s3;p->next = q;p = q;}p->next = NULL;fclose(fp);return head;}
解释:
由于在第一行数据中是字符串
所以使用fgets读取第一行数据
//动态创建链表的过程struct student *p,*q,*head;p = q = (struct student *)malloc(sizeof(struct student))//开辟空间head = pwhile(p!=NULL){q = (struct student *)malloc(sizeof(struct student));p->next = q;p = q;}p->next = NULL;return head;//在while中将数据域加入即可
由于上述实在文件中读取数据
所以形式上有不同的地方
但是本质是相同的
查询信息
struct student *p,*q;p = head;q = p->next;if(p匹配即头匹配){打印p的数据域}else{while(q && 不匹配){q = q->next;}if(q匹配){打印q的数据域}else{NONE}}
删除学生
struct student *p , *q;p = head;while( p不匹配 && p->next!=NULL){q = p;p = p->next;}//一旦匹配,跳出whileif(匹配){if( p == head ) //如果是头匹配{head = p->next;//换头,此过程就把头也删了}else{q->next = p->next;}}if(不匹配){NONE}return head;//当删除了头时,把新的头返回
修改学生信息
struct student *p ,*q;p = head;while(匹配&&p->next!=NULL){q = p;p = p->next;}if(匹配){修改数据计算总分调用函数排名}
排名
struct student *p , *q ;p = head;while( p ) //擂台法进行排序{p->sum = p->s1 + p->s2 + p->s3;p->rank = 1;q = head;while(q!=p){if((q->sum) > (p->sum)){p->rank +=1;}else if((q->sum)< (p->sum)){q->rank +=1;}q=q->next;}p = p->next;}
输出学生信息
struct student *p;p = head;while(p){printp = p->next;}
计算最高分最低分
struct student *p,q,*summax,summin;p = head;q = head;summax = p;summin = q;while(p!=NULL){if(p->sum > summax->sum){summax = p;}p = p->next;}while(q!=NULL){if(q->sum > summin->sum){summin = q;}q = q->next;}printf("%f",summax->sum);printf("%f",summin->sum);
写进文件
FILE *fp;if((fp=fopen("result.txt","w"))==NULL)//打开文件 {printf("can't open.\n");exit(-1);}fprintf;fclose(fp);
以上就是实现的所有过程
找到了头就找到了所有的数据