C语言——学生成绩管理系统实现
学生成绩管理系统主要实现功能*
创建顺序表保存学生成绩信息;
录入学生成绩信息;
查看成绩表已录入学生数;
查看已录入成绩学生信息;
按学号、姓名查找学生成绩信息;
按学号、姓名修改学生成绩信息;
按学号、姓名删除学生成绩信息;
输入密码清除、销毁成绩表(管理员选项)。
效果图展示:![在这里插入图片描述](https://img-blog.csdnimg.cn/9f69a44568bb4e16bcbffaee11400e2d.png)
实现对学生成绩表的增、删、改、查;
一、结构体和全局变量定义
typedef struct stu 9 { 10 char xuehao[20]; 11 char name[20]; 12 int score; 13 }stu; 14 15 typedef stu data_t; 16 17 typedef struct list 18 { 19 data_t data[SIZE]; 20 int last; 21 }seqlist;
本程序定义了两个结构体。第一个结构体保存了学生的学号、姓名、成绩信息;第二个结构体则定义类型为结构体类型的结构体数组保存学生信息
二、动态开辟空间函数
//初始化 24 seqlist *createSeqlist() 25 { 26 //动态开辟空间 27 seqlist *seq = (seqlist *)malloc(sizeof(seqlist)); 28 if(NULL == seq) 29 { 30 perror("malloc"); 31 return NULL; 32 } 33 //对顺序表清零;也可使用bzero; 34 memset(seq->data,0,sizeof(data_t)*SIZE); 35 seq->last = -1;//下标位置初始化为-1; 36 37 return seq; 38 }
利用malloc函数动态开辟空间,可使用memset或bzero函数对成绩表清零,本次选用memset函数。
三、成绩录入函数
//插入 59 int insert(seqlist *seq) 60 { 61 //1.判满 62 if(seqlistFull(seq)) 63 return -1; 64 65 char xuehao[20] = {0}; 66 char name[20] = {0}; 67 int score = 0; 68 69 printf("学号:"); 70 scanf("%s",xuehao); 71 printf("姓名:"); 72 scanf("%s",name); 73 printf("成绩:"); 74 scanf("%d",&score); 75 seq->last++; 76 strcpy(seq->data[seq->last].xuehao,xuehao); 77 strcpy(seq->data[seq->last].name,name); 78 seq->data[seq->last].score = score; 79 80 return 0; 81 82 }
先利用判满函数,进行判断成绩表是否已存满,存满则无法继续录入成绩;
成绩表SIZE宏定义为100,可根据实际情况进行扩大;
学生学号及姓名最大长度为20字节;
四、按学号实现删、改、查操作
//按学号查找对应下标位置 85 int findPosByXuehao(seqlist *seq,char *xuehao) 86 { 87 //判空 88 if(seqlistEmpty(seq)) 89 return -1; 90 91 //遍历顺序表找出目标学号对应位置 92 int i = 0; 93 for(i = 0;i<seq->last;i++) 94 { 95 if(strcmp(seq->data[i].xuehao,xuehao) == 0) 96 return i; 97 return -1; 98 } 99 return 0; 100 }
//按学号删除 103 int deleteByXuehao(seqlist *seq,char *xuehao) 104 { 105 //1.判空 106 if(seqlistEmpty(seq)) 107 return -1; 108 int pos = findPosByXuehao(seq,xuehao); 109 //3.按位置删除 110 for(int i = pos ; i < seq->last; i++) 111 { 112 strcpy(seq->data[i].xuehao,seq->data[i+1].xuehao); 113 strcpy(seq->data[i].name,seq->data[i+1].name); 114 seq->data[i].score = seq->data[i+1].score; 115 } 116 seq->last--; 117 return 0; 118 }
//按学号查询 121 void findByXuehao(seqlist *seq,char *xuehao) 122 { 123 //1.判空 124 if(seqlistEmpty(seq)) 125 return ; 126 127 //2.找出学号对应位置 128 int pos = findPosByXuehao(seq,xuehao); 129 130 //3.查询 131 printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score); 132 return; 133 134 }
//按学号修改 137 int changeByXuehao(seqlist *seq,char *xuehao,int score) 138 { 139 //1.判空 140 if(seqlistEmpty(seq)) 141 return -1; 142 143 //2.找出学号对应位置 144 int pos = findPosByXuehao(seq,xuehao); 145 146 //3.修改 147 seq->data[pos].score = score; 148 printf("修改成功!\n"); 149 printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score); 150 151 return 0; 152 }
首先,还是先写一个通过学号定位位置函数,以供后续查、删、改操作函数调用,减少代码复杂度;
思路:遍历成绩表,使用字符串函数strcmp对已录入的学生学号和要进行操作的学生学号进行比对,比对成功则能定位到位置pos,无比对成功的则返回未查找到改学生学号;
定位到需要操作的学号位置后,则可通过位置对结构体数组成员进行修改,实现删、改、查等操作;
五、按姓名对学生成绩信息进行删、查、改操作
//按找出目标姓名对应下标位置 155 int findPosByName(seqlist *seq,char *name) 156 { 157 //判空 158 if(seqlistEmpty(seq)) 159 return -1; 160 161 //遍历找出姓名对应下标 162 int i = 0; 163 for(i = 0; i <seq->last ; i++) 164 { 165 if(strcmp(seq->data[i].name,name) == 0) 166 return i; 167 return -1; 168 } 169 return 0; 170 }
//按姓名查找 174 int findByName(seqlist *seq,char *name) 175 { 176 //1.判空 177 if(seqlistEmpty(seq)) 178 return -1; 179 //2.遍历查找 180 for(int i=0;i<seq->last;i++) 181 { 182 if(strcmp(seq->data[i].name,name) == 0) 183 { 184 printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[i].xuehao,seq->data[i].name,seq->data[i].score); 185 } 186 else 187 { 188 printf("没有这个学生\n"); 189 return -1; 190 } 191 } 192 return 0; 193 }
//按姓名删除 196 int deleteByName(seqlist *seq,char *name) 197 { 198 //1.按值找出位置 199 int pos = findPosByName(seq,name); 200 201 //2.按位置删除 202 for(int i = pos ; i < seq->last; i++) 203 { 204 strcpy(seq->data[i].xuehao,seq->data[i+1].xuehao); 205 strcpy(seq->data[i].name,seq->data[i+1].name); 206 seq->data[i].score = seq->data[i+1].score; 207 } 208 seq->last--; 209 printf("删除成功!\n"); 210 211 return 0; 212 }
//按姓名修改 215 int changeByName(seqlist *seq,char *name,int score) 216 { 217 //1.按值找出位置 218 if(seqlistEmpty(seq)) 219 return -1; 220 int pos = findPosByName(seq,name); 221 222 //2.按找出位置修改 223 seq->data[pos].score = score; 224 printf("修改成功!\n"); 225 printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score); 226 227 return 0; 228 }
与按学号对成绩表同理:
首先,还是先写一个通过姓名定位位置函数,以供后续查、删、改操作函数调用,减少代码复杂度;
思路:遍历成绩表,使用字符串函数strcmp对已录入的学生姓名和要进行操作的学生姓名进行比对,比对成功则能定位到位置pos,无比对成功的则返回未查找到改学生姓名;
定位到需要操作的姓名位置后,则可通过位置对结构体数组成员进行修改,实现删、改、查等操作;
六、成绩表清空与销毁
//清空 231 void clear(seqlist *seq) 232 { 233 seq->last = -1; 234 235 return; 236 } 237 238 //销毁 239 void destory(seqlist **seq) 240 { 241 free(*seq); 242 *seq = NULL; 243 244 return ; 245 }
成绩表的清空与销毁就是释放开辟出的空间;为了不随意清空销毁;在主函数添加了密码选项,密码输入正确则可以清空销毁,否则返回;
七、相关实现截图
代码运行环境:Linux 64位机;
编译成功运行后打印出功能菜单,根据选项对成绩表进行操作;
录入
按格式录入成绩后可打印录入的学生成绩信息
根据功能菜单可以依次实现打印成绩表学生数按学号、姓名修改、删除、查找成绩信息等操作;
源代码:
#include <stdlib.h>
#include <string.h>
#define SIZE 100
typedef struct stu
{
char xuehao[20];
char name[20];
int score;
}stu;
typedef stu data_t;
typedef struct list
{
data_t data[SIZE];
int last;
}seqlist;
//初始化
seqlist *createSeqlist()
{
//动态开辟空间
seqlist *seq = (seqlist *)malloc(sizeof(seqlist));
if(NULL == seq)
{
perror("malloc");
return NULL;
}
//对顺序表清零;也可使用bzero;
memset(seq->data,0,sizeof(data_t)*SIZE);
seq->last = -1;//下标位置初始化为-1;
return seq;
}
//判空:空返回1;非空返回0;
int seqlistEmpty(seqlist *seq)
{
return (seq->last == -1)?1:0;
}
//判满:满返回1;非空返回0;
int seqlistFull(seqlist *seq)
{
return (seq->last == SIZE - 1)?1:0;
}
//求表长
int length(seqlist *seq)
{
return seq->last+1;
}
//插入
int insert(seqlist *seq)
{
//1.判满
if(seqlistFull(seq))
return -1;
char xuehao[20] = {0};
char name[20] = {0};
int score = 0;
printf("学号:");
scanf("%s",xuehao);
printf("姓名:");
scanf("%s",name);
printf("成绩:");
scanf("%d",&score);
seq->last++;
strcpy(seq->data[seq->last].xuehao,xuehao);
strcpy(seq->data[seq->last].name,name);
seq->data[seq->last].score = score;
return 0;
}
//按学号查找对应下标位置
int findPosByXuehao(seqlist *seq,char *xuehao)
{
//判空
if(seqlistEmpty(seq))
return -1;
//遍历顺序表找出目标学号对应位置
int i = 0;
for(i = 0;i<seq->last;i++)
{
if(strcmp(seq->data[i].xuehao,xuehao) == 0)
return i;
return -1;
}
return 0;
}
//按学号删除
int deleteByXuehao(seqlist *seq,char *xuehao)
{
//1.判空
if(seqlistEmpty(seq))
return -1;
int pos = findPosByXuehao(seq,xuehao);
//3.按位置删除
for(int i = pos ; i < seq->last; i++)
{
strcpy(seq->data[i].xuehao,seq->data[i+1].xuehao);
strcpy(seq->data[i].name,seq->data[i+1].name);
seq->data[i].score = seq->data[i+1].score;
}
seq->last--;
return 0;
}
//按学号查询
void findByXuehao(seqlist *seq,char *xuehao)
{
//1.判空
if(seqlistEmpty(seq))
return ;
//2.找出学号对应位置
int pos = findPosByXuehao(seq,xuehao);
//3.查询
printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score);
return;
}
//按学号修改
int changeByXuehao(seqlist *seq,char *xuehao,int score)
{
//1.判空
if(seqlistEmpty(seq))
return -1;
//2.找出学号对应位置
int pos = findPosByXuehao(seq,xuehao);
//3.修改
seq->data[pos].score = score;
printf("修改成功!\n");
printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score);
return 0;
}
//按找出目标姓名对应下标位置
int findPosByName(seqlist *seq,char *name)
{
//判空
if(seqlistEmpty(seq))
return -1;
//遍历找出姓名对应下标
int i = 0;
for(i = 0; i <seq->last ; i++)
{
if(strcmp(seq->data[i].name,name) == 0)
return i;
return -1;
}
return 0;
}
//按姓名查找
int findByName(seqlist *seq,char *name)
{
//1.判空
if(seqlistEmpty(seq))
return -1;
//2.遍历查找
for(int i=0;i<seq->last;i++)
{
if(strcmp(seq->data[i].name,name) == 0)
{
printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[i].xuehao,seq->data[i].name,seq->data[i].score);
}
else
{
printf("没有这个学生\n");
return -1;
}
}
return 0;
}
//按姓名删除
int deleteByName(seqlist *seq,char *name)
{
//1.按值找出位置
int pos = findPosByName(seq,name);
//2.按位置删除
for(int i = pos ; i < seq->last; i++)
{
strcpy(seq->data[i].xuehao,seq->data[i+1].xuehao);
strcpy(seq->data[i].name,seq->data[i+1].name);
seq->data[i].score = seq->data[i+1].score;
}
seq->last--;
printf("删除成功!\n");
return 0;
}
//按姓名修改
int changeByName(seqlist *seq,char *name,int score)
{
//1.按值找出位置
if(seqlistEmpty(seq))
return -1;
int pos = findPosByName(seq,name);
//2.按找出位置修改
seq->data[pos].score = score;
printf("修改成功!\n");
printf("学号:%s 姓名:%s 成绩:%d\n",seq->data[pos].xuehao,seq->data[pos].name,seq->data[pos].score);
return 0;
}
//清空
void clear(seqlist *seq)
{
seq->last = -1;
return;
}
//销毁
void destory(seqlist **seq)
{
free(*seq);
*seq = NULL;
return ;
}
//打印
void display(seqlist *seq)
{
//1.判空
if(seqlistEmpty(seq))
return;
//2.遍历顺序表并打印
printf("学号 姓名 成绩\n");
for(int i = 0;i<=seq->last;i++)
{
printf(" %s %s %d \n",seq->data[i].xuehao,seq->data[i].name,seq->data[i].score);
}
return ;
}
int main(int argc,const char *argv[])
{
seqlist *seq = createSeqlist();
if(NULL == seq)
{
printf("Create Fail!!!");
return -1;
}
int flag = 1;
while(flag)
{
printf("*******欢迎使用学生管理系统*******\n");
printf("1:输入成绩信息\n2:打印学生成绩\n3:打印表中学生数\n4:按学号修改成绩\n5:按姓名修改学生成绩\n6:按学号查找\n7:按姓名查找\n8:按学号删除成绩\n9:按姓名删除成绩\n10:清空成绩表\n11:销毁学生成绩表\n0:退出\n");
printf("**********************************\n");
int m;
char xuehao[20];
char name[20];
char password[20];
int score;
scanf("%d",&m);
switch(m)
{
case 1:
puts("");
insert(seq);
puts("");
break;
case 2:
puts("");
display(seq);
puts("");
break;
case 3:
puts("");
printf("学生个数为: %d\n",length(seq));
puts("");
break;
case 4:
puts("");
printf("输入学号及修改后成绩:");
scanf("%s%d",xuehao,&score);
changeByXuehao(seq,xuehao,score);
puts("");
break;
case 5:
puts("");
printf("输入姓名及修改后成绩:");
scanf("%s%d",name,&score);
changeByName(seq,name,score);
puts("");
break;
case 6:
puts("");
printf("输入要查找的学号:");
scanf("%s",xuehao);
findByXuehao(seq,xuehao);
puts("");
break;
case 7:
puts("");
printf("输入要查找的姓名:");
scanf("%s",xuehao);
findByName(seq,name);
puts("");
break;
case 8:
puts("");
printf("输入要删除信息学生学号:");
scanf("%s",xuehao);
deleteByXuehao(seq,xuehao);
puts("");
break;
case 9:
puts("");
printf("输入要删除信息学生姓名:");
scanf("%s",name);
deleteByName(seq,name);
puts("");
break;
case 10:
puts("");
printf("密码:");
scanf("%s",password);
if(strcmp(password,"888888") == 0)
clear(seq);
else
printf("密码错误!");
puts("");
break;
case 11:
puts("");
printf("密码:");
scanf("%s",password);
if(strcmp(password,"888888") == 0)
destory(&seq);
else
printf("密码错误!");
puts("");
break;
case 0:
flag = 0;
break;
}
}
return 0;
}