项目需求分析
一、 非功能性需求
- 用c语言进行编写
- 操作界面和操作方式简单
- 故障处理:如果因电脑稳定性和用户操作出现故障,需要进行相关的提示,并且保护数据的完整。
- 错误操作提示:出,格式错误,不存在等情况进行相关提示
二、 功能性需求 - 系统启动后,弹出一个用户界面,能实现人机交互的功能。而且只能通过界面菜单命令实现各种功能(包括系统退出功能),可以设计欢迎词。
- 录入信息包括班级、姓名、学号、五门课程成绩。
- 平均成绩:计算每门课程的平均成绩和学生五门课程的平均成绩并存档计算。
下面的功能性需求需要完成上面三个功能后才能实现
- 成绩输出:输出学生的信息和对应的原始成绩以及平均成绩。
- 成绩排序(按平均成绩):出排序后的学生信息以及对应的课程成绩和平均成绩
- 成绩查找:两种查找方式分别是,按学号查找和按姓名查找
- 成绩修改:如果学生的成绩录入错误,可以对学生的成绩进行修改,并且修改之后从新求平均值成绩和重新排序。
- 成绩追加:增补遗漏的学生以及对应的信息和对应的课程成绩,并计算出平均成绩,增补以后重新排序,并输出新增学生信息和对应课程成绩和平均成绩。
附加内容 - 成绩删除:如果录入一个不存在学的学生的信息,可以指定学生的信息进行删除。(按学生姓名或者名字删除)
- 成绩分段:对学生按不同成次分段
- 单科排名:对5门课成绩进行单科排名(并且可以查询某单科成绩的排名,并对单科成绩进行分段)
- 文件存储:把学生信息和对应的课程成绩和平均成绩存入到文件中。
- 文件输出:输出文件中的内容。
- 文件导入:从文件中导入数据到成绩管理系统中,然后进行管理
主文件main.c
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(stu)
//定义结构体类型
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
//15个选项相关函数
stu *information_entry(stu *head);//信息录入
double *average_score(stu *head);//平均成绩
void score_output(stu *head);//成绩输出
void score_ranking(stu *head);//成绩排名
void single_ranking(stu *head);//单科排名
void score_found(stu *head);//成绩查找
void score_change(stu *head);//成绩修改
void score_add(stu *head);//成绩追加
void score_stage(stu *head);//成绩分段
void single_stage(stu *head);//单科分段
stu *score_delete(stu *head);//成绩删除
void file_conserve(stu *head);//文件存储
void file_input();//文件输入
stu *file_import(stu *head);//文件导入
int fied_judje();//判断函数(用来判断每次选择输入的值与输入是否有误)
int n=0;//全局变量,用来记录录入的加导入的学生数量
int lang_ave;//只要增加数据之后lang_ave==0,
//只有进行第二步求平均值等于1 这样就可以保证
//在求完平均值才能进行其他的
int main()
{
stu *head=NULL;//链表头地址
double *ave;//用来接收平均成绩的成绩的返回值
while(1)
{
printf(" * *\n");
printf("*** ************* —————————————————\n");
printf(" * * * * 姓名:丁梦迪 \n");
printf(" * * * * 班级:1703 \n");
printf("* * ************* 学号541713460306 \n");
printf(" * * * * ——————————————————\n");
printf(" * * * *\n");
printf(" * *************\n");
printf("** ********************* *\n");
printf(" * *\n\n\n");
printf("*****************************欢迎进入学生信息管理系统*****************************\n");
printf("** **\n");
printf("** 1. 信息录入 2. 平均成绩 3. 成绩输出 4. 成绩排名 5. 单科排名 **\n");
printf("** **\n");
printf("** 6. 成绩查找 7. 成绩修改 8. 成绩追加 9. 成绩分段 10.单科分段 **\n");
printf("** **\n");
printf("** 11.成绩删除 12.文件存储 13.文件输入 14.文件导入 15.我要退出 **\n");
printf("** **\n");
printf("*****************************输入以上数字执行你的操作*****************************\n");
int chose_1;
scanf("%d",&chose_1);//菜单选择
int lang=0;//用于判断选择是否正确,并且用于选择循环结束的条件
for(;lang==0;)
{
switch(chose_1)
{
case 1:
{head=information_entry(head);//录入信息
lang=1;
break;
}
case 2:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}else
{
ave=average_score(head);//求平均成绩
printf("\n5门课各科平均成绩为:%6.2f %6.2f %6.2f %6.2f %6.2f\n5门课总平均成绩为:%6.2f\n"
,*ave,*(ave+1),*(ave+2),*(ave+3),*(ave+4),*(ave+5));
}
lang=1;
break;
}
case 3:
{if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_output(head);//成绩输出
}
}
lang=1;
break;
}
case 4:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_ranking(head);//成绩排序
}
}
lang=1;
break;
}
case 5:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
single_ranking(head);//单科排序
}
}
lang=1;
break;
}
case 6:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_found(head);
}
}
lang=1;
break;
}
case 7:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_change(head);
}
}
lang=1;
break;
}
case 8:
{if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_add(head);//成绩追加
}
}
lang=1;
break;
}
case 9:
{
if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
score_stage(head);//成绩分段
}
}
lang=1;
break;
}
case 10:
{if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
single_stage(head);;//单科分段
}
}
lang=1;
break;
}
case 11:
{if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
head=score_delete(head);//成绩删除
}
}
lang=1;
break;
}
case 12:
{if(n==0)
{
printf("\n<<你还没有录入或者导入成绩~~>>\n");
}
else
{
if(lang_ave==0)
{
printf("\n<<你还没有计算平均成绩>>\n");
}else
{
file_conserve(head);//文件存储
}
}
lang=1;
break;
}
case 13:file_input();lang=1;break;//文件输入
case 14:
{head=file_import(head);//文件导入
lang=1;
break;
}
case 15:printf("\n你已正常学生管理退出系统!\n");exit(1);
default:printf("\n你的输入有错误请重新输入!\n");scanf("%d",&chose_1);
}
}
printf("\n————————————————————\n返回菜单请输入:1 退出请输入:2\n————————————————————\n");
int chose_2=fied_judje();//调用判断函数
if(chose_2==1)
{
system("CLS");
continue;
}
else
{
printf("\n<<你已正常学生管理退出系统!>>\n");
exit(1);
}
}
return 0;
}
}
数据录入 information_entry.c
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
stu *information_entry(stu *head)//成绩录入
{
printf("\n请输入学生的班级、学号、姓名、五门课成绩(数据之间一个空格,请把所有数据输入0结束)~~:\n");
stu *head1=creatlist(head);
printf("\n<<学生信息录入成功~~!>>\n");
return head1;
}
数据录入调用链表creatlist.c
#include <stdlib.h>
#define LEN sizeof(stu)
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
extern n;
stu *creatlist(stu *head)
{
stu *p1,*p2;
stu *head1;//如果有数据,把新数据添加到上一次链表的末尾
p1=p2=( stu *) malloc(LEN);
scanf("%s %d %s %lf %lf %lf %lf %lf",p1->classs,&p1->num,p1->name,&p1->score[0],
&p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
if(n==0)
{
head=NULL;
while(p1->num!=0)
{
n=n+1;
if(n==1)head=p1;
else p2->next=p1;
p2=p1;
p1=(stu *)malloc(LEN);
scanf("%s %d %s %lf %lf %lf %lf %lf",&p1->classs,&p1->num,&p1->name,&p1->score[0],
&p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
}
p2->next=NULL;
return head;
}else//已经存在导入的情况下可以继续连接在在导入链表的末端录入
{
stu *p=head;
int i;
for(i=1;i<n-1;i++)
{
p=p->next;
}
p->next=head1;
int n1=0;
while(p1->num!=0)
{
n=n+1;
n1++;
if(n1==1)p->next=p1;
else p2->next=p1;
p2=p1;
p1=(stu *)malloc(LEN);
scanf("%s %d %s %lf %lf %lf %lf %lf",&p1->classs,&p1->num,&p1->name,&p1->score[0],
&p1->score[1],&p1->score[2],&p1->score[3],&p1->score[4]);
}
p2->next=NULL;
head->average=0;
return head;
}
}
求平均值 average_score.c
#include <stdlib.h>
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
extern lang_ave;
double *average_score(stu *head)//平均成绩
{
stu *p=head;
double ave[6];
int i;
for(i=0;i<6;i++)
{
ave[i]=0;
}
int count=0;
for(;p!=NULL;)
{
count++;
ave[0]=p->score[0]+ave[0];
ave[1]=p->score[1]+ave[1];
ave[2]=p->score[2]+ave[2];
ave[3]=p->score[3]+ave[3];
ave[4]=p->score[4]+ave[4];
p=p->next;
}
ave[0]=ave[0]/count;
ave[1]=ave[1]/count;
ave[2]=ave[2]/count;
ave[3]=ave[3]/count;
ave[4]=ave[4]/count;
ave[5]=(ave[1]+ave[2]+ave[3]+ave[4]+ave[0])/5;
lang_ave=1;
return ave;
}
成绩输出 score_output.c
#include <stdlib.h>
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
extern n;
void score_output(stu *head)//成绩输出
{
stu *p=head;
int i;
for(i=0;i<n;i++)
{
p->average=(p->score[0]+p->score[1]+p->score[2]+p->score[3]+p->score[4])/5;
p=p->next;
}
printf("\n下面是学生的信息:\n");
printf("\n班级: 学号: 姓名: 五门成绩: 平均成绩:\n");
p=head;
for(;p!=NULL;)
{
printf("%s %d %s %6.2f %6.2f %6.2f %6.2f %6.2f\n",
p->classs,p->num,p->name,p->score[0],p->score[1],p->score[2],p->score[3],p->score[4],p->average);
p=p->next;
}
}
成绩排名 score_ranking.c
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
extern n;
void score_ranking(stu *head)//成绩排名(按平均成绩)
{
stu *p=head;
stu sort[n];//排序临时数组
stu temp;//排序交换
int i,j,m;
//求平均值并且把所有学生数据复制到数组
for(i=0;i<n;i++)
{
p->average=(p->score[0]+p->score[1]+p->score[2]+p->score[3]+p->score[4])/5;
sort[i]=*p;
p=p->next;
}
//按从小到大
for(i=0;i<n-1;i++)
{
m=i;
for(j=i+1;j<n;j++)
{
if(sort[m].average>sort[j].average)
{
m=j;
}
}
temp=sort[i];
sort[i]=sort[m];
sort[m]=temp;
}
//选择输出方式
int chose1;
printf("\n———————————————————————————————————");
printf("\n选择按平均值从大到小输出请输入:1 选择从小到大输出请输入:2\n");
printf("———————————————————————————————————\n");
chose1=fied_judje();
printf("\n下面是学生的信息:\n");
printf("\n班级: 学号: 姓名: 五门成绩: 平均成绩:\n");
if(chose1==1)
{
for(i=n-1;i>=0;i--)
{
printf("%s %d %s %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n",
sort[i].classs,sort[i].num,sort[i].name,sort[i].score[0],sort[i].score[1],sort[i].score[2],
sort[i].score[3],sort[i].score[4],sort[i].average);
}
}else
{
for(i=0;i<n;i++)
{
printf("%s %d %s %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n",
sort[i].classs,sort[i].num,sort[i].name,sort[i].score[0],sort[i].score[1],sort[i].score[2],
sort[i].score[3],sort[i].score[4],sort[i].average);
}
}
}
单科排名 single_ranking.c
typedef struct Student
{
char classs[20];//班级
int num;//学号
char name[20];//名字
double score[5];//五科成绩
double average;//平均成绩
struct Student *next;//下一个地址
}stu;
extern n;
void single_ranking(stu *head)//单科排名
{
stu *p;
stu sort_single[5][n];//排序临时数组
stu temp;//排序交换
//把链表复制到5个数组
int i,j,k,m;
for(i=0;i<5;i++)
{
p=head;
for(j=0;j<n;j++)
{
sort_single[i][j]=*p;
p=p->next;
}
}
////按从小到大排序
for(i=0;i<5;i++)
{
for(j=0;j<n-1;j++)
{
m=j;
for(k=j+1;k<n;k++)
{
if(sort_single[i][m].score[i]>sort_single[i][k].score[i])
m=k;
}
temp=sort_single[i][m];
sort_single[i][m]=sort_single[i][j];
sort_single[i][j]=temp;
}
}
for(;;)
{
int chose_1,chose_2;
printf("\n请输入按第几科排名:");
for(;;)
{
scanf("%d",&chose_1);
if(chose_1<=5&&chose_1>=1)
{
break;
}
else
{
printf("\n<<你的输入有错误请重新输入!>>\n");
}
}
printf("\n————————————————————————————————————");
printf("\n选择按单科从大到小输出请输入:1 选择从小到大输出请输入:2\n");
printf("—————————————————————————————————————\n");
chose_2=fied_judje();
printf("\n下面是学生的信息:\n");
printf("班级: 学号: 姓名: 第%d科成绩: \n",chose_1);
//排序输出
if(chose_2==1)//从大到小
{
for(i=n-1;i>=0;i--)
{
printf("%s %d %s %6.2f\n",
sort_single[chose_1][i].classs,
sort_single[chose_1][i].num,
sort_single[chose_1][i].name,
sort_single[chose_1][i].score[chose_1]);
}
}else//从小到大
{
for(i=0;i<n;i++)
{
printf("%s %d %s %6.2f\n",
sort_single[chose_1][i].classs,
sort_single[chose_1][i].num,
sort_single[chose_1][i].name,
sort_single[chose_1][i].score[chose_1]);
}
}
int chose_3;
printf("\n——————————————————————————");
printf("\n继续选择请输入1: 退出单科排序请输入:2\n");
printf("——————————————————————————\n");
chose_3=fied_judje();
if(chose_3==1) continue;
else break;
}
}
未完待续请参见结构体链表学生管理系统_2
https://www.imooc.com/article/22418
仅供参考,不足的地方还望原谅!!!
**by:郑轻大学生**