需求概述
编写一个可以对学生的成绩信息进行管理的系统,通过该系统可以实现对学生成绩的显示,排序,增删改查,保存载入并且统计出各科最高分和不及格人数
展示
总体设计
功能划分
密码登录模块 班级创建模块 学生信息录入模块 学生信息显示模块 学生信息查询模块 学生信息排序模块 学生信息统计模块 学生信息删除模块 学生信息新增模块 学生信息修改模块 学生信息保存模块 学生信息载入模块 系统退出模块
学生结构体链表 包含学生的学号,姓名,成绩,总分,平均分,排名
程序流程
详细设计
头文件部分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
结构体
#define N 30//最大容量
#define M 3//功课门数
typedef struct info
{
int sid;//学号
char name[20];//姓名
int score[M];//M门功课的成绩
double total;//总分
double aver;//平均分
int order;
}INFO;
typedef struct stu
{
INFO data;//数据域
struct stu *next;//指针域
}STU;
密码登录模块
int command,i,flag=0;//command为操作指令,i计数器,flag判断密码是否正确
char c, Password[6];
STU *h;
printf('请输入密码(3次机会)\n');
for(i=0;i<3;i++)
{
int x=0;
while(x<5&&c!=13)//13是回车符的ASCII码
{
c=getch();
Password[x++]=c;
if(c!=13)
putchar('*');//输入的密码以*的形式显示
}
Password[x]='\0';
if(strcmp(Password,'12345\0')==0)
{
flag=1;
break;//如果密码正确则跳出循环
}
else
if(i==2)
printf('\n密码错误!退出系统!');
else
printf('\n密码错误!请输入正确密码:');
}
if(flag)
{
//进入系统
}
菜单显示
void showMenu()
{
printf('\n密码正确!\n');
printf('------学生信息管理系统V2.0--------\n');
printf('* 1. 创建班级 *\n');
printf('* 2. 学生信息录入 *\n');
printf('* 3. 学生信息显示 *\n');
printf('* 4. 学生信息查询 *\n');
printf('* 5. 学生信息排序 *\n');
printf('* 6. 学生信息统计 *\n');
printf('* 7. 学生信息删除 *\n');
printf('* 8. 学生信息新增 *\n');
printf('* 9. 学生信息修改 *\n');
printf('* 10. 学生信息保存 *\n');
printf('* 11.学生信息载入 *\n');
printf('* 0. 退出系统 *\n');
printf('----------------------------------\n');
printf('* 作者:是我啊东山,学号:xxxx *\n');
printf('----------------------------------\n');
}
班级创建模块
printf('请输入需要创建的班级人数:');
scanf('%d',&count);//count为全局变量
printf('初始化班级人数为%d人\n',count);
学生信息录入模块
STU *createClass(int n)//n为要创建的个数
{
STU *p,*q,*h;//h为头指针,p指向新创建的学生,q指向最后一个学生
int i;
for(i=0;i<n;i++)
{
p=(STU *)malloc(sizeof(STU));
printf('请输入第%d个学生的学号、姓名、语数英成绩:',i+1);
scanf('%d%s%d%d%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2]);
p->data.total=p->data.score[0]+p->data.score[1]+p->data.score[2];
p->data.aver=p->data.total/M;
p->data.order=0;
p->next=NULL;
if(i==0)
h=p;//将头指针固定在链表头部
else
q->next=p;//将链表末尾和新创建的学生连接起来
q=p;//q指针指向新创建的学生即链表的末尾
}
return h;//返回头指针
}
学生信息显示模块
void showStuInfo(STU *h)//h为头指针
{
STU *p;
p=h;
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
while(p!=NULL)
{
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
p=p->next;//当前学生信息答应完后,让p指向下一个学生
}
}
学生信息查询模块
void searchStuInfo(STU *h,int n)//h为头指针,n为学号
{
STU *p;
p=h;
int flag=0;
while(p!=NULL)
{
if(p->data.sid==n)//学号匹配则输出
{
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
flag=1;
break;
}
else//学号不匹配则指向下一个学生
p=p->next;
}
if(flag)//输出查询结果
printf('查询完毕!\n');
else
printf('查无此人!\n');
}
学生信息排序模块
void sortStuInfo(STU *h)//h为头指针
{
int x,i=1;
INFO t;
STU *p,*r,*s;
p=h;//指向第一个节点
r=p->next;//指向第二个节点
s=r->next;//指向第三个节点
printf('总分排序输入0\n语文排序输入1\n数学排序输入2\n英语排序输入3\n');
printf('请输入:');
scanf('%d',&x);
if(x)
{
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.score[x-1]<r->data.score[x-1])//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
}
else
{
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.total<r->data.total)//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
}
p=h;
while(p!=NULL)
{
p->data.order=i++;
p=p->next;
}
}
学生信息统计模块
void countStuInfo(STU *h)//h为头指针
{
STU *p,*r,*s;
INFO t;
p=h;//指向第一个节点
r=p->next;//指向第二个节点
s=r->next;//指向第三个节点
int i,c=0,m=0,y=0;
while(p!=NULL)
{
if(p->data.score[0]<60)c++;
if(p->data.score[1]<60)m++;
if(p->data.score[2]<60)y++;
p=p->next;
}
for(i=0;i<3;i++)
{
p=h;
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.score[i]<r->data.score[i])//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
p=h;
switch(i)
{
case 0:printf('语文最高:');break;
case 1:printf('数学最高:');break;
case 2:printf('英语最高:');
}
printf('%s %d分\n',p->data.name,p->data.score[i]);
}
printf('不及格人数统计:\n');
printf('语文:%d人\n数学:%d人\n英语:%d人\n',c,m,y);
}
学生信息删除模块
STU *deleteStuInfo(STU *h)//h为头指针,s为学号
{
STU *head,*p,*q;
head=h;
int s;
if(count==0)
{
printf('班级为空!\n');
return head;
}
p=h;
q=p->next;
printf('请输入要删除的学生的学号:');
scanf('%d',&s);
printf('\n');
if(p->data.sid==s)//如果是头节点,直接返回第二个
{
printf('删除成功!\n');
return q;
}
else
{
while(q!=NULL)
{
if(q->data.sid==s)
{
p->next=q->next;
printf('删除成功!\n');
return head;
}
else
{
p=p->next;
q=p->next;
}
}
printf('查无此人!\n');
return head;
}
}
学生信息新增模块
void addStuInfo(STU *h)//h为头指针
{
STU *p,*q;
p=h;
while(p!=NULL)
{
if(p->next==NULL)
{
count++;//人数加一
if(count>N)
printf('超出最大容量\n');
else
{
q=(STU *)malloc(sizeof(STU));
printf('请输入添加的学生的学号、姓名、成绩:');
scanf('%d%s%d%d%d',&q->data.sid,q->data.name,&q->data.score[0],&q->data.score[1],&q->data.score[2]);
q->data.total=q->data.score[0]+q->data.score[1]+q->data.score[2];
q->data.aver=q->data.total/M;
q->data.order=0;
q->next=p->next;
p->next=q;
printf('添加成功!\n');
break;
}
}
p=p->next;
}
}
学生信息修改模块
void changeStuInfo(STU *h, int n)//h为头指针
{
int flag=0;
STU *p;
p=h;
while(p!=NULL)
{
if(p->data.sid==n)
{
printf('请输入学生的学号、姓名、语数英成绩:');
scanf('%d%s%d%d%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2]);
p->data.total=p->data.score[0]+p->data.score[1]+p->data.score[2];
p->data.aver=p->data.total/M;
p->data.order=0;
printf('修改成功!\n');
flag=1;
break;
}
else
p=p->next;
}
if(flag==0)
printf('查无此人!\n');
}
学生信息保存模块
void saveStuInfo(STU *h)//h为头指针
{
STU *p;
FILE *fp;
p=h;
fp=fopen('data.txt','w');
if(fp==NULL)
{
printf('无法打开文件!');
exit(0);
}
else
{
fprintf(fp,'%d\n',count);//保存学生人数信息
while(p!=NULL)
{
fprintf(fp,'%d%s\n%d\n%d\n%d\n%f\n%f\n%d\n',p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver,p->data.order);//保存学生信息
p=p->next;
}
}
fclose(fp);
printf('保存成功\n');
}
学生信息载入模块
STU *loadStuInfo(STU *h)//h为头指针
{
int i;
STU *p,*q;
FILE *fp;
fp=fopen('data.txt','r');
if(fp==NULL)
{
printf('无法打开文件!');
exit(0);
}
else
{
fscanf(fp,'%d\n',&count);//读取学生人数信息
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
for(i=1;i<count;i++)
{
p=(STU *)malloc(sizeof(STU));
fscanf(fp,'%d%s%d%d%d%lf%lf%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2],&p->data.total,&p->data.aver,&p->data.order);
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
p->next=NULL;
if(i==1)
h=p;//将头指针固定在链表头部
else
q->next=p;//将链表末尾和新创建的学生连接起来
q=p;//q指针指向新创建的学生即链表的末尾
}
printf('读取成功\n');
}
fclose(fp);
return h;
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define N 30//最大容量
#define M 3//功课门数
typedef struct info
{
int sid;//学号
char name[20];//姓名
int score[M];//M门功课的成绩
double total;//总分
double aver;//平均分
int order;
}INFO;
typedef struct stu
{
INFO data;//数据域
struct stu *next;//指针域
}STU;
int count=0,n;
void showMenu();//显示菜单
STU *createClass(int n);//学生信息录入模块
void showStuInfo(STU *h);//学生信息显示模块
void searchStuInfo(STU *h,int n);//学生信息查询模块
void sortStuInfo(STU *h);//学生信息排序模块
void countStuInfo(STU *h);//学生信息统计模块
STU *deleteStuInfo(STU *h);//学生信息删除模块
void addStuInfo(STU *h);//学生信息新增模块
void changeStuInfo(STU *h, int n);//学生信息修改模块
void saveStuInfo(STU *h);//学生信息保存模块
STU *loadStuInfo(STU *h);//学生信息载入模块
int main()
{
int command,i,flag=0;//command为操作指令,i计数器,flag判断密码是否正确
char c, Password[6];
STU *h;
printf('请输入密码(3次机会)\n');
for(i=0;i<3;i++)
{
int x=0;
while(x<5&&c!=13)//13是回车符的ASCII码
{
c=getch();
Password[x++]=c;
if(c!=13)
putchar('*');//输入的密码以*的形式显示
}
Password[x]='\0';
if(strcmp(Password,'12345\0')==0)
{
flag=1;
break;//如果密码正确则跳出循环
}
else
if(i==2)
printf('\n密码错误!退出系统!');
else
printf('\n密码错误!请输入正确密码:');
}
if(flag)
{
showMenu();
printf('请选择:');
scanf('%d',&command);
printf('\n');
while(1)//根据command的值执行不同的值
{
switch(command){
case 1:{
printf('请输入需要创建的班级人数:');
scanf('%d',&count);
printf('初始化班级人数为%d人\n',count);
};break;
case 2:{
h=createClass(count);
printf('学生信息录入成功!\n');
};break;
case 3:{
showStuInfo(h);
printf('学生信息显示成功!\n');
};break;
case 4:{
printf('请输入学生的学号:');
scanf('%d',&n);
searchStuInfo(h,n);
};break;
case 5:{
sortStuInfo(h);
printf('排序成功!\n');
};break;
case 6:countStuInfo(h);break;
case 7:h=deleteStuInfo(h);break;
case 8:addStuInfo(h);;break;
case 9:{
printf('请输入要修改的学生的学号:');
scanf('%d',&n);
changeStuInfo(h,n);
};break;
case 10:saveStuInfo(h);break;
case 11:h=loadStuInfo(h);break;
case 0:exit(0);//退出系统
}
printf('按任意健继续');
getch();//让程序暂停一下,按任意键继续
system('cls');//清除屏幕
showMenu();
printf('请选择:');
scanf('%d',&command);
}
}
return 0;
}
void showMenu()
{
printf('\n密码正确!\n');
printf('------学生信息管理系统V2.0--------\n');
printf('* 1. 创建班级 *\n');
printf('* 2. 学生信息录入 *\n');
printf('* 3. 学生信息显示 *\n');
printf('* 4. 学生信息查询 *\n');
printf('* 5. 学生信息排序 *\n');
printf('* 6. 学生信息统计 *\n');
printf('* 7. 学生信息删除 *\n');
printf('* 8. 学生信息新增 *\n');
printf('* 9. 学生信息修改 *\n');
printf('* 10. 学生信息保存 *\n');
printf('* 11.学生信息载入 *\n');
printf('* 0. 退出系统 *\n');
printf('----------------------------------\n');
printf('* 作者:顾凡,学号:092620209 *\n');
printf('----------------------------------\n');
}
STU *createClass(int n)//n为要创建的个数
{
STU *p,*q,*h;//h为头指针,p指向新创建的学生,q指向最后一个学生
int i;
for(i=0;i<n;i++)
{
p=(STU *)malloc(sizeof(STU));
printf('请输入第%d个学生的学号、姓名、语数英成绩:',i+1);
scanf('%d%s%d%d%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2]);
p->data.total=p->data.score[0]+p->data.score[1]+p->data.score[2];
p->data.aver=p->data.total/M;
p->data.order=0;
p->next=NULL;
if(i==0)
h=p;//将头指针固定在链表头部
else
q->next=p;//将链表末尾和新创建的学生连接起来
q=p;//q指针指向新创建的学生即链表的末尾
}
return h;//返回头指针
}
void showStuInfo(STU *h)//h为头指针
{
STU *p;
p=h;
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
while(p!=NULL)
{
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
p=p->next;//当前学生信息答应完后,让p指向下一个学生
}
}
void searchStuInfo(STU *h,int n)//h为头指针,n为学号
{
STU *p;
p=h;
int flag=0;
while(p!=NULL)
{
if(p->data.sid==n)//学号匹配则输出
{
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
flag=1;
break;
}
else//学号不匹配则指向下一个学生
p=p->next;
}
if(flag)//输出查询结果
printf('查询完毕!\n');
else
printf('查无此人!\n');
}
void countStuInfo(STU *h)//h为头指针
{
STU *p,*r,*s;
INFO t;
p=h;//指向第一个节点
r=p->next;//指向第二个节点
s=r->next;//指向第三个节点
int i,c=0,m=0,y=0;
while(p!=NULL)
{
if(p->data.score[0]<60)c++;
if(p->data.score[1]<60)m++;
if(p->data.score[2]<60)y++;
p=p->next;
}
for(i=0;i<3;i++)
{
p=h;
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.score[i]<r->data.score[i])//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
p=h;
switch(i)
{
case 0:printf('语文最高:');break;
case 1:printf('数学最高:');break;
case 2:printf('英语最高:');
}
printf('%s %d分\n',p->data.name,p->data.score[i]);
}
printf('不及格人数统计:\n');
printf('语文:%d人\n数学:%d人\n英语:%d人\n',c,m,y);
}
void sortStuInfo(STU *h)//h为头指针
{
int x,i=1;
INFO t;
STU *p,*r,*s;
p=h;//指向第一个节点
r=p->next;//指向第二个节点
s=r->next;//指向第三个节点
printf('总分排序输入0\n语文排序输入1\n数学排序输入2\n英语排序输入3\n');
printf('请输入:');
scanf('%d',&x);
if(x)
{
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.score[x-1]<r->data.score[x-1])//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
}
else
{
while(p!=NULL)
{
while(r!=NULL)
{
if(p->data.total<r->data.total)//如果前一个小于后一个则交换
{
t=p->data;
p->data=r->data;
r->data=t;
}
else
r=r->next;
}
p=p->next;
r=s;
}
}
p=h;
while(p!=NULL)
{
p->data.order=i++;
p=p->next;
}
}
STU *deleteStuInfo(STU *h)//h为头指针,s为学号
{
STU *head,*p,*q;
head=h;
int s;
if(count==0)
{
printf('班级为空!\n');
return head;
}
p=h;
q=p->next;
printf('请输入要删除的学生的学号:');
scanf('%d',&s);
printf('\n');
if(p->data.sid==s)//如果是头节点,直接返回第二个
{
printf('删除成功!\n');
return q;
}
else
{
while(q!=NULL)
{
if(q->data.sid==s)
{
p->next=q->next;
printf('删除成功!\n');
return head;
}
else
{
p=p->next;
q=p->next;
}
}
printf('查无此人!\n');
return head;
}
}
void addStuInfo(STU *h)//h为头指针
{
STU *p,*q;
p=h;
while(p!=NULL)
{
if(p->next==NULL)
{
count++;//人数加一
if(count>N)
printf('超出最大容量\n');
else
{
q=(STU *)malloc(sizeof(STU));
printf('请输入添加的学生的学号、姓名、成绩:');
scanf('%d%s%d%d%d',&q->data.sid,q->data.name,&q->data.score[0],&q->data.score[1],&q->data.score[2]);
q->data.total=q->data.score[0]+q->data.score[1]+q->data.score[2];
q->data.aver=q->data.total/M;
q->data.order=0;
q->next=p->next;
p->next=q;
printf('添加成功!\n');
break;
}
}
p=p->next;
}
}
void changeStuInfo(STU *h, int n)//h为头指针
{
int flag=0;
STU *p;
p=h;
while(p!=NULL)
{
if(p->data.sid==n)
{
printf('请输入学生的学号、姓名、语数英成绩:');
scanf('%d%s%d%d%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2]);
p->data.total=p->data.score[0]+p->data.score[1]+p->data.score[2];
p->data.aver=p->data.total/M;
p->data.order=0;
printf('修改成功!\n');
flag=1;
break;
}
else
p=p->next;
}
if(flag==0)
printf('查无此人!\n');
}
void saveStuInfo(STU *h)//h为头指针
{
STU *p;
FILE *fp;
p=h;
fp=fopen('data.txt','w');
if(fp==NULL)
{
printf('无法打开文件!');
exit(0);
}
else
{
fprintf(fp,'%d\n',count);//保存学生人数信息
while(p!=NULL)
{
fprintf(fp,'%d%s\n%d\n%d\n%d\n%f\n%f\n%d\n',p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver,p->data.order);//保存学生信息
p=p->next;
}
}
fclose(fp);
printf('保存成功\n');
}
STU *loadStuInfo(STU *h)//h为头指针
{
int i;
STU *p,*q;
FILE *fp;
fp=fopen('data.txt','r');
if(fp==NULL)
{
printf('无法打开文件!');
exit(0);
}
else
{
fscanf(fp,'%d\n',&count);//读取学生人数信息
printf('|排名 |学号 |姓名 |语文 |数学 |英语 |总分 |平均分|\n');
for(i=1;i<count;i++)
{
p=(STU *)malloc(sizeof(STU));
fscanf(fp,'%d%s%d%d%d%lf%lf%d',&p->data.sid,p->data.name,&p->data.score[0],&p->data.score[1],&p->data.score[2],&p->data.total,&p->data.aver,&p->data.order);
printf('|%-6d|%-6d|%-6s|%-6d|%-6d|%-6d|%-6.0f|%-6.2f|\n',p->data.order,p->data.sid,p->data.name,p->data.score[0],p->data.score[1],p->data.score[2],p->data.total,p->data.aver);
p->next=NULL;
if(i==1)
h=p;//将头指针固定在链表头部
else
q->next=p;//将链表末尾和新创建的学生连接起来
q=p;//q指针指向新创建的学生即链表的末尾
}
printf('读取成功\n');
}
fclose(fp);
return h;
}
|