C语言学生成绩管理系统
前言
为了加深我对C语言的学习,特在此记录我的C语言作业,新手写得不够好请大家见谅。
一、功能解析
该学生成绩管理系统包括七个功能,分别是添加学生信息、删除学生信息、修改学生信息、查询学生信息、插入学生信息、排序学生信息和打印所有学生信息。由于我还没有学习到链表,因此本代码还没有保存功能。
二、模块代码
1.结构体定义以及函数调用
代码如下:
#include <stdio.h>
int menu(void);
enum TAG{QUIT,ADD,DEL,CHA,FIND,INSERT,RANK,PRI};
struct STU{
char name[20];
int id;
float score;
};
struct STU stu[50];
int count = 0;//统计系统中学生个数
void add(void);
void delete(void);
void change(void);
void find(void);
void insert(void);
void rank(void);
void print(void);
int is_exist(int num);
int main()
{
while(1)
{
switch(menu())
{
case ADD:add();break;
case DEL:delete();break;
case CHA:change();break;
case FIND:find();break;
case INSERT:insert();break;
case RANK:rank();break;
case PRI:print();break;
case QUIT: return 0;
}
}
return 0;
}
2.菜单界面
代码如下:
int menu(void)
{
printf("******学生管理系统******\n");
printf("******1. 添加学生信息***\n");
printf("******2. 删除学生信息***\n");
printf("******3. 修改学生信息***\n");
printf("******4. 查询学生信息***\n");
printf("******5. 插入学生信息***\n");
printf("******6. 学生信息排序***\n");
printf("******7. 打印所有信息***\n");
printf("******0. 退出系统******\n");
printf("请输入要执行的操作\n");
int n;
scanf("%d",&n);
return n;
}
3.学生信息添加模块
在该模块中,判断要加的学生是否存在,由于成绩会相同,名字也可能会重复但学号不会重复,因此选择学号为输入标准。学号存在则退出系统,学号不存在则开始添加。代码如下:
void add(void)
{
int num,i;
printf("请输入要添加的学号\n");
scanf("%d",&num);
for(i=0;i<count;i++){
if(stu[i].id == num){
printf("该学号已存在\n");
return;
}
}
stu[count].id = num;
printf("请输入添加的学生姓名\n");
scanf("%s",stu[count].name);
printf("请输入添加学生的成绩\n");
scanf("%f",&stu[count].score);
count++;
}
4.学生信息删除模块
在该模块中,同样要判断即将删除的学生是否存在,若存在,则采用结构体覆盖的方法,将要删除的前一个结构体信息覆盖,即stu[i]=stu[i+1];写完后发觉可以用字符型变量y/n进行进一步确定是否删除,后续会补上。
void delete(void)
{
int num1,i,j;
printf("请输入要删除的学号\n");
scanf("%d",&num1);
for(i=0;i<count;i++)
if(stu[i].id == num1)
break;
for(j=i;j<count;j++)
{
stu[j]=stu[j+1];
}
count--;
if(stu[i].id != num1)
printf("找不到对象!!!\n");
}
5.学生信息修改模块
在该模块中,按照学号查看该学号是否存在,如果存在,修改信息, 再次提示是否继续修改如果不存在,提示是否再次修改。代码如下:
该代码中用到了字符判断,涉及到了缓冲区的问题,因此使用getchar清空缓冲区,这样才能得到要输入的信息。
void change(void)
{
int num,s;
input:
printf("请输入要修改的学号\n");
scanf("%d",&num);
s = is_exist(num);
if(s == -1){
printf("该学生信息不存在\n");
goto loop;
}
printf("请输入要修改姓名和成绩\n");
scanf("%s%f",stu[s].name,&stu[s].score);
loop:
printf("是否继续修改信息? y or n\n");
getchar();
if(getchar() == 'y')
goto input;
}
6.学生信息查找模块
在该模块中,我定义了三种查找方式,分别是按照学号、姓名和成绩,当姓名和成绩相同时,则打印出所有符合条件的学生信息。代码如下:
void find(void)
{
int i,tp,num1;
char a[10];
float b;
printf("请输入要查找的方式\n");
printf("1:按学号查找\t2:按姓名查找\t3:按成绩查找\n");
scanf("%d",&tp);
switch(tp)
{
case 1:
printf("请输入该学生学号\n");
scanf("%d",&num1);
for(i=0;i<count;i++)
{
if(stu[i].id==num1)
{
printf("该学生的信息如下:\n");
printf("学号为:%d\t\n",stu[i].id);
printf("姓名为:%s\t\n",stu[i].name);
printf("成绩为:%.1f\t\n",stu[i].score);
}
else printf("找不到对象!!!\n");
}
break;
case 2:
printf("请输入该学生姓名\n");
scanf("%s",a);
for(i=0;i<count;i++)
{
if(strcmp(stu[i].name,a)==0)
{
printf("该学生的信息如下:\n");
printf("学号为:%d\t\n",stu[i].id);
printf("姓名为:%s\t\n",stu[i].name);
printf("成绩为:%.1f\t\n",stu[i].score);
}
else printf("找不到对象!!!\n");
}
break;
case 3:
printf("请输入该科目成绩\n");
scanf("%f",&b);
for(i=0;i<count;i++)
{
if(stu[i].score==b)
{
printf("该成绩的学生信息如下:\n");
printf("学号为:%d\t\n",stu[i].id);
printf("姓名为:%s\t\n",stu[i].name);
printf("成绩为:%.1f\t\n",stu[i].score);
}
else printf("找不到对象!!!\n");
}
break;
}
}
7.学生信息插入模块
开始的我对插入功能的理解为:先添加后排序,这是上了个厕所后突然想到的,于是开始将添加函数和排序函数放在了一起。但今天老师讲了该部分代码后我发现我的想法完全不对。
该部分的代码是,找到对应位置,放置在对应位置前或者对应位置后,以此完成插入功能。同样判断要插入的学号是否存在,使用goto完成循环操作。代码如下:
void insert(void)
{
int sys_num,sys_location,new,ret,i,flag=1;// flag==1 input flag==2 input_num
input:
printf("选择要插入的位置\n");
scanf("%d",&sys_num);
sys_location = is_exist(sys_num);
if(sys_location == -1){
printf("要插入的位置不存在\n");
flag = 1;
goto loop;
}
input_num:
printf("请输入新添加的学号\n");
scanf("%d",&new);
ret = is_exist(new);
if(ret != -1){
printf("您要插入的学号已存在\n");
flag = 2;
goto loop;
}
for(i=count-1;i>sys_location;i--)
stu[i+1] = stu[i];
printf("请输入插入方式 y--前插 n--后插\n");
getchar();
if(getchar() == 'y')
{
stu[i+1] = stu[i];
i--;
}
stu[i+1].id = new;
printf("请输入新加的姓名和成绩\n");
scanf("%s%f",stu[i+1].name,&stu[i+1].score);
count++;
flag = 1;
loop:
printf("是否继续插入信息 y or n\n");
getchar();
if(getchar() == 'y'){
if(flag ==1)
goto input;
else
goto input_num;
}
}
8.学生信息排序模块
在该模块中,顺序有两种,分别是升序和降序,同时我也使用了两种排序方式:分别为冒泡排序和选择排序。
void rank(void)
{
printf("按成绩排序 1--升序 2--降序\n");
int x,i,j;
struct STU tmp;
scanf("%d",&x);
if(x==1){
for(i=0;i<count-1;i++)
for(j=0;j<count-1-i;j++)
if(stu[j].score > stu[j+1].score)
{
tmp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = tmp;
}
}
else if(x==2) //降序 选择排序
{
for(i=0;i<count-1;i++)
for(j=i+1;j<count;j++)
{
if(stu[i].score < stu[j].score)
{
tmp = stu[i];
stu[i] = stu[j];
stu[j] = tmp;
}
}
}
}
9.确认信息是否存在与打印所有信息
由于多个功能都需要判断信息是否已存在,因此为了方便定义了一个函数来完成该操作。同样是根据学号操作,查找中如果找到该学生学号,直接返回该学生所对应的信息。如果查找失败则返回-1,如此的目的是i可能会取值为0,为了不与其冲突。
int is_exist(int num)
{
for(int i=0;i<count;i++)
{
if(stu[i].id == num)
return i;
}
return -1;
}
void print(void)
{
printf("当前系统中有%d名学生信息\n",count);
printf("学号\t姓名\t成绩\n");
for(int i=0;i<count;i++)
printf("%d\t%s\t%.1f\n",stu[i].id,stu[i].name,stu[i].score);
}
总结
这是我C语言第一次比较大的作业。开始老师给了我们一个框架,上午的时候面对着这个框架我也不知道如何下手,我甚至觉得自己不可能完成。而下午的时候在博客里翻阅了很多大佬的代码,也和同学进行了沟通,发现真正操作起来也并没有想象的那么困难。完成花了大概一个下午,非常有成就感,代码可能有很多处不足,新人第一次发帖,望各位大佬多多包涵。