项目需求分析
一、 非功能性需求
- 用c语言进行编写
- 操作界面和操作方式简单
- 故障处理:如果因电脑稳定性和用户操作出现故障,需要进行相关的提示,并且保护数据的完整。
- 错误操作提示:出,格式错误,不存在等情况进行相关提示
二、 功能性需求 - 系统启动后,弹出一个用户界面,能实现人机交互的功能。而且只能通过界面菜单命令实现各种功能(包括系统退出功能),可以设计欢迎词。
- 录入信息包括班级、姓名、学号、五门课程成绩。
- 平均成绩:计算每门课程的平均成绩和学生五门课程的平均成绩并存档计算。
下面的功能性需求需要完成上面三个功能后才能实现
- 成绩输出:输出学生的信息和对应的原始成绩以及平均成绩。
- 成绩排序(按平均成绩):出排序后的学生信息以及对应的课程成绩和平均成绩
- 成绩查找:两种查找方式分别是,按学号查找和按姓名查找
- 成绩修改:如果学生的成绩录入错误,可以对学生的成绩进行修改,并且修改之后从新求平均值成绩和重新排序。
- 成绩追加:增补遗漏的学生以及对应的信息和对应的课程成绩,并计算出平均成绩,增补以后重新排序,并输出新增学生信息和对应课程成绩和平均成绩。
附加内容 - 成绩删除:如果录入一个不存在学的学生的信息,可以指定学生的信息进行删除。(按学生姓名或者名字删除)
- 成绩分段:对学生按不同成次分段
- 单科排名:对5门课成绩进行单科排名(并且可以查询某单科成绩的排名,并对单科成绩进行分段)
- 文件存储:把学生信息和对应的课程成绩和平均成绩存入到文件中。
- 文件输出:输出文件中的内容。
- 文件导入:从文件中导入数据到成绩管理系统中,然后进行管理
主文件main.c #include#include #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("* * ************* 学号541713460306n"); printf(" * ** * ——————————————————n"); printf(" * ** *n"); printf(" * *************n"); printf("** ********************* *n"); printf(" * *nnn"); 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.2fn5门课总平均成绩为:%6.2fn" ,*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 退出请输入:2n————————————————————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#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 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 #includetypedef 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 #includetypedef 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 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.2fn", 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;iaverage=(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;isort[j].average)
{
m=j;
}
}
temp=sort[i];
sort[i]=sort[m];
sort[m]=temp;
}
//选择输出方式
int chose1;
printf("n———————————————————————————————————");
printf("n选择按平均值从大到小输出请输入:1 选择从小到大输出请输入:2n");
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.2fn",
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
单科排名 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;jnext;
}
}
////按从小到大排序
for(i=0;i<5;i++)
{
for(j=0;jsort_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 选择从小到大输出请输入:2n");
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.2fn",
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
未完待续请参见结构体链表学生管理系统_2
https://www.imooc.com/article/22418
仅供参考,不足的地方还望原谅!!!
**by:郑轻大学生** 


