学生成绩管理系统-C语言(附源码和课程设计报告)
这是我初学C语言时的课程设计作业,源码贴出来希望对有需要的小伙伴有所帮助
系统功能层次图
头文件源代码
#include<stdio.h>
#include<stdlib.h>
#define FILENAME"student.dat" //宏定义
typedef enum{MAN, WOMAN} SEX; //枚举型,常量符号化
typedef struct Student //定义学生结构体参数
{
int ID; //学号
char Name[20]; //姓名
SEX sex; //性别
float Mark1; //科目一成绩
float Mark2; //科目二成绩
float Mark3; //科目三成绩
float Total; //总成绩
struct Student *next; //下一个节点的指针
}STUDENT, *PSTUDENT;
void Showmenu(); //1、显示菜单
int GetMenuChoose(); //2、获取用户选择的菜单编号
PSTUDENT CreateStudent(); //3、创建一个节点,它会返回一个新创建的学生信息节点的指针
int AddStudent(PSTUDENT pstu); //4、把学生信息节点加入到链表中
PSTUDENT GetPrevAddr(int ID); //5、返回指定编号学生节点的上一个节点的指针
void ShowAll(); //6、显示所有学生信息
int ShowStudentCount(); //7、显示已有学生信息数量
void ModityStudent(int ID); //8、修改学生信息
int Question(const char *pstr); //9、获取用户的选择
int GetInputID(); //10、获取用户输入的学生的学号
void DelStudent(int ID); //11、删除学号为ID的学生信息
void DelAll(); //12、删除所有学生信息
void SaveToFile(); //13、把学生信息保存的文件当中
void LoadFromFile(); //14、从文件中读取学生信息
void Search(); //15、成绩查询
PSTUDENT GetAddr(int ID); //16、返回指定编号学生节点的指针
PSTUDENT InputScore(); //17、录入单科学习成绩
void Statistic(); //18、统计不符合要求的学生名单
void SerchResuls(); //19、浏览学生成绩
void Sort1(); //20、对学生科目一成绩进行排序
void Sort2(); //21、对学生科目二成绩进行排序
void Sort3(); //22、对学生科目三成绩进行排序
void Sort4(); //23、对学生总成绩进行排序
主函数源代码
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
int main()
{
STUDENT g_head; //头节点
int running = 1;
while(running)
{
switch(GetMenuChoose())
{
case 0:
running = 0;
break;
case 1:
AddStudent(CreateStudent());
break;
case 2:
DelStudent(GetInputID());
break;
case 3:
ModityStudent(GetInputID());
break;
case 4:
DelAll();
break;
case 5:
ShowAll();
break;
case 6:
AddStudent(InputScore());
break;
case 7:
SerchResuls();
break;
case 8:
Search();
break;
case 9:
Statistic();
case 10:
LoadFromFile();
break;
case 11:
SaveToFile();
break;
}
system("pause");
}
return 0;
}
添加学生信息
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//3、创建一个节点,它会返回一个新创建的学生信息节点的指针
PSTUDENT CreateStudent()
{
int sex;
float sum;
PSTUDENT pstu = (PSTUDENT)malloc(sizeof(STUDENT));//在堆内申存请空间,存储学生信息
if(!pstu)
{
printf("申请内存空间失败!\n");
return NULL;
}
printf("请输入学生的学号:");
while(1 != scanf("%d",&pstu->ID) || GetPrevAddr(pstu->ID))
{
printf("学生的学号输入错误或已经存在,请重新输入学生的学号:");
fflush(stdin);
}
printf("请输入学生的姓名(不超过20个字符):");
scanf("%20s",pstu->Name);
printf("请选择学生的性别(1.男 2.女):");
while(1 != scanf("%d",&sex) || sex < 1 || sex > 2)
{
printf("性别选择错误,请重新选择学生的性别(1.男 2.女):");
fflush(stdin);
}
if(1 == sex)
{
pstu->sex = MAN;
}
else
{
pstu->sex = WOMAN;
}
printf("请输入学生科目一的成绩:");
scanf("%3f",&pstu->Mark1);
printf("请输入学生科目二的成绩:");
scanf("%3f",&pstu->Mark2);
printf("请输入学生科目三的成绩:");
scanf("%3f",&pstu->Mark3);
sum = pstu->Mark1 + pstu->Mark2 + pstu->Mark3;
pstu->Total = sum;
printf("该学生的总成绩:%4.1f",pstu->Total);
pstu->next = NULL;
return pstu;
}
//4、把学生信息节点加入到链表中
int AddStudent(PSTUDENT pstu)
{
PSTUDENT ps = &g_head;
if(!pstu)
{
return 0;
}
//判断该学生信息是否已经存在
if(GetPrevAddr(pstu->ID))
{
printf("编号为%d的学生信息已存在!\n",pstu->ID);
free(pstu); //释放该节点的内存空间
return 0;
}
while(ps->next)//找到当前链表的最后一个节点
{
ps = ps->next;
}
//把新节点加到最后一个节点的后边
ps->next = pstu;
pstu->next = NULL;
return 1;
}
//5、返回指定编号学生节点的上一个节点的指针
PSTUDENT GetPrevAddr(int ID)
{
PSTUDENT pstu = &g_head;
while(pstu->next)
{
if(pstu->next->ID == ID)
{
return pstu;
}
pstu = pstu->next;
}
return NULL;
}
显示所有学生信息
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//6、显示所有学生信息
void ShowAll()
{
PSTUDENT pstu = &g_head;
printf("----------------------------------------------------------------------------\n");
printf(" 学号 姓 名 性别 科目一成绩 科目二成绩 科目三成绩 总成绩\n");
printf("----------------------------------------------------------------------------\n");
while(pstu->next)
{
printf("%d ",pstu->next->ID);
printf("%9s",pstu->next->Name);
printf(" %6s",pstu->next->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->next->Mark1);
printf(" %3.1f",pstu->next->Mark2);
printf(" %3.1f",pstu->next->Mark3);
printf(" %4.1f\n",pstu->next->Total);
pstu = pstu->next;//让指针指向下一个节点
}
printf("----------------------------------------------------------------------------\n");
ShowStudentCount();
}
//7、显示已有学生信息数量
int ShowStudentCount()
{
int count = 0;
PSTUDENT pstu = &g_head;
while(pstu->next)
{
count++;
pstu = pstu->next;
}
printf("\n当前共有%d位学生信息。\n",count);
return count;
}
删除学生信息
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//11、删除学号为ID的学生信息
void DelStudent(int ID)
{
PSTUDENT pstu;
PSTUDENT ptmp;
if(pstu = GetPrevAddr(ID))
{
if(!Question("确定要删除该学生信息吗?"))
{
return;
}
ptmp = pstu->next;
pstu->next = ptmp->next;
free(ptmp);//释放该节点的内存空间
printf("删除了学号为%d的学生信息。\n");
}
else
{
printf("没有找到学号为%d的学生信息。\n",ID);
}
}
//12、删除所有学生信息
void DelAll()
{
PSTUDENT pstu = g_head.next;
PSTUDENT ptmp;
int count = 0;
if(!Question("确定要删除当前所有的学生信息吗?"))
{
return;
}
while(pstu)
{
ptmp = pstu;
pstu = pstu->next;
free(ptmp);//释放该节点的内存空间
++count;
}
printf("共删除了%d位学生信息\n",count);
g_head.next = NULL;
}
录入单科学习成绩
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//17、录入单科学习成绩
PSTUDENT InputScore()
{
int sex;
int sub;
PSTUDENT pstu = (PSTUDENT)malloc(sizeof(STUDENT));//在堆内申存请空间,存储学生信息
pstu->Mark1 = 0.0;
pstu->Mark2 = 0.0;
pstu->Mark3 = 0.0;
if(!pstu)
{
printf("申请内存空间失败!\n");
return NULL;
}
printf("请输入学生的学号:");
while(1 != scanf("%d",&pstu->ID) || GetPrevAddr(pstu->ID))//判断学号输入是否正确或是否已录入信息
{
printf("学生的学号输入错误或已经存在,请重新输入学生的学号:");
fflush(stdin);
}
printf("请输入学生的姓名(不超过20个字符):");
scanf("%20s",pstu->Name);
printf("请选择学生的性别(1.男 2.女):");
while(1 != scanf("%d",&sex) || sex < 1 || sex > 2)
{
printf("性别选择错误,请重新选择学生的性别(1.男 2.女):");
fflush(stdin);
}
if(1 == sex)
{
pstu->sex = MAN;
}
else
{
pstu->sex = WOMAN;
}
printf("请选择录入该学生哪科成绩(1、2、3):\n");
scanf("%d",&sub);
if(sub == 1)
{
printf("请输入学生科目一的成绩:");
scanf("%3f",&pstu->Mark1);
pstu->Total = pstu->Mark1 + pstu->Mark2 + pstu->Mark3;
}
if(sub == 2)
{
printf("请输入学生科目二的成绩:");
scanf("%3f",&pstu->Mark1);
pstu->Total = pstu->Mark1 + pstu->Mark2 + pstu->Mark3;
}
if(sub == 3)
{
printf("请输入学生科目三的成绩:");
scanf("%3f",&pstu->Mark1);
pstu->Total = pstu->Mark1 + pstu->Mark2 + pstu->Mark3;
}
pstu->next = NULL;
return pstu;
}
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//10、获取用户输入的学生的学号
int GetInputID()
{
int ID;
printf("请输入学生的学号:");
while(1 != scanf("%d",&ID));
{
// printf("学号输入错误!请重新输入学生的学号(整型):");
fflush(stdin);
}
return ID;
}
显示菜单
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//1、显示菜单
void Showmenu()
{
system("cls");
printf("-----------------------------学生成绩管理系统--------------------------------\n");
printf("\n\t1、添加学生信息 2、删除某个学生信息 3、修改学生信息\n");
printf("\t4、删除所有学生信息 5、显示所有学生信息 6、录入单科学习成绩\n ");
printf("\t7、查看单科成绩排名 8、成绩查询 9、统计所有不合格学生名单\n");
printf("\t10、从文件中读取学生信息 11、把学生信息保存到文件当中\n");
printf("\t0、退出系统\n");
printf("\n-----------------------------------------------------------------------------\n");
}
//2、获取用户选择的菜单编号
int GetMenuChoose()
{
int num;//保存用户选择的菜单编号
Showmenu();
printf("请选择菜单(0~11):");
while(1 != scanf("%d",&num) || num < 0 || num > 11)
{
Showmenu();
printf("选择菜单错误,请重新选择(0~10):");
fflush(stdin);//清空输入缓冲区
}
}
修改学生信息
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//8、修改学生信息
void ModityStudent(int ID)
{
PSTUDENT pstu = GetPrevAddr(ID);//获取要修改的学生节点的上一个节点
int choose;
if(!pstu)
{
printf("没有学号为%d的学生信息。\n",ID);
return;
}
pstu = pstu->next;//将要修改的学生节点的指针改为指向自己的
printf("当前学生的姓名为%s\n",pstu->Name);
if(Question("确定要修改嘛?\n"))
{
printf("请输入学生的姓名(不超过20个字符):");
scanf("%20s", pstu->Name);
}
printf("当前学生的性别为%s ",pstu->sex == MAN ? "男" : "女");
if(Question("确定要修改嘛?"))
{
printf("请输入学生的性别(1、男 2、女):");
while(1 != scanf("%d",&choose) || choose < 1 || choose > 2)
{
printf("输入错误,请重新输入学生的性别(1、男 2、女):");
fflush(stdin);
}
if(1 == choose)
{
pstu->sex = MAN;
}
else
{
pstu->sex = WOMAN;
}
}
printf("当前学生的科目一的成绩为%3.1f\n",pstu->Mark1);
if(Question("确定要修改嘛?\n"))
{
printf("请输入该学生的科目一成绩:");
scanf("%3f",&pstu->Mark1);
}
printf("当前学生的姓名科目二的成绩为%3.1f\n",pstu->Mark2);
if(Question("确定要修改嘛?\n"))
{
printf("请输入该学生的科目二成绩:");
scanf("%3f",&pstu->Mark2);
}
printf("当前学生的科目三的成绩为%3.1f\n",pstu->Mark3);
if(Question("确定要修改嘛?\n"))
{
printf("请输入该学生的科目三成绩:");
scanf("%3f",&pstu->Mark3);
}
printf("修改完毕!\n");
}
从文件中读取学生信息
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//14、从文件中读取学生信息
void LoadFromFile()
{
int i;
int count = 0;
int repeat = 0;
FILE *pf;
PSTUDENT pstu;
printf("提示:从文件中读取数据会询问是否清空当前学生信息(不清空表示合并所有信息)。\n");
if((pf = fopen(FILENAME,"rb")) == NULL)
{
printf("文件还没有创建,请手工输入学生信息并保存!\n");
return;
}
DelAll();//删除之前的所有学生信息,然后从文件中读取
fread(&count, 1, sizeof count, pf);//获取学生信息的数量
for(i = 0; i < count; ++i)
{
pstu = (PSTUDENT)malloc(sizeof(STUDENT));
fread(pstu, 1, sizeof(STUDENT),pf);
if(!AddStudent(pstu))
{
++repeat;//保存有多少个和当前链表中已有的学生信息相重复的已有的学生信息
}
}
fclose(pf);
printf("文件读取完毕!新增学生信息%d条。\n",count - repeat);
}
把学生信息保存到文件当中
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//13、把学生信息保存到文件当中
void SaveToFile()
{
FILE *pf = fopen(FILENAME,"wb");//以二进制的方式写入文件
PSTUDENT pstu = &g_head;
int i = 0;
int count = ShowStudentCount();
if(!pf)
{
printf("打开待写入的文件失败!\n");
return;
}
if(!Question("确定要将当前学生信息保存到文件中吗?"))
{
fclose(pf);
return;
}
fwrite(&count, 1, sizeof(count),pf);//把学生信息的数量先写入到文件头
while(pstu->next)
{
fwrite(pstu->next, 1, sizeof(STUDENT),pf);//把每位学生信息写入文件
++i;
pstu = pstu->next;
}
fclose(pf);
if(i == count)
{
printf("成功的写入了%d条学生信息。\n",count);
}
else
{
printf("应写入%d条学生信息,实际写入%d条学生信息。\n",count,i);
}
}
成绩查询
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//15、成绩查询
void Search()
{
int ID;
//PSTUDENT pstu;
printf("请输入所要查询成绩学生的学号:");
scanf("%d",&ID);
PSTUDENT pstu = GetPrevAddr(ID);
if(pstu == NULL)
{
printf("学生的学号输入错误或已经存在");
return;
}
printf("----------------------------------------------------------------------------\n");
printf(" 学号 姓 名 性别 科目一成绩 科目二成绩 科目三成绩 总成绩\n");
printf("----------------------------------------------------------------------------\n");
printf("%d ",pstu->next->ID);
printf("%9s",pstu->next->Name);
printf(" %6s",pstu->next->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->next->Mark1);
printf(" %3.1f",pstu->next->Mark2);
printf(" %3.1f",pstu->next->Mark3);
printf(" %4.1f\n",pstu->next->Total);
printf("----------------------------------------------------------------------------\n");
}
//16、返回指定编号学生节点的指针
PSTUDENT GetAddr(int ID)
{
PSTUDENT pstu = &g_head;
while(pstu->next)
{
if(pstu->ID == ID)
{
return pstu->next;
}
pstu = pstu->next;
}
return NULL;
}
单科成绩排名
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//19、浏览学生成绩
void SerchResuls()
{
int t;//排名菜单操作按钮存储位置
system("cls");
printf("\t\t------------------------------------\n");
printf("\t\t| 1、按科目一成绩排名查看信息 |\n");
printf("\t\t| 2、按科目二成绩排名查看信息 |\n");
printf("\t\t| 3、按科目三成绩排名查看信息 |\n");
printf("\t\t| 4、按总成绩排名查看信息 |\n");
printf("\t\t------------------------------------\n");
printf("请输入选项:");
scanf("%d",&t);
switch(t)
{
case 1:
Sort1();//排序
break;
case 2:
Sort2();//排序
break;
case 3:
Sort3();//排序
break;
case 4:
Sort4();//排序
break;
default:
printf("无效选项!\n");
break;
}
}
//20、对学生科目一成绩进行排序
void Sort1()
{
int first;//储存该学科的最高成绩,初定为100;
int rank = 0;//记录名次
PSTUDENT pstu = g_head.next;
if(pstu == NULL)//判断是否有学生信息
{
printf("没有学生信息!\n");
}
else
{
printf("---------------------------------------------------------\n");
printf(" 学号 姓 名 性别 成绩 排名\n");
printf("---------------------------------------------------------\n");
for(first = 100; first >= 0; first--)
{
pstu = g_head.next;
while(pstu != NULL)
{
if((int)pstu->Mark1 == first)
{
rank++;
printf("%d ",pstu->ID);
printf("%9s",pstu->Name);
printf(" %6s",pstu->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->Mark1);
printf(" %3d",rank);
printf("\n");
}
pstu = pstu->next;
}
}
}
}
//21、对学生科目二成绩进行排序
void Sort2()
{
int first;//储存该学科的最高成绩,初定为100;
int rank = 0;//记录名次
PSTUDENT pstu = g_head.next;
if(pstu == NULL)//判断是否有学生信息
{
printf("没有学生信息!\n");
}
else
{
printf("---------------------------------------------------------\n");
printf(" 学号 姓 名 性别 成绩 排名\n");
printf("---------------------------------------------------------\n");
for(first = 100; first >= 0; first--)
{
pstu = g_head.next;
while(pstu != NULL)
{
if((int)pstu->Mark2 == first)
{
rank++;
printf("%d ",pstu->ID);
printf("%9s",pstu->Name);
printf(" %6s",pstu->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->Mark2);
printf(" %3d",rank);
printf("\n");
}
pstu = pstu->next;
}
}
}
}
//22、对学生科目三成绩进行排序
void Sort3()
{
int first;//储存该学科的最高成绩,初定为100;
int rank = 0;//记录名次
PSTUDENT pstu = g_head.next;
if(pstu == NULL)//判断是否有学生信息
{
printf("没有学生信息!\n");
}
else
{
printf("---------------------------------------------------------\n");
printf(" 学号 姓 名 性别 成绩 排名\n");
printf("---------------------------------------------------------\n");
for(first = 100; first >= 0; first--)
{
pstu = g_head.next;
while(pstu != NULL)
{
if((int)pstu->Mark3 == first)
{
rank++;
printf("%d ",pstu->ID);
printf("%9s",pstu->Name);
printf(" %6s",pstu->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->Mark3);
printf(" %3d",rank);
printf("\n");
}
pstu = pstu->next;
}
}
}
}
//23、对学生总成绩进行排序
void Sort4()
{
int first;//储存该学科的最高成绩,初定为100;
int rank = 0;//记录名次
PSTUDENT pstu = g_head.next;
if(pstu == NULL)//判断是否有学生信息
{
printf("没有学生信息!\n");
}
else
{
printf("---------------------------------------------------------\n");
printf(" 学号 姓 名 性别 成绩 排名\n");
printf("---------------------------------------------------------\n");
for(first = 300; first >= 0; first--)
{
pstu = g_head.next;
while(pstu != NULL)
{
if((int)pstu->Total == first)
{
rank++;
printf("%d ",pstu->ID);
printf("%9s",pstu->Name);
printf(" %6s",pstu->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->Total);
printf(" %3d",rank);
printf("\n");
}
pstu = pstu->next;
}
}
}
}
统计挂科超过两科的同学名单
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//18、统计不符合要求的学生名单
void Statistic()
{
PSTUDENT pstu = &g_head;
int a = 0;//不符合要求的学生人数计数器
system("cls");
printf("以下是有两科及以上不及格同学的信息:\n");
printf("----------------------------------------------------------------------------\n");
printf(" 学号 姓 名 性别 科目一成绩 科目二成绩 科目三成绩 总成绩\n");
printf("----------------------------------------------------------------------------\n");
for(; pstu->next != NULL; pstu = pstu->next)
{
if((pstu->next->Mark1 < 60 && pstu->next->Mark2 < 60) || (pstu->next->Mark1 < 60 && pstu->next->Mark3 < 60) || (pstu->next->Mark2 < 60 && pstu->next->Mark3 < 60))
{
printf("%d ",pstu->next->ID);
printf("%9s",pstu->next->Name);
printf(" %6s",pstu->next->sex == MAN ? "男" : "女");
printf(" %3.1f",pstu->next->Mark1);
printf(" %3.1f",pstu->next->Mark2);
printf(" %3.1f",pstu->next->Mark3);
printf(" %4.1f\n",pstu->next->Total);
a++;
}
}
printf("----------------------------------------------------------------------------\n");
printf("共有%d人不合格",a);
}
获取用户选择
#include<stdio.h>
#include<stdlib.h>
#include"sms.h"
//9、获取用户的选择 给用户二次选择的机会
int Question(const char *pstr)
{
char answer;
printf("%s请选择(y or n):",pstr);
while(1 != scanf("%c",&answer) || (answer != 'y' && answer != 'n'))
{
//printf("输入错误!%s请重新选择选择(y or n):",pstr);
}
fflush(stdin);//清空输入缓冲区
if('y' == answer)
{
return 1;
}
else
{
return 0;
}
}
本系统运用了单链表,是自学的,理解上不算透彻,但是程序是可以运行的,在单科成绩排名模块中,算法有点缺陷,在用户数据庞大时系统可能会崩掉,1000人以内应该是可以轻松运行的。技术不佳,大佬勿喷。源码报告?拿走拿走
系统源码文件:
链接:https://pan.baidu.com/s/1cy6QbCkhnAwykuclkf294g
提取码:n70c
系统报告:
链接:https://pan.baidu.com/s/1OiVFCmkpjmvzAhMBEaupJA
提取码:
开发环境
操作系统:Windows10
开发工具:Dev-C++
PS:小白第一写文章,欢迎大家批评指正