学生成绩管理系统是一个学校不可缺少的重要部分,它的内容对于学校的决策者和管理者来说都至关重要,所以学生成绩管理系统应该为用户提供充足的信息和快捷的查询手段。同时,学生成绩管理是各大学的主要日常管理工作之一,涉及到校、系、师、生的诸多方面,随着教学体制的不断改革,尤其是学分制、选课制的展开和深入,学生成绩日常管理工作及保存管理日趋繁重、复杂。高校都迫切需要研制开发一款属于自己的功能强大,操作简单,具有人性化的学生成绩管理系统。
设计一个利用文件处理方式,实现对学生学籍信息(包括:学号,姓名,性别,年龄,籍贯,系别,专业,班级)进行添加、修改、删除、查找、统计输出等操作。学生学籍管理系统的功能要求如下:
①增加数据
②更新数据
③查询数据
④删除数据
⑤显示数据
⑥重组文件
⑦要求本系统采用结构体等数据结构。
学生学籍管理系统包含6个模块。
(1)增加数据模块 (2)更新数据模块。
(3)查询数据模块 (4)删除数据模块。
(5)显示数据模块 (6)重组文件模块
(1)主函数:main()函数。
(2)子函数:
①增加数据函数:add_data()函数
②更新数据函数:updata_data()函数
③查询数据函数:search_data()函数
④删除数据函数:delete_data()函数
⑤显示数据函数:list_data()函数
⑥重组文件函数:pack()函数
(1)add_data()函数
函数原型:void add_data();
函数功能:输入一个或多个学生的信息,并将所输入的学生信息存入到数据文件中。
(2)updata_data()函数
函数原型:void updata_data();
函数功能:更新已存在的学生的信息。
(3)search_data()函数
函数原型:void search_data();
函数功能:按学号查询未作删除标记的学生的信息。
(4)delete_data()函数
函数原型:void delete_data();
函数功能:对某学生信息作删除标记,只作逻辑删除。
(5)list_data()函数
函数原型:void list_data();
函数功能:按指定条件显示未作删除标记的学生的信息。
(6)pack()函数
函数原型:void pack();
函数功能:对作删除标记的学生信息作物理删除。
/*全部数据定义及各子函数声明*/
#include
#include
#include
#define MAX 100
struct student
{
short status; /*数据状态,0:正常 1:删除*/
int num; /*学生的学号*/
char name[9]; /*姓名*/
char sex[3]; /*性别*/
int age; /*年龄*/
char origin[21]; /*籍贯*/
char depart[21]; /*系别*/
char major[21]; /*专业*/
int clas; /*班级*/
};
/*子函数部分*/
void add_data(); /*增加数据*/
void update_data(); /*更新数据*/
void search_data(); /*查询数据*/
void delete_data(); /*删除数据,只做删除标志*/
void list_data(); /*显示数据*/
void pack(); /*在物理上删除作有删除标记的记录*/
/*主函数*/
FILE *fp;
void main()
{
int select; /*选择变量*/
if((fp=fopen("stu.dat","rb+"))==NULL) /*stu.dat文件不存在*/
{
if((fp=fopen("stu.dat","wb+"))==NULL) /*打开stu.dat文件失败*/
{
printf("打开文件stu.dat失败!");
system("PAUSE"); /*暂时停一下,等待下一个操作*/
exit(1); /*退出程序*/
}
}
do
{
printf("\n学生学籍管理系统\n");
printf("1.增加数据 \n2.更新数据 \n3.查询数据\n4.删除数据\n5.显示数据 \n6.重组文件\n7.退出\n");
printf("\n请选择:\n");
scanf("%d",&select);
while(select<1||select>7)
{
printf("请输入1至7的数:");
scanf("%d",&select);
}
switch(select)
{
case 1:
add_data(); /*增加数据*/
break;
case 2:
update_data(); /*更新数据*/
break;
case 3:
search_data(); /*查询数据*/
break;
case 4:
delete_data(); /*删除数据,只作删除标志*/
break;
case 5:
list_data(); /*显示数据*/
break;
case 6:
pack(); /*在物理上删除作有删除标记的记录*/
break;
}
}while(select!=7); /*选择7退出循环*/
fclose(fp); /*关闭文件*/
system("PAUSE"); /*暂时停一下,等待下一个操作*/
}
/*增加数据函数*/
void add_data()
{
struct student stu; /*定义学生变量stu*/
char tag; /*设置标志是否继续添加数据*/
stu.status=0; /*数据状态,0:正常 1:删除*/
do
{
printf("学号:");
scanf("%d",&stu.num);
printf("姓名:");
scanf("%s",stu.name);
printf("性别:");
scanf("%s",stu.sex);
printf("年龄:");
scanf("%d",&stu.age);
printf("籍贯:");
scanf("%s",stu.origin);
printf("系别:");
scanf("%s",stu.depart);
printf("专业:");
scanf("%s",stu.major);
printf("班级:");
scanf("%d",&stu.clas);
fseek(fp,0,SEEK_END); /*将指针移动到文件尾部*/
/*将学生信息存入文件中*/
fwrite(&stu,sizeof(struct student),1,fp);
printf("继续添加吗(y/n):");
while (getchar()!='\n'); /*跳过当前行*/
tag=getchar();
tag=tolower(tag); /*将大写字母转化为小写字母*/
while(tag!='y'&&tag!='n')
{
printf("输入非法,从新输入(y/n):");
while(getchar()!='\n'); /*跳过当前行*/
tag=getchar();
tag=tolower(tag); /*将大写字母转化为小写字母*/
}
}while(tag=='y'); /*当回答要求循环时*/
}
/*更新数据函数*/
void update_data()
{
struct student stu; /*学生*/
int num; /*要修改的学生的学号*/
printf("输入要修改的学生的学号:");
scanf("%d",&num);
rewind(fp); /*使位置指针返回到文件的开头*/
fread(&stu,sizeof(struct student),1,fp); /*读入学生信息*/
while(!feof(fp))
{
/*文件未结束*/
/*查找学号相同且数据状态正常未作删除标记*/
if(stu.num==num&&stu.status==0)
break;
fread (&stu,sizeof(struct student),1,fp);/*继续读取学生信息*/
}
if(!feof(fp))
{
/*查询成功*/
printf("更新前学生的信息:\n");
printf("%-10s%-10s%-7s%-7s%-10s%-10s%-10s%7s\n",
"学号","姓名","性别","年龄","籍贯","系别","专业","班级");
printf("%-10d%-10s%-7s%-7d%-10s%-10s%-10s%-7d\n",
stu.num,stu.name,stu.sex,stu.age,stu.origin,
stu.depart,stu.major,stu.clas);
printf("输入更新后的数据:\n");
printf("学号:");
scanf("%d",&stu.num);
printf("姓名:");
scanf("%s",stu.name);
printf("性别:");
scanf("%s",stu.sex);
printf("年龄:");
scanf("%d",&stu.age);
printf("籍贯:");
scanf("%s",stu.origin);
printf("系别:");
scanf("%s",stu.depart);
printf("专业:");
scanf("%s",stu.major);
printf("班级:");
scanf("%d",&stu.clas);
/*将指针从当前位置移动到一个学生信息之前*/
fseek(fp,-sizeof(struct student),SEEK_CUR);
fwrite(&stu,sizeof(struct student),1,fp); /*写入数据*/
}
else
{
/*查询失败*/
printf("无此学号的学生!\n");
clearerr(fp); /*清除文件结束标志*/
}
}
/*查询数据函数*/
void search_data()
{
struct student stu; /*学生*/
int num; /*学生的学号*/
printf("输入要查询的学生的学号:");
scanf("%d",&num);
rewind(fp);
fread(&stu,sizeof(struct student),1,fp); /*读入学生信息*/
while(!feof(fp))
{
/*文件未结束*/
/*学生的学号相同且数据正常,未作删除标记*/
if(stu.num==num&&stu.status==0) /*查询成功*/
break;
fread(&stu,sizeof(struct student),1,fp);/*读入学生信息*/
}
if(!feof(fp))
{
/*查询成功*/
printf("%-10s%-10s%-7s%-7s%-10s%-10s%-10s%7s\n",
"学号","姓名","性别","年龄","籍贯","系别","专业","班级");
printf("%-10d%-10s%-7s%-7d%-10s%-10s%-10s%-7d\n",
stu.num,stu.name,stu.sex,stu.age,stu.origin,
stu.depart,stu.major,stu.clas);
}
else
{
/*查询失败*/
printf("无此学号的学生:");
clearerr(fp);
}
}
/*删除数据函数*/
void delete_data()
{
struct student stu;
int num;
printf("输入要删除数据的学生的学号:");
scanf("%d",&num);
rewind(fp);
fread(&stu,sizeof(struct student),1,fp);
while(!feof(fp))
{
/*文件未结束*/
/*学生的学号相同并且数据状态正常,未作删除标记*/
if(stu.num==num&&stu.status==0)
break;
fread(&stu,sizeof(struct student),1,fp);
}
if(!feof(fp))
{
/*查询成功*/
printf("被删除记录为:\n");
printf("%-10s%-10s%-7s%-7s%-10s%-10s%-10s%7s\n",
"学号","姓名","性别","年龄","籍贯","系别","专业","班级");
printf("%-10d%-10s%-7s%-7d%-10s%-10s%-10s%-7d\n",
stu.num,stu.name,stu.sex,stu.age,stu.origin,
stu.depart,stu.major,stu.clas);
stu.status=1; /*使数据状态为删除状态*/
/*将指针从当前位置移动到一个学生信息之前*/
fseek(fp,-sizeof(struct student),SEEK_CUR);
fwrite(&stu,sizeof(struct student),1,fp); /*写入数据*/
}
else
{
/*查询失败*/
printf("无此学生学号的信息!\n");
clearerr(fp);
}
}
/*显示数据函数*/
void list_data()
{
struct student stu[MAX],tstudent;
int select; /*选择变量*/
int stcout=0,n; /*stcout表示学生的个数*/
int i,j;
printf("请选择:\n");
printf("1.按学号显示 2.按专业显示\n");
scanf("%d",&select);
while(select<1||select>3)
{
printf("请输入1或2的数:");
scanf("%d",&select);
}
rewind(fp); /*使位置指针返回到文件的开头*/
fread(&stu[0],sizeof(struct student),1,fp); /*读入学生信息*/
while(!feof(fp))
{
/*计算文件中学生信息的学生数*/
stcout++;
/*继续读入学生信息*/
fread(&stu[stcout],sizeof(struct student),1,fp);
}
if(select==1)
{
/*用冒泡排序法把学生信息按学号大小排序*/
for(i=1;i<=stcout;i++)
for(j=0;j<stcout-i;j++)
{
if(stu[j].num>stu[j+1].num)
{
tstudent=stu[j];
stu[j]=stu[j+1];
stu[j+1]=tstudent;
}
}
printf("按学生的学号排序:\n");
printf("%-10s%-10s%-7s%-7s%-10s%-10s%-10s%7s\n",
"学号","姓名","性别","年龄","籍贯","系别","专业","班级");
for(i=0;i<stcout;i++) /*按学号顺序输出学生信息*/
{
if(stu[i].status==0) /*数据状态正常,未作删除标志*/
{
printf("%-10d%-10s%-7s%-7d%-10s%-10s%-10s%-7d\n",
stu[i].num,stu[i].name,stu[i].sex,stu[i].age,
stu[i].origin,stu[i].depart,stu[i].major,
stu[i].clas);
}
}
}
else
{
/*用冒泡排序法把学生信息按专业排序*/
for(i=0;i<stcout;i++)
for(j=0;j<stcout-i;j++)
{
if(strcmp(stu[j].major,stu[j+1].major)>0)
{
tstudent=stu[j];
stu[j]=stu[j+1];
stu[j+1]=tstudent;
}
}
printf("按专业排序:\n");
printf("%-10s%-10s%-7s%-7s%-10s%-10s%-10s%7s\n",
"学号","姓名","性别","年龄","籍贯","系别","专业","班级");
for(i=0;i<stcout;i++) /*按专业顺序输出学生信息*/
{
if(stu[i].status==0)
{
printf("%-10d%-10s%-7s%-7d%-10s%-10s%-10s%-7d\n",
stu[i].num,stu[i].name,stu[i].sex,stu[i].age,
stu[i].origin,stu[i].depart,stu[i].major,
stu[i].clas);
}
}
}
clearerr(fp); /*清除文件结束标记*/
}
/*重组文件函数*/
void pack()
{
struct student stu;
FILE *fpTmp;
if((fpTmp=fopen("stu_tmp.dat","wb"))==NULL)
{
/*文件stu_tmp.dat打开失败*/
printf("打开文件stu_tmp.dat失败!");
system("PAUSE"); /*暂时停一下,等待下一个操作*/
exit(2); /*退出程序*/
}
rewind(fp); /*使文件指针返回到文件开头*/
fread(&stu,sizeof(struct student),1,fp); /*读入图书信息*/
while(!feof(fp))
{
/*文件未结束*/
if(stu.status==0) /*数据状态正常,未作删除标记*/
fwrite(&stu,sizeof(struct student),1,fpTmp); /*写入图书信息*/
fread(&stu,sizeof(struct student),1,fp); /*继续读入图书信息*/
}
fclose(fp);fclose(fpTmp); /*关闭文件*/
remove("stu.dat"); /*删除文件*/
rename("stu_tmp.dat","stu.dat"); /*更改文件名*/
if((fp=fopen("stu.dat","rb+"))==NULL)
{
/*打开文件stu.dat失败*/
printf("打开文件stu.dat失败!");
system("PAUSE"); /*暂时停一下,等待下一个操作*/
exit(3); /*退出程序*/
}
}