#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu{
int term; // 学期
char grade[20]; // 班级
char num[20]; // 学号
char name[20]; // 姓名
float object[4]; // 三门课的 成绩,其中第0号元素存储总分
struct stu *next_stu; // 用于排序
struct stu *next; // 指向下一位同学
}STU;
STU *head = NULL; // 头指针
STU *tail = NULL; // 这是排序的头指针
// 新建tail指针,然后遍历,把是该学期该班级的学生结点有序添加如这个结点的位置,用next_stu来指向
void input(void);
void add(STU *p);
void revise(void);
void tongji(void);
void find_stu(void);
void find_list(void);
void output(void);
// 录入学生成绩
void input(void)
{
char ch;
STU *p = (STU *)malloc(sizeof(STU));
printf("请输入学期:");
scanf("%d", &p->term);
printf("请输入班级:");
scanf("%s", p->grade);
printf("请输入学号:");
scanf("%s", p->num);
printf("请输入姓名:");
scanf("%s", p->name);
printf("分别输入三门课的成绩:");
scanf("%f%f%f", &p->object[1], &p->object[2], &p->object[3]);
p->object[0] = p->object[1] + p->object[2] + p->object[3];
head = p;
p->next = NULL;
fflush(stdin);
while(1)
{
printf("是否继续录入(y/n):");
scanf("%c", &ch);
if(ch == 'n' || ch == 'N')
break;
if(ch != 'y' && ch != 'Y')
{
printf("你的输入有误,请重新输入\n");
continue;
}
STU *q = (STU *)malloc(sizeof(STU));
printf("请输入学期:");
scanf("%d", &q->term);
printf("请输入班级:");
scanf("%s", q->grade);
printf("请输入学号:");
scanf("%s", q->num);
printf("请输入姓名:");
scanf("%s", q->name);
printf("分别输入三门课的成绩:");
scanf("%f%f%f", &q->object[1], &q->object[2], &q->object[3]);
q->object[0] = q->object[1] + q->object[2] + q->object[3];
p->next = q;
q->next = NULL;
p = q;
fflush(stdin);
}
}
// 修改学生成绩
void revise(void)
{
STU *p = (STU *)malloc(sizeof(STU));
printf("请输入学期:");
scanf("%d", &p->term);
printf("请输入班级:");
scanf("%s", p->grade);
printf("请输入学号:");
scanf("%s", p->num);
printf("请输入姓名:");
scanf("%s", p->name);
printf("请输入修改后的三科成绩:");
scanf("%f%f%f", &p->object[1], &p->object[2], &p->object[3]);
p->object[0] = p->object[1] + p->object[2] + p->object[3];
STU *q = head;
while(q)
{
if(q->term == p->term && strcmp(q->grade, p->grade)==0 && strcmp(q->num, p->num)==0 && strcmp(q->name, p->name)==0)
{
for(int i=0; i<4; i++)
q->object[i] = p->object[i];
printf("修改成功\n");
return; // 如果找到了就直接返回
}
q = q->next;
}
// 如果没有找到
printf("未找到你要修改的学生信息,请检查是否输入有误\n");
return ;
}
// 统计学生成绩
void tongji(void)
{
int term;
char grade[20];
int n = 0; // 记录学生人数
float sum = 0.0; // 记录该班的总分
printf("请输入要统计的学期:");
scanf("%d", &term);
printf("请输入要统计的班级:");
scanf("%s", grade);
STU *p = head;
while(p) // 边统计边排序
{
if(p->term == term && strcmp(p->grade, grade)==0) // 若是那一个班的
{
sum += p->object[0];
n += 1;
add(p); // 把那个结点添加到顺序序列中
}
p = p->next;
}
printf("\n%s班在%d学期的班级分数统计为:\n", grade, term);
printf("总分:%.2f\t平均分:%.2f\n", sum, sum/n);
printf("\n学生成绩排序为:\n");
printf("学号\t\t姓名\t\t平均成绩\n");
STU *t = tail;
while(t)
{
printf("%s\t%s\t\t%.2f\n", t->num, t->name, t->object[0]/3);
t = t->next_stu;
}
}
// 添加一个结点到tail的链中
void add(STU *p)
{
if(tail == NULL) // 如果是第一个结点
{
tail = p;
p->next_stu = NULL;
return ;
}
// 寻找插入位置
STU *p1 = tail;
STU *p2 = tail; // 记录p1的前面一个结点
while(p1)
{
if(p->object[0] > p1->object[0]) // 顺序为从小到大
{
if(tail == p1 && p1->next_stu == NULL) // 如果当前结点就是头结点并且只有一个元素
{
tail = p;
p->next_stu = p1;
return ;
}
if(p1->next_stu == NULL) // 如果当前结点是尾结点
{
p2->next_stu = p;
p->next_stu = p1;
return ;
}
p2->next_stu = p; // 如果是其它情况
p->next_stu = p1;
return ;
}
p2 = p1;
p1 = p1->next_stu;
}
// 如果没有找到证明就是插在最后了
p2->next_stu = p;
p->next_stu = NULL;
return ;
}
// 查询学生成绩
void find_stu(void)
{
int term;
char num[20];
char name[20];
printf("请输入学期:");
scanf("%d", &term);
printf("请输入学号:");
scanf("%s", num);
printf("请输入姓名:");
scanf("%s", name);
STU *p = head;
while(p)
{
if(p->term == term && strcmp(p->num, num)==0 && strcmp(p->name, name)==0)
{
printf("他的成绩信息为:\n");
printf("总分:%.2f\n", p->object[0]);
printf("语文成绩:%.2f\t数学成绩:%.2f\t英语成绩:%.2f\n", p->object[1], p->object[2], p->object[3]);
if(p->object[1] < 60.0 || p->object[2] < 60.0 || p->object[3] < 60.0) // 看有没有不及格科目
{
printf("他的不及格科目有:");
if(p->object[1] < 60.0)
printf("语文\t");
if(p->object[2] < 60.0)
printf("数学\t");
if(p->object[3] < 60.0)
printf("英语\t");
puts("\n");
return ;
}
// 如果没有不及格科目
printf("他没有不及格科目");
return ;
// 如果没有不及格科目
printf("他没有不及格科目");
return ;
}
p = p->next;
}
// 如果没找到的话
printf("你要查找的学生未找到,请检查是否输入正确\n");
}
// 查询学生名单
void find_list(void)
{
int term;
char grade[20];
printf("请输入学期:");
scanf("%d", &term);
printf("请输入班级:");
scanf("%s", grade);
printf("%d学期%s班的学生名单为:\n", term ,grade);
STU *p = head;
while(p)
{
if(p->term == term && strcmp(p->grade, grade)==0)
printf("%s\n", p->name);
p = p->next;
}
}
// 输出学生的成绩单
void output(void)
{
int term;
char grade[20];
printf("请输入学期:");
scanf("%d", &term);
printf("请输入班级:");
scanf("%s", grade);
printf("%d学期%s班的学生成绩单为:\n", term, grade);
printf("学号\t\t姓名\t语文\t数学\t英语\t总分\n");
STU *p = head;
while(p)
{
if(p->term == term && strcmp(p->grade, grade)==0)
{
printf("%s\t%s\t%.2f\t%.2f\t%.2f\t%.2f\n", p->num, p->name, p->object[1], p->object[2], p->object[3], p->object[0]);
}
p = p->next;
}
}
void menu(void)
{
printf("****************************************************\n\n");
printf("\t\t1.录入学生成绩\n");
printf("\t\t2.修改学生成绩\n");
printf("\t\t3.统计学生成绩\n");
printf("\t\t4.查询学生成绩\n");
printf("\t\t5.查询学生名单\n");
printf("\t\t6.输出学生的成绩单\n");
printf("\t\t7.退出系统\n");
printf("\n****************************************************\n");
printf("请输入序号选择你要的操作:");
}
int main()
{
int select;
int flag = 1;
while(flag)
{
menu();
scanf("%d", &select);
switch(select)
{
case 1: input(); break; // 录入学生成绩
case 2: revise(); break; // 修改学生成绩
case 3: tongji(); break; // 统计学生成绩
case 4: find_stu(); break; // 查询学生成绩
case 5: find_list(); break; // 查询学生名单
case 6: output(); break; // 输出学生的成绩单
case 7: flag = 0; break; //退出系统
default: printf("你的输入有误,请重新输入\n"); break;
}
tail = NULL;
fflush(stdin);
printf("\n按回车继续\n");
getchar();
}
return 0;
}