目录
一、学生成绩管理系统简介
该系统基于C语言中的结构体与链表,基本功能有增,删,查,改,文件的保存,排序和一些查重的功能二、
- 学生成绩管理系统的详解
1.引入库
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
2.定义结构体
代码如下:
typedef struct _student
{
int num; //学号
char name[20]; //姓名
int age; //年龄
char sex[20]; //性别
float chinese; //语文成绩
float math; //数学成绩
double total; //总分
}student;
3.链表
代码如下:
//链表
typedef struct _Node
{
student stu; //数据域 student结构体
struct _Node* next; //指针域
}Node;
4.定义头节点
代码如下:
//头结点
Node* phead = NULL; //链表头结点
5.函数的声明
代码如下:
//门户
void welcome();
//录入学生成绩
void input_student();
//打印学生信息
void print_student();
//保存学生成绩
void Savestudent();
//按照学生总成绩排序
void line();
//统计学生人数
int Count_Student();
void count();
//查找学生信息
void Find_stu();
//修改学生信息
void change_stu();
//删除学生信息
void deletestudent();
//判断性别
void PDsex();
//按姓名查找学生信息
void Name_Fand();
//按学号查找学生信息
void ID_Fand();
//修改函数门面
void change_face();
// 学号 姓名 年龄 性别 语文成绩 数学成绩
//void change_id();
void change_name();
void change_age();
void change_sex();
void change_chinese();
void change_math();
void change_all();
6.主函数
代码如下:
int main()
{
phead=(Node*)malloc(sizeof(Node));//链表空头
phead->next=NULL;
while(1)
{
welcome();
char ch = _getch();// 读取字符不需要回车确认 scanf getchar都需要回车确认
switch (ch)
{
case '1'://1.录入学生成绩
input_student();
break;
case '2'://2.打印学生成绩
print_student();
break;
case '3'://3.保存学生成绩
Savestudent();
break;
case '4'://4.统计所有学生人数
count();
break;
case '5'://5. 查找学生信息
Find_stu();
break;
case '6'://6.修改学生信息
change_stu();
break;
case '7'://7.删除学生信息
deletestudent();
break;
case'8':line();
fflush(stdin);
break;
case '0':// 0.退出系统
printf("感谢使用此系统\n");
exit(0);
break;
default://其他
printf("您的输入有误,请重新输入!!!\n");
system("pause");
system("cls");
break;
}
}
return 0;
}
注:
switch( )
{
case…
}
能够有效防止乱输东西
7.主菜单
代码如下:
void welcome()
{
printf("\t\t\t\t*************************************\n");
printf("\t\t\t\t* 欢迎使用学生成绩管理系统 *\n");
printf("\t\t\t\t*************************************\n");
printf("\t\t\t\t* 请选择功能列表 *\n");
printf("\t\t\t\t*************************************\n");
printf("\t\t\t\t* 1.录入学生成绩 *\n");
printf("\t\t\t\t* 2.打印学生成绩 *\n");
printf("\t\t\t\t* 3.保存学生成绩 *\n");
printf("\t\t\t\t* 4.统计所有学生人数 *\n");
printf("\t\t\t\t* 5.查找学生信息 *\n");
printf("\t\t\t\t* 6.修改学生信息 *\n");
printf("\t\t\t\t* 7.删除学生成绩 *\n");
printf("\t\t\t\t* 8.按总成绩排名 *\n");
printf("\t\t\t\t* 0.退出系统 *\n");
printf("\t\t\t\t*************************************\n");
}
8.添加学生
代码如下:
void input_student()
{
int a,x;
loop:printf("请问您要录入几个学生的信息\n");
x=scanf("%d",&a);// 利用返回值判断输入是否正确
if(x!=1)
{
printf("输入错误请重新输入\n");
fflush(stdin);
goto loop;
}
for(int i = 1;i <= a;i ++)
{
Node* pnewstu = (Node*)malloc(sizeof(Node));
pnewstu -> next = NULL;
//往链表里面插入一个节点 //头插法
if(phead == NULL)
{
phead = pnewstu;
}
else
{
pnewstu -> next = phead;
phead = pnewstu;
}
printf("请输入第%d个学生姓名:\n",i);
scanf("%s",&pnewstu->stu.name);
int x;
tp3:tp:printf("请输入第%d个学生的学号\n",i);
x=scanf("%d",&pnewstu->stu.num);
if(x!=1)
{
printf("学号只能为数字,请重新输入\n");
fflush(stdin);
goto tp;
}
if(pnewstu->stu.num<0)
{
printf("此学号不能为负数,请重新输入!\n");
fflush(stdin);
goto tp;
}
int c;
Node* q=phead->next;
while(q!=NULL)
{
c=q->stu.num;
if(pnewstu->stu.num==c)
{
printf("该学号已注册,请重新输入新的学号\n");
fflush(stdin);
goto tp3;
}
q=q->next;
}
int z;
tp2:printf("请输入第%d个学生年龄:\n",i);
z=scanf("%d",&pnewstu->stu.age);
if(z!=1)
{
printf("年龄只能为数字,请重新输入\n");
fflush(stdin);
goto tp2;
}
if(pnewstu->stu.age<0)
{
printf("年龄不能为零或者为负,请重新输入!\n");
fflush(stdin);
goto tp2;
}
getchar();
printf("请输入第%d个学生的性别\n",i);
scanf("%s",&pnewstu->stu.sex);
getchar();
PDsex();
int d;
tp4:printf("请输入第%d个学生语文成绩:\n",i);
d=scanf("%f",&pnewstu->stu.chinese);
if(d!=1)
{
printf("成绩只能为数字,请重新输入!\n");
fflush(stdin) ;
goto tp4;
}
if(pnewstu->stu.chinese<0)
{
printf("成绩只能为正数和零,请重新输入!\n");
fflush(stdin);
goto tp4;
}
int e;
tp5:printf("请输入第%d个学生数学成绩:\n",i);
e=scanf("%f",&pnewstu->stu.math);
if(e!=1&&pnewstu->stu.math<0)
{
printf("数学成绩只能为数字,并且成绩不能为负,请重新输入!\n");
fflush(stdin);
goto tp5;
}
if(pnewstu->stu.math<0)
{
printf("成绩只能为正数和零,请重新输入!\n");
fflush(stdin);
goto tp5;
}
pnewstu=pnewstu->next;
printf("学生信息录入成功!\n");
}
system("pause");
system("cls");
}
头插法
代码如下:
Node* pnewstu = (Node*)malloc(sizeof(Node));
pnewstu -> next = NULL;
//往链表里面插入一个节点 //头插法
if(phead == NULL)
{
phead = pnewstu;
}
else
{
pnewstu -> next = phead;
phead = pnewstu;
}
pnewstu=pnewstu->next;
图片:
申请下一个空间时,领下一个空间排在后一个空间的前面,新申请的空间变为头。
判断是否输入正确
代码如下:
利用返回值是否为1来判断输入是否正确
x=1则输入正确
x=0则输入错误
使用goto语句重新进行赋值
int a,x;
loop:printf("请问您要录入几个学生的信息\n");
x=scanf("%d",&a);// 利用返回值判断输入是否正确
if(x!=1)
{
printf("输入错误请重新输入\n");
fflush(stdin);
goto loop;
}
判断性别
代码如下:
特别将判断性别摘了出来,这个代码比较多,放在函数中会减少些代码量,并且后面的修改中也是有使用到。
输入时只能够输入 ‘男’ or ‘女’,输入其他的都会重新输入。
void PDsex()
{
while(1)
{
char man[3] = {"男"} ;
char woman[3] = {"女"};
Node* q = phead;
loop:if(strcmp(q->stu.sex,man))
{
if(strcmp(q->stu.sex,woman))
{
printf("性别只能为“男 ”或“女 ”再次输入性别\n");
scanf("%s",q->stu.sex);
goto loop;
}
}
if((strcmp(q->stu.sex,man)) || (strcmp(q->stu.sex,woman)))
{
return;
}
}
system("pause");
system("cls");
}
9.打印学生信息
代码如下:
将链表中的信息打印出来需要对链表进行遍历
//打印学生信息
void print_student()
{
system("cls");
//学号 姓名 年龄 性别 语文成绩 数学成绩
printf("************************************************************************************************\n");
printf("* 学生成绩展示 *\n");
printf("************************************************************************************************\n");
//遍历链表
Node* p = phead;
while(p != NULL)
{
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
printf("************************************************************************************************\n");
p = p->next;
}
system("pause");
system("cls");
}
10.删除学生信息
代码如下:
//删除学生信息
void deletestudent()
{
Count_Student();
if(Count_Student()==0)
{
printf("暂无学生信息,请添加后再进行此操作!\n");
system("pause");
system("cls");
return;
}
loop:int snum ,x;
printf("请输入要删除的学生的学号\n");
x=scanf("%d",&snum);
if(x!=1)
{
printf("学号信息只能为数字,请输入正确的学号信息后重试!\n");
fflush(stdin);
goto loop;
}
Node* p1;
//判断是不是头结点
if(phead->stu.num == snum)
{
p1 = phead;
free(p1);
phead = phead->next;
system("pause");
system("cls");
return;
}
Node* p = phead;
Node* p2;
while(p->next != NULL)
{
if(p->next->stu.num == snum)
{
p2 = p->next;//备份
p->next = p->next->next;//p->next指向下下一个数据的数据域
free(p2);//释放
printf("删除成功\n");
system("pause");
system("cls");
return;
}
p = p->next;
if(p->next == NULL)
{
break;
}
}
if(p->next == NULL)
{
printf("没有找到该学生\n");
}
system("pause");
system("cls");
}
11.查询
代码如下:
//查找学生信息
void Find_stu()
{
while(1)
{
Count_Student();
if(Count_Student()==0)
{
printf("暂无学生信息,请添加后再进行此操作!\n");
system("pause");
system("cls");
return;
}
system("cls");
welcome();
printf("请选择查找类型;\n");
printf("1.按姓名查找\n");
printf("2.按学号查找\n");
printf("0.返回主页面\n");
char ch=_getch();
switch (ch)
{
case '1'://按姓名查找
Name_Fand();
break;
case '2'://按学号查找
ID_Fand();
break;
case'0':
system("pause");
system("cls");
return;
default:printf("输入错误,请重新选择功能\n");
system("pause");
system("cls");
break;
}
}
}
使用学号查询
代码如下:
void ID_Fand()
{
loop:Node* p=phead;
int id;
printf("请输入要查找学生的学号信息:\n");
scanf("%d",&id);
while(p)
{
if(p->stu.num==id)
{
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}//姓名 年龄 性别 语文成绩 数学成绩
使用姓名查询
代码如下:
void Name_Fand()//按姓名查找学生信息
{
Node *p=phead;
char name[20];
printf("请输入你要查找的学生姓名:\n");
scanf("%s",name);
while(p)
{
if(strcmp(p->stu.name,name)==0)
{
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
}
p = p->next;
}
if(p==NULL)
{
printf("暂无该生信息\n");
}
system("pause");
system("cls");
}
12.修改学生信息
代码如下:
修改的主菜单:
void change_face()// 姓名 年龄 性别 语文成绩 数学成绩
{
printf("1.修改姓名\n");
printf("2.修改年龄\n");
printf("3.修改性别\n");
printf("4.修改语文成绩\n");
printf("5.修改数学成绩 \n");
printf("6.修改全部信息\n");
printf("0.返回主页\n");
}
修改的函数主题:
//修改学生信息
void change_stu()
{
Count_Student();
if(Count_Student()==0)
{
printf("暂无学生信息,请添加再进行此操作!\n");
system("pause");
system("cls");
return;
}
while(1)
{
system("cls");
welcome();
change_face();
char ch;
ch=_getch();
switch(ch)//姓名 年龄 性别 语文成绩 数学成绩
{
case '1':change_name();//修改姓名
break;
case '2': change_age();//修改年龄
break;
case'3':change_sex();//修改性别
break;
case '4':change_chinese();//修改语文成绩
break;
case '5':change_math();//修改数学成绩
break;
case '6':change_all();//修改所有信息
break;
case '0':
system("pause");
system("cls");
return;
default:printf("输入有误,请重新输入!\n");
break;
}
}
}
修改姓名
代码如下:
void change_name()
{
tp:int num,x;
printf("1.修改姓名\n");
printf("请输入需要修改的学号信息:\n");
x=scanf("%d",&num);
if(x!=1)
{
printf("输入的学号只能为数字,请重新输入!\n");
fflush(stdin);
goto tp;
}
Node* p=phead;
while(p)
{
if(p->stu.num==num)
{
char name[20];
printf("请输入要修改的学生姓名:\n");
scanf("%s",p->stu.name);
printf("修改成功\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}
修改年龄
代码如下:
void change_age()
{
tp:int num,x;
printf("2.修改年龄\n");
printf("请输入需要修改学生的学号信息:\n");
x=scanf("%d",&num);
if(x!=1)
{
printf("输入的学号只能为数字,请重新输入!\n");
fflush(stdin);
goto tp;
}
Node* p=phead;
while(p)
{
if(p->stu.num==num)
{
tp2:int z;
printf("请输入修改后的学生年龄:\n");
z=scanf("%d",&p->stu.age);
if(z!=1)
{
printf("年龄只能为数字,请重新输入:\n");
fflush(stdin);
goto tp2;
}
if(p->stu.age<0)
{
printf("年龄不能为负\n");
fflush(stdin);
goto tp2;
}
if(p->stu.age>256)
{
printf("年龄过大,请重新输入!\n");
fflush(stdin);
goto tp2;
}
else
{
printf("修改成功!\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}
修改性别
代码如下:
void change_sex()
{
void PDsex();
tp:int num,x;
printf("3.修改性别\n");
printf("请输入需要修改学生的学号信息:\n");
x=scanf("%d",&num);
if(x!=1)
{
printf("输入的学号只能为数字,请重新输入!\n");
fflush(stdin);
goto tp;
}
Node* p=phead;
while(p)
{
if(p->stu.num==num)
{
printf("请输入修改后的学生性别:\n");
scanf("%s",&p->stu.sex);
PDsex();
printf("修改成功!\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}
修改语文成绩
代码如下:
void change_chinese()
{
tp:int num,x;
printf("4.修改语文成绩\n");
printf("请输入需要修改学生的学号信息:\n");
x=scanf("%d",&num);
if(x!=1)
{
printf("输入的学号只能为数字,请重新输入!\n");
fflush(stdin);
goto tp;
}
Node* p=phead;
while(p)
{
if(p->stu.num==num)
{
tp2:int z;
printf("请输入修改后的学生语文成绩:\n");
z=scanf("%d",&p->stu.chinese);
if(z!=1)
{
printf("成绩只能为数字,请重新输入:\n");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese<0)
{
printf("成绩不能为负\n");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese>150)
{
printf("成绩过大,超出正常值!\n");
fflush(stdin);
goto tp2;
}
else
{
printf("修改成功!\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}
修改数学成绩
代码如下:
void change_math()
{
tp:int num,x;
printf("5.修改数学成绩\n");
printf("请输入需要修改学生的学号信息:\n");
x=scanf("%d",&num);
if(x!=1)
{
printf("输入的学号只能为数字,请重新输入!\n");
fflush(stdin);
goto tp;
}
Node* p=phead;
while(p)
{
if(p->stu.num==num)
{
tp2:int z;
printf("请输入修改后的学生数学成绩:\n");
z=scanf("%d",&p->stu.chinese);
if(z!=1)
{
printf("成绩只能为数字,请重新输入:\n");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese<0)
{
printf("成绩不能为负\n");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese>150)
{
printf("成绩过大,超出正常值!\n");
fflush(stdin);
goto tp2;
}
else
{
printf("修改成功!\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
}
p=p->next;
}
if(p==NULL)
{
printf("暂无该学生信息\n");
}
system("pause");
system("cls");
}
修改全部信息
代码如下:
void change_all()
{
printf("6.修改该学生所有信息\n");
loop:printf("请输入想要修改的学生的学号信息\n");
int snum,x;
x=scanf("%d",&snum);
if(x!=1)
{
printf("学号只能为数字,请重新输入\n");
fflush(stdin);
goto loop;
}
Node *p = phead;
while(p)
{
if(p->stu.num == snum)
{
printf("请输入并修改该学生的:姓名,年龄,性别,语文成绩,数学成绩\n");
printf("请输入学生的姓名:\n");
scanf("%s",p->stu.name);
int z;
tp1:printf("请输入学生年龄:\n");
z=scanf("%d",&p->stu.age);
if(z!=1)
{
printf("年龄只能为数字,请重新输入\n");
fflush(stdin);
goto tp1;
}
if(p->stu.age<0)
{
printf("年龄不能为负,请重新输入!\n");
fflush(stdin);
goto tp1;
}
if(p->stu.age>256)
{
printf("年龄过大,请重新输入\n");
fflush(stdin);
goto tp1;
}
getchar();
printf("请输入学生的性别\n");
scanf("%s",&p->stu.sex);
getchar();
PDsex();
int d;
tp2:printf("请输入学生语文成绩:\n");
d=scanf("%f",&p->stu.chinese);
if(d!=1)
{
printf("成绩只能为数字,请重新输入\n!");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese<0)
{
printf("成绩只能为正数和0,请重新输入!\n");
fflush(stdin);
goto tp2;
}
if(p->stu.chinese>150)
{
printf("成绩过大,超出正常值!\n");
fflush(stdin);
goto tp2;
}
int e;
tp3:printf("请输入学生数学成绩:\n");
e=scanf("%f",&p->stu.math);
if(e!=1)
{
printf("数学成绩只能为数字,请重新输入!\n");
fflush(stdin);
goto tp3;
}
if(p->stu.math<0)
{
printf("成绩只能为正数和0,请重新输入!\n");
fflush(stdin);
goto tp3;
}
if(p->stu.math>150)
{
printf("成绩过大,超出正常值!\n");
fflush(stdin);
goto tp3;
}
printf("修改成功\n");
p->stu.total=p->stu.chinese+p->stu.math;
printf("学号:%d\t姓名:%s\t年龄:%d\t性别:%s\t语文成绩:%.2f\t数学成绩:%.2f\t总分:%.2lf\t\n",
p->stu.num,
p->stu.name,
p->stu.age,
p->stu.sex,
p->stu.chinese,
p->stu.math,
p->stu.total);
break;
}
p=p->next;
system("pause");
system("cls");
}
if(p==NULL)
{
printf("暂无该学生\n");
}
system("pause");
system("cls");
}
13.排序
代码如下:
void line()
{
fflush(stdin);
int i = 0,j;
double g[100]; //定义一个数组用来存放总成绩
int k = 0;
Node* p = phead;
while(p)
{
p->stu.total=p->stu.chinese+p->stu.math;
g[k]=p->stu.total;
k++;
p=p->next; //将每个人的总成绩存入一个数组中
}
for(i=0;i<k;i++) //按总分数从高到低的顺序进行排序
{
for(j=0;j<k-i;j++)
{
if(g[j]<g[j+1])
{
int t;
t=g[j];
g[j]=g[j+1];
g[j+1]=t;
}
}
}
printf("按总分从高到低的顺序输出: \n");
for(i=0;i<=k;i++)
{
p=phead;
while(p)
{ p->stu.total=p->stu.chinese+p->stu.math; //如果刚才便利的总成绩和文件中的一样就输出那个人的信息
if(g[i]==p->stu.total)
{
printf("姓名:%s ",p->stu.name);
printf("学号:%d ",p->stu.num);
printf("性别:%s ",p->stu.sex);
printf("语文:%.2f ",p->stu.chinese);
printf("数学:%.2f ",p->stu.math);
printf("总分:%.2f\n",p->stu.total);
printf("\n");
}
p=p->next; //内循环中指针走向下一个节点
}
}
system("pause");
system("cls");
}