|
|
#include<stdio.h>
|
|
|
#include<stdlib.h>
|
|
|
#include<string.h>
|
|
|
#include<malloc.h>
|
|
|
typedef struct student
|
|
|
{
|
|
|
char name[20],major[20]; //学生姓名专业
|
|
|
int id; //学生学号
|
|
|
int math,english,computer,sum; //各科成绩,总分
|
|
|
struct student *next;
|
|
|
}ST;
|
|
|
ST students[100],g_head,*hp;
|
|
|
int stu_count=2,sys_count=0;
|
|
|
void showmenu() //菜单
|
|
|
{
|
|
|
system("cls");
|
|
|
printf("\n------------------学生成绩管理系统-----------------\n");
|
|
|
printf("\n\t 1.添加学生信息\n\t 2.删除某个学生信息\n\t 3.显示某个学生信息\n");
|
|
|
printf("\t 4.修改学生信息\n\t 5.删除所有学生信息\n\t 6.显示所有学生信息\n");
|
|
|
printf("\t 7.成绩排名\n\t 8.读取文件学生信息\n\t 9.保存学生信息至文件\n");
|
|
|
printf("\t 0.退出系统\n");
|
|
|
printf("\n---------------------------------------------------\n");
|
|
|
}
|
|
|
ST* creat_list() //创建链表
|
|
|
{
|
|
|
int i=0;
|
|
|
hp=(ST *)malloc(sizeof(ST));
|
|
|
hp->next=NULL;
|
|
|
printf("************学生信息链表创建成功****************\n\n");
|
|
|
return hp;
|
|
|
}
|
|
|
int getmenu_number() //获取菜单选项
|
|
|
{
|
|
|
int num;
|
|
|
showmenu();
|
|
|
printf("\n\n 请选择功能号0~9\n");
|
|
|
printf("\n---------------------------------------------------\n");
|
|
|
while(1!=scanf("%d",&num)||num>9||num<0)
|
|
|
{
|
|
|
fflush(stdin);
|
|
|
printf(" \n 输入错误!\n 请重新输入数字0~9!\n\n");
|
|
|
showmenu();
|
|
|
printf("--------------------------------------------------\n\n");
|
|
|
}
|
|
|
return num;
|
|
|
}
|
|
|
ST* creat_student() //创建学生信息结点(从链表结尾添加)
|
|
|
{
|
|
|
ST *s;
|
|
|
s=(ST*)malloc(sizeof(ST)); //生成新的结点
|
|
|
printf("~请输入学生姓名,学号,专业,数学成绩,英语成绩,计算机成绩\n");
|
|
|
scanf("%s",s->name);
|
|
|
scanf("%d",&s->id);
|
|
|
scanf("%s",s->major);
|
|
|
scanf("%d",&s->math);
|
|
|
scanf("%d",&s->english);
|
|
|
scanf("%d",&s->computer);
|
|
|
printf("\n");
|
|
|
printf("******创建学生信息结点成功******\n\n");
|
|
|
s->next=NULL;
|
|
|
return s;
|
|
|
}
|
|
|
ST* getprevaddr(int num) //返回指定学号学生节点的上一个节点的指针
|
|
|
{
|
|
|
ST *sp1=hp;
|
|
|
while(sp1->next)
|
|
|
{
|
|
|
if(sp1->next->id==num)
|
|
|
return sp1;
|
|
|
else sp1=sp1->next;
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
int add_student() //添加学生信息 (未创建链表)
|
|
|
{
|
|
|
int t=1;
|
|
|
ST *pst,*ps;
|
|
|
while(t)
|
|
|
{
|
|
|
ps=creat_list();
|
|
|
pst=creat_student();
|
|
|
printf("开始添加学生信息\n");
|
|
|
if(!pst)
|
|
|
{
|
|
|
printf("未获取到学生信息结点\n\n");
|
|
|
return 0;
|
|
|
}
|
|
|
if(getprevaddr(pst->id))
|
|
|
{
|
|
|
printf("学号为%d的学生信息已经存在\n",pst->id);
|
|
|
free(pst);
|
|
|
return 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
while(ps->next) ps=ps->next; //使指针指向链表尾部
|
|
|
ps->next=pst;
|
|
|
}
|
|
|
pst->next=NULL;
|
|
|
printf("若要继续添加学生信息请输入 1,否则添加 0\n\n");
|
|
|
scanf("%d",&t);
|
|
|
}
|
|
|
printf(" ******添加学生信息成功!******\n");
|
|
|
system("pause");
|
|
|
return 1;
|
|
|
}
|
|
|
int getstudent_id() //获取用户输入的学生id
|
|
|
{
|
|
|
int num;
|
|
|
printf(" 请输入学生id(整数)!\n");
|
|
|
while(1!=scanf("%d",&num))
|
|
|
{
|
|
|
printf(" 输入错误,请重新输入学生id(整数)!\n");
|
|
|
fflush(stdin);
|
|
|
}
|
|
|
return num;
|
|
|
}
|
|
|
void delete_student() //根据学号删除某个学生信息
|
|
|
{
|
|
|
ST *pst,*ptemp;
|
|
|
int num;
|
|
|
printf(" 请输入待删除信息的学生的id\n\n");
|
|
|
scanf("%d",&num);
|
|
|
pst=getprevaddr(num);
|
|
|
ptemp=pst->next;
|
|
|
pst->next=ptemp->next;
|
|
|
free(ptemp);
|
|
|
printf(" 删除了学号为%d的学生的信息\n\n",num);
|
|
|
}
|
|
|
int show_student() //根据学号显示某个学生信息
|
|
|
{int num;
|
|
|
ST *pst=hp;
|
|
|
num=getstudent_id();
|
|
|
while(pst->next)
|
|
|
{printf("内循环\n");
|
|
|
if(pst->id==num)
|
|
|
{
|
|
|
printf("姓名 学号 专业 数学 英语 计算机 \n");
|
|
|
printf("%s\t%d\t%s\t%d\t%d\t%d\n",pst->name,pst->id,pst->major,pst->math,pst->english,pst->computer);
|
|
|
return 1;
|
|
|
}
|
|
|
pst=pst->next;
|
|
|
}
|
|
|
printf("显示成功\n");
|
|
|
system("pause");
|
|
|
}
|
|
|
void show_allstudent() //显示所有学生信息
|
|
|
{
|
|
|
ST *ps=&g_head;
|
|
|
printf("--------------------------------------------------------------------\n");
|
|
|
printf("学号 姓名 专业 数学 英语 计算机\n");
|
|
|
printf("--------------------------------------------------------------------\n");
|
|
|
while(ps->next)
|
|
|
{
|
|
|
printf("%d\t%s\t%s\t%d\t%d\t%d\n",ps->id,ps->name,ps->major,ps->math,ps->english,ps->computer);
|
|
|
ps=ps->next;
|
|
|
}
|
|
|
printf("--------------------------------------------------------------------\n");
|
|
|
system("pause");
|
|
|
}
|
|
|
void delete_allstudent() //删除所有学生信息
|
|
|
{ int count=0;
|
|
|
ST *pst,*ptemp;pst=hp;
|
|
|
while(pst)
|
|
|
{
|
|
|
ptemp=pst;
|
|
|
pst=pst->next;
|
|
|
free(ptemp);
|
|
|
++count;
|
|
|
}
|
|
|
printf("一共删除了%d个学生信息\n",count);
|
|
|
hp->next = NULL;
|
|
|
}
|
|
|
void print(struct student stu) //打印学生信息
|
|
|
{
|
|
|
stu.sum=stu.math+stu.english+stu.computer;
|
|
|
printf("%s\t %s\t %d\t %d\t %d\t %d\n",stu.id,stu.name,stu.math,stu.english,stu.computer,stu.sum);
|
|
|
}
|
|
|
int get_sum_student() //获取学生总人数
|
|
|
{
|
|
|
ST *pst;
|
|
|
pst=creat_list();
|
|
|
while(pst)
|
|
|
{
|
|
|
pst=pst->next;
|
|
|
++stu_count;
|
|
|
}
|
|
|
printf("学生总人数为%d\n",stu_count);
|
|
|
return stu_count;
|
|
|
}
|
|
|
void fix_information()//修改学生信息(包括对各科成绩、姓名的修改)
|
|
|
{
|
|
|
int id,i=0, math, english,computer;
|
|
|
char name_con[100];
|
|
|
printf(" 请输入要修改信息的学生的学号!\n");
|
|
|
scanf("%d",&id);
|
|
|
printf(" 请输入要修改的学生的信息(依次为数学,英语,计算机成绩,名字)\n");
|
|
|
scanf("%d%d%d%s",&math,&english,&computer,name_con);
|
|
|
while(i<stu_count)
|
|
|
{ if(students[i].id==id) {students[i].math=math;students[i].english=english;students[i].computer=computer;strcpy(students[i].name,name_con);}
|
|
|
i++;
|
|
|
}
|
|
|
printf("学生信息修改成功!\n\n");
|
|
|
}
|
|
|
void swap(int *p1,int *p2) //交换两个变量的值
|
|
|
{
|
|
|
int temp;
|
|
|
temp=*p1;
|
|
|
*p1=*p2;
|
|
|
*p2=temp;
|
|
|
}
|
|
|
void sum_sore_sort() //成绩排名
|
|
|
{int count;char b[100];
|
|
|
scanf("%d",&count);
|
|
|
/* for(int i=0;i<count;i++)
|
|
|
{
|
|
|
scanf("%d%s%d%d%d\n",&a[i].id,a[i].name,&a[i].math,&a[i].english,&a[i].computer);
|
|
|
a[i].sum=a[i].english+a[i].math+a[i].computer;
|
|
|
}
|
|
|
*/
|
|
|
for(int i=0;i<stu_count;i++)
|
|
|
{
|
|
|
char *temp;temp=b;
|
|
|
for(int j=0;j<stu_count-i-1;j++)
|
|
|
{if(students[j].sum<students[j+1].sum)
|
|
|
{
|
|
|
swap(&students[j].sum,&students[j+1].sum);
|
|
|
swap(&students[j].id,&students[j+1].id);
|
|
|
swap(&students[j].math,&students[j+1].math);
|
|
|
swap(&students[j].computer,&students[j+1].computer);
|
|
|
swap(&students[j].english,&students[j+1].english);
|
|
|
strcpy(temp,students[j].name);
|
|
|
strcpy(students[j].name,students[j+1].name);
|
|
|
strcpy(students[j+1].name,temp);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
printf("排名 学号 姓名 数学 英语 计算机 总分");
|
|
|
for(int i=0;i<stu_count;i++)
|
|
|
{ printf("%d\t",i+1);
|
|
|
print(students[i]);
|
|
|
if(i!=stu_count-1) printf("\n");
|
|
|
}
|
|
|
}
|
|
|
void update_stu() //修改学生信息
|
|
|
{
|
|
|
int math,english,computer,Count,id;
|
|
|
int i=0;
|
|
|
printf("先输入待修改的学生的学号,再输入要修改的成绩(依次是数学,英语,计算机)");
|
|
|
scanf("%d%d%d%d",&id,&math,&english,&computer);
|
|
|
Count=get_sum_student();
|
|
|
while(i<Count)
|
|
|
{ if(students[i].id==id) {students[i].math=math;students[i].english=english;students[i].computer=computer;}
|
|
|
i++;
|
|
|
}
|
|
|
}
|
|
|
void loadfromfile()
|
|
|
{
|
|
|
int i,repeat=0,count;
|
|
|
FILE *pf;
|
|
|
ST *pstu=creat_list();
|
|
|
printf("提示:从文件中读取学生信息会询问是否清空当前学生信息(不清空表示合并所有信息)\n");
|
|
|
if((pf=fopen("cke","rb"))==NULL)
|
|
|
{
|
|
|
printf("文件还没有创建,请手工输入学生信息并保存吧!\n");
|
|
|
return ;
|
|
|
}
|
|
|
delete_allstudent();
|
|
|
//删除之前的所有学生信息,然后从文件中读取
|
|
|
fread(&count, sizeof(count),1, pf);//获取学生信息的数量
|
|
|
for(i = 0; i <count; ++i)
|
|
|
{
|
|
|
pstu = (ST*)malloc(sizeof(ST));
|
|
|
fread(pstu,sizeof(ST),1, pf);
|
|
|
if(!add_student())
|
|
|
{
|
|
|
++repeat;
|
|
|
//保持有多少个和当前链表中相重复的学生信息
|
|
|
}
|
|
|
}
|
|
|
fclose(pf);
|
|
|
printf("文件读取完毕!新增学生信息%d条。\n", count-repeat);
|
|
|
}
|
|
|
void save_file() //把学生信息保存到文件当中
|
|
|
{ int count;
|
|
|
FILE *pf = fopen("cke", "wb");
|
|
|
ST *pstu = creat_list();
|
|
|
int i = 0;
|
|
|
if(!pf)
|
|
|
{
|
|
|
printf("打开待写入的文件失败!\n");
|
|
|
return;
|
|
|
}
|
|
|
fwrite(&count,sizeof(i), 1,pf);
|
|
|
//把学生信息的数量先写入到文件头
|
|
|
printf("学号 姓名 专业 数学 英语 计算机 \n");
|
|
|
while(pstu->next)
|
|
|
{ fwrite(pstu->next, sizeof(ST),1, pf);
|
|
|
//把每位学生信息写入文件
|
|
|
++i;
|
|
|
pstu = pstu->next;
|
|
|
}
|
|
|
fclose(pf);
|
|
|
if(i == count)
|
|
|
{
|
|
|
printf("成功的写入了%d条学生信息。\n", count);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
printf("应写入%d条学生信息,实际写入%d条学生信息。\n", count, i);
|
|
|
}
|
|
|
}
|
|
|
int main()
|
|
|
{
|
|
|
int running=1;
|
|
|
while(running)
|
|
|
{
|
|
|
showmenu();
|
|
|
switch(getmenu_number())
|
|
|
{
|
|
|
case 0:running=0;break;
|
|
|
case 1:add_student();break;
|
|
|
case 2:delete_student();break;
|
|
|
case 3:show_student();break;
|
|
|
case 4:update_stu();break;
|
|
|
case 5:delete_allstudent();break;
|
|
|
case 6:show_allstudent();break;
|
|
|
case 7:sum_sore_sort();break;
|
|
|
case 8:loadfromfile();break;
|
|
|
case 9:save_file();break;
|
|
|
default:printf("输入出错,请重新输入功能号0~9\n");
|
|
|
}
|
|
|
}
|
|
|
system("pause");
|
|
|
return 0;
|
|
|
} |