C语言课程设计报告 学生成绩管理系统.docx
《C语言课程设计报告 学生成绩管理系统.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告 学生成绩管理系统.docx(37页珍藏版)》请在冰豆网上搜索。
C语言课程设计报告学生成绩管理系统
C语言课程设计报告
院系:
机械与电子信息学院
姓名:
王鹏飞
班号:
07310126
学号:
20101003558
指导教师:
龚文引
日期:
2011年7月
学生成绩管理系统
一、题目要求
设计一个学生成绩管理程序,对在校某班学生几门课程的考试成绩进行统一管理。
每个学生记录包括学号、姓名、年龄、数学、英语、物理成绩,默认以学号为序存放。
(1)一个文件按以班为单位存储学生记录。
(2)将允许的操作分为四种,以A、B、C、D、E、F为标志(若设置菜单操作更佳):
A:
插入一个新的学生记录(录入学生信息);
B:
修改学生记录;
C:
删除一个学生记录;
D:
登记成绩;
E:
修改成绩;
F:
浏览全班成绩。
(3)计算学生的总成绩。
(4)按学号排序输出全班成绩表。
二、需求分析
根据题目要求,由于学生信息是存放在文件中,所以应提供文件的输入、输出等操作;在程序中需要浏览学生的信息,应提供添加、修改、删除、排序等操作;另外还应提供键盘式选择菜单实现功能选择。
三、总体设计
根据上面的需求分析,可以将这个系统的设计分为8个模块,数据输入,添加数据,修改数据,删除数据,修改成绩,学号排序,浏览成绩,退出模块.
学生成绩管理系统
数据输入
添加数据
修改数据
删除数据
修改成绩
学号排序
浏览成绩
退出模块
四.详细设计
1、主函数
【分析】
将各个功能模块设置为菜单选项,方便调用,且执行完每部分功能模块后能够方便返回到系统界面.
【流程图】:
开始
显示一系列功能选项
N
输入n,判断n是否是A-H间的字母
Y
根据n的值调用各功能模块函数
结束
【程序代码】:
menu()/*主界面*/
{
intw1;
charn;/*.变量n保存选择菜单数字,w1判断输入的数字是否在功能菜单对应数字范围内*/
do
{
puts("\t\t***************菜单****************\n\n");
puts("\t\t\t\tA.录入学生信息");
puts("\t\t\t\tB.修改学生记录");
puts("\t\t\t\tC.删除一个学生记录");
puts("\t\t\t\tD.登记成绩");
puts("\t\t\t\tE.修改成绩");
puts("\t\t\t\tF.浏览全班成绩");
puts("\t\t\t\tG.退出");
puts("\n\n\t\t************************************\n");
printf("操作选择(A-H):
[]\b\b");
n=getchar();
printf("\n");
if(n<'A'||n>'H')
w1=1;/*对选择的数字作判断*/
else
w1=0;
}
while(w1==1);
switch(n)/*选择功能*/
{
case'A':
enter();break;/*输入模块*/
case'B':
modify();break;/*修改模块*/
case'C':
delete();break;/*删除模块*/
case'D':
add();break;/*登记成绩模块*/
case'E':
modify_score();break;/*修改成绩模块*/
case'F':
browse();break;/*浏览模块*/
case'G':
exit(0);/*退出模块*/
}
}
main()/*主函数*/
{
menu();
}
2、各功能模块设计
(1)输入模块
【数据分析】:
单看各数据信息,学号﹑年龄以及数学﹑英语﹑物理各科成绩和总分均是整型,姓名可以采用字符型数组.数据信息存放在文件中,一条记录对应一个学生,既符合习惯也方便信息管理.把学生的学号﹑姓名﹑年龄﹑各科成绩及总分作为结构体成员,存放若干个学生信息就用结构体数组.
【流程图】:
输入用户要输入学生记录的个数n
i从0到n-1调用输入函数input(i)
Y
调用保存函数save(n)
【程序代码】
enter()/*输入模块*/
{
inti,n;
printf("Howmanystudents(1-%d)?
:
",N);
scanf("%d",&n);/*要输入的记录个数*/
printf("\nEnterdatanow\n\n");
for(i=0;i{
printf("\nInput%dthstudentrecord.\n",i+1);
input(i);/*调用输入函数*/
}
if(i!
=0)
save(n);/*调用保存函数*/
printf_back();/*一个任务结束时让用户选择是浏览还是返回*/
}
(2)修改模块
【分析】:
该模块的功能是显示所有学生信息,考虑到记录很多,故采用分屏显示。
显示完所有记录后,用户输入要修改学生的学号,根据学号查找学生记录,并提示用户修改该记录的哪部分信息,是学号、姓名、年龄或某科成绩、总分还是所有信息都修改,根据用户选择修改相应信息。
【流程图】:
返回主菜单
Y
N
【程序代码】:
modify()/*修改模块*/
{
structstudents;
FILE*fp;
inti,n,k,w0=1,w1,w2=0;
n=load();
do
{
k=-1;/*给用户看全部记录以便确认要修改的记录*/
printf_face();/*调用显示数据结构项目函数*/
for(i=0;i{
if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{
printf("\n\n请输入您要修改的学生编号(No.073101-).按任意键继续...");
getch();
puts("\n\n");
}
printf_one(i);
printf("\n");
}
do
{
printf("\n\n请输入您要修改的学生编号(No.073101-)!
NO.:
073101-");
scanf("%d",&s.num);/*输入要修改的数据的学号*/
for(i=0;iif(s.num==stu[i].num)
{
k=i;/*找到要修改的记录*/
s=stu[i];/*把stu[i]备份给s,以便用户反悔时恢复*/
}
if(k==-1)printf("\n\n记录不存在,请重新输入!
");
}
while(k==-1);/*当k=-1表示没有找到*/
printf_face();
printf_one(k);/*调用显示一个记录的函数*/
w1=modify_data(k,n);/*修改学生记录并且返回保存控制值w1,w1=1则表示用户已确认修改*/
if(w1==1)/*确认修改*/
{
printf("\n修改成功!
^_^.\n\n是否继续修改?
\n\n\t1.是2.返回并保存\t[]\b\b");
scanf("%d",&w0);
w2=1;/*来控制保存,使w2=1是标记已有过修改*/
}
else
{
w0=0;/*结束*/
if(w2==1)
stu[k]=s;
}/*没有修改,把备份的s恢复,使w0=0是为了让循环终止*/
if(w0!
=1&&w2==1)
save(n);/*正常返回,且有过修改*/
}
while(w0==1);
menu();
}
(3)删除模块
【分析】:
该模块的功能是与修改模块一样先显示所有的学生信息,同样考虑到记录很多,采用分屏显示。
显示完所有记录后,用户输入要删除学生的学号,根据学号查找学生记录并删除。
删除一般的做法是将数据从文件中删除,删除位置后面的记录往前挪。
【流程图】:
显示所有记录,让用户看哪个要删除
输入要删除的学号
是否找到此学生记录
Y
N
显示找到的记录提示没有找到
使stu[k].sum=0
Y
继续删除?
N
返回主菜单
【程序代码】:
delete()/*删除模块*/
{
structstudents;
FILE*fp;
inti,n,k,w0=1,w1,w2=0;
n=load();
do
{
k=-1;
printf_face();
for(i=0;i{
if((i!
=0)&&(i%10==0))/*分屏显示*/
{
printf("\n\n请输入您要删除的学生编号(No.073101-).按任意键继续...");
getch();
puts("\n\n");
}
printf_one(i);
printf("\n");
}
do
{
printf("\n\n请输入您要删除的学生编号(No.073101-)!
NO.:
073101-");
scanf("%d",&s.num);
for(i=0;iif(s.num==stu[i].num)
{
k=i;
s=stu[i];/*将要删除的记录备份给s*/
}
if(k==-1)printf("\n\n记录不存在,请重新输入!
");
}
while(k==-1);
printf_face();
printf_one(k);
printf("\n确定删除?
\n\n\t1.是2.此次返回,但不保存[]\b\b");
scanf("%d",&w1);
if(w1==1)
{
stu[k].sum=0;/*标记为0后,保存时便不保存*/
printf("\n成功删除!
^_^.\n\n是否继续删除?
\n\n\t1.是2.返回并保存\t[]\b\b");
scanf("%d",&w0);
w2=1;/*确认删除*/
}
else
{
w0=0;/*end*/
if(w2==1)
stu[k]=s;
}
if(w0!
=1&&w2==1)
save(n);/*正常返回且已删除*/
}
while(w0==1);
menu();
}
(4)登记成绩模块
【分析】:
该模块的功能是用户需要增加新的学生记录,请从键盘输入并逐条写到原来的输入文件中.
【流程图】:
调用加载函数n=load();并计算可以记录个数n
输入用户要添加学生记录的个数m
K=m+n
i从n到k调用输入函数input(i)
保存添加的记录
【程序代码】:
add()/*登记成绩模块*/
{
inti,n,m,k;
FILE*fp;
n=load();
printf("您要添加几个学生(1-%d)?
:
",N-n);
scanf("%d",&m);/*输入要添加的记录个数*/
k=m+n;
for(i=n;i{
printf("\n请输入第%d个学生数据.\n",i+1);
input(i);/*调用输入函数*/
}
if((fp=fopen("score.txt","ab"))==NULL)/*以ab方式打开文件,添加保存*/
{
printf("不能打开此文件.\n");
}
for(i=n;iif(fwrite(&stu[i],sizeof(structstudent),1,fp)!
=1)
printf("文件写入错误.\n");
fclose(fp);
printf_back();/*一个任务结束时的选择浏览还是返回*/
}
(5)修改成绩模块
【分析】:
该模块的功能是修改各科成绩或全体成绩。
【流程图】:
返回主菜单
【程序代码】:
modify_score()/*修改成绩模块*/
{
structstudents;
FILE*fp;
inti,n,k,w0=1,w1,w2=0;
n=load();
do
{
k=-1;
printf_face();
for(i=0;i{
if((i!
=0)&&(i%10==0))/*分屏显示*/
{
printf("\n\n请输入您要修改成绩的学生编号(No.073101-)!
.按任意键继续...");
getch();
puts("\n\n");
}
printf_one(i);
printf("\n");
}
do
{
printf("\n\n请输入您要修改成绩的学生编号(No.073101-)!
NO.:
073101-");
scanf("%d",&s.num);/*输入要修改的学生学号*/
for(i=0;iif(s.num==stu[i].num)
{
k=i;
s=stu[i];/*将要修改的记录备份*/
}
if(k==-1)
printf("\n\n记录不存在,请再次输入!
");
}
while(k==-1);
printf_face();
printf_one(k);
w1=modify_score1(k);/*调用修改成绩函数*/
if(w1==1)
{
printf("\n修改成功!
^_^.\n\n是否继续修改成绩?
\n\n\t1.是2.保存并返回\t[]\b\b");
scanf("%d",&w0);
w2=1;/*确认修改*/
}
else
{
w0=0;/*结束*/
if(w2==1)
stu[k]=s;
}
if(w0!
=1&&w2==1)
save(n);
}
while(w0==1);/*正常返回且已修改*/
menu();
}
(6)浏览模块
【分析】:
该模块的功能是显示所有学生记录信息。
【流程图】:
【程序代码】:
browse()/*浏览模块*/
{
inti,j,n;
n=load();/*加载记录*/
printf_face();/*调用显示数据结构项目函数*/
for(i=0;i{
if((i!
=0)&&(i%10==0))/*分屏显示*/
{
printf("\n\n按任意键继续...");
getch();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
printf("\n");
}
printf("\t共有%d项记录.\n",n);
printf("\n按任意键返回...");
getch();/*按任意键*/
menu();
}
3、一些公共函数
下面是在每个模块中都有可能用到的一些公共函数。
(1)保存函数save(intn)
【说明】
形参n控制保存的个数。
当stu[k].sum=0表示删除,不保存该记录。
【程序代码】
save(intn)/*保存函数,保存n个记录*/
{
FILE*fp;
inti;
if((fp=fopen("score.txt","wb"))==NULL)/*以输出打开方式,在此前的记录被覆盖*/
{
printf("\n不能打开此文件\n");
returnNULL;
}
for(i=0;iif(stu[i].sum!
=0)/*stu[i].sum=0表示该记录已删除*/
if(fwrite(&stu[i],sizeof(structstudent),1,fp)!
=1)
printf("文件写入错误\n");
fclose(fp);
}
(2)加载函数load()
【说明】
该函数可以用来加载所有记录,并且可以返回所有记录的个数。
【程序代码】
load()/*加载记录或可以计算记录个数的函数*/
{
FILE*fp;
inti;
if((fp=fopen("score.txt","rb"))==NULL)/*以输出打开方式,在此前的记录被覆盖*/
{
printf("\n不能打开此文件\n");
returnNULL;
}
for(i=0;!
feof(fp);i++)
fread(&stu[i],sizeof(structstudent),1,fp);
fclose(fp);
return(i-1);/*返回记录个数*/
}
(3)学号输入函数no_input(inti,intn)
【说明】
该函数对输入学号进行判断,确保输入的学号唯一。
形参i表示第i个学生记录,形参n表示总共有n个学生记录。
【程序代码】
no_input(inti,intn)/*学号输入函数*/
{
intk,w1;
do
{
w1=0;
printf("NO.:
073101-");
scanf("%d",&stu[i].num);
if(stu[i].num<1||stu[i].num>N)/*判断学号是否在1到N之间*/
{
puts("输入错误!
学号只能在(1-N)之间.请重新输入!
\n");
w1=1;
}
if(w1!
=1)
for(k=0;kif(k!
=i&&(stu[k].num==stu[i].num))/*判断学号是否有相同*/
{
puts("此记录已存在.请重新输入!
\n");
w1=1;break;
}
}
while(w1==1);
}
(4)输入三科成绩函数enter_score(inti)
【说明】
形参i表示第i个学生记录。
【程序代码】
enter_score(inti)/*输入三科成绩函数*/
{
printf("数学英语物理");
scanf("%d%d%d",&stu[i].Math,&stu[i].English,&stu[i].Physical);/*对分数输入*/
}
(5)求总分函数sum(inti)
【说明】
形参i表示第i个学生记录。
【程序代码】
sum(inti)/*对第i个记录的分数求总分*/
{
stu[i].sum=stu[i].Math+stu[i].English+stu[i].Physical;
}
(6)输入一个记录的函数input(inti)
【说明】
形参i表示第i个学生记录。
【程序代码】
input(inti)/*输入一个记录的函数*/
{
no_input(i,i);/*调用学号输入函数*/
printf("姓名:
年龄:
");
scanf("%s%d",stu[i].name,&stu[i].age);/*输入姓名、年龄*/
enter_score(i);/*调用分数输入函数*/
sum(i);
}
(7)修改成绩函数modify_score1(inti)
【说明】
形参i表示第i个学生成绩记录,此函数带回保存控制值w1,当w1=1时表示确认保存。
【程序代码】
modify_score1(inti)/*修改成绩函数*/
{
intc,w1;
do
{
puts("\n修改=>\n\n1.数学2.英语3.物理4.总分5.取消并返回");
printf("您需要修改?
:
[]\b\b");/*输入选择作个判断*/
scanf("%d",&c);
if(c>5||c<1)
{
puts("\n选择错误!
请重新选择!
");/*判断选择是否错误*/
getchar();
}
}
while(c>5||c<1);
do
{
switch(c)/*选择要修改的项目*/
{
case1:
printf("数学:
");
scanf("%d",&stu[i].Math);break;
case2:
printf("英语:
");
scanf("%d",&stu[i].English);break;
case3:
printf("物理:
");
scanf("%d",&stu[i].Physical);break;
case4:
enter_score(i);break;/*调用成绩输入函数*/
case5:
break;
}
if(c>0&&c<5)sum(i);/*调用求总分函数*/
puts("\n现在:
\n");
printf_face();
printf_one(i);/*修改后的记录让用户确认*/
printf("\n确认修改?
\n\n\t1.是2.否,重新修改3.此次保存并返回[]\b\b");
scanf("%d",&w1);/*输入2表示重新修改*/
}
while(w1==2);
return(w1);
}
(8)修改记录函数modify_data(inti,intn)
【说明】
形参i表示第i个学生成绩记录,形参n表示有n个记录,此函数带回保存控制值w1,当w1=1时表示确认保存。
【程序代码】
modify_data(inti,intn)/*修改记录函数*/
{
intc,w1;
do
{
puts("\n修改=>\n\n1.编号2.姓名3.年龄4.数学5.英语6.物理7.总分8.所有数据9.取消并返回");
printf("您需要修改?
:
[]\b\b"