(一)、 课程设计题目
《学生成绩管理系统》的设计与实现
(二)、 课程设计目的
1、 进一步掌握和利用C语言进行程设计的能力;
2、 进一步理解和运用结构化程设计的思想和方法;
3、 初步掌握开发一个小型实用系统的基本方法;
4、 学会调试一个较长程序的基本方法;
5、 学会利用流程图或N-S图表示算法;
6、 掌握书写程设计开发文档的能力(书写课程设计报告);
(三)、 设计内容
1、每一条记录包括一个学生的学号、姓名、3门课成绩、平均成绩。
2、输入功能:可以一次完成若干条记录的输入。
3、显示功能:完成全部学生记录的显示。
4、查找功能:完成按姓名查找学生记录,并显示。
5、排序功能:按学生平均成绩进行排序。
6、插入功能:按平均成绩高低插入一条学生记录。
7、将学生记录存在文件score中。
8、应提供一个界面来调用各个功能,调用界面和各个功能的操作界面应尽可能清晰美观!
(四)、 设计要求
1、 用C语言实现系统;
2、 利用结构体数组实现学生成绩的数据结构设计;
3、 系统具有增加,查询,插入,排序等基本功能;
4、 系统的各个功能模块要求用函数的形式实现;
5、 完成设计任务并书写课程设计报告。
6、 将学生成绩信息存在文件中。
(五)、提交材料
1、课程设计报告
1)课程设计题目、内容、要求。
2)总体设计(包含几大功能模块)。
3)详细设计(各功能模块的具体实现算法——流程图)
4)数据结构设计描述,各模块(函数)的功能介绍,参数说明等。
5)调试分析(包含各模块的测试用例,及测试结果。)
6)总结(课程设计完成了哪些功能,还有哪些地方需要改进,及通过一周的课程设计有何收获,调试程序的体会等)
二:本程序共有八个功能与数据结构说明:
1.学生记录的输入(一次性输入,输入个数由用户决定,最大可容纳80记录,最大数可以在源程序中改) 。
2.追加学生记录。(追加后不能超过最在值80)。
3.修改记录。
4.删除记录。
5.浏览全部记录。
6.查找记录(按姓名查找)。
7.插入记录。
8.对记录进行排序(按平均成绩排序)。
9.退出。
10.数据结构是这样的:学号只能由数字字符组成,最大可以11个字符;姓名由字符组成,最大可以20个字符;三门科目分数都是整型;平均成绩是实型。
11.程序中定义了学生的容量为50个。容量可以在源程序宏定义中改,本程序宏定义#define N 50
#include<string.h>
#include<stdio.h>
/*控制学生记录的容量*/
#define N 50
struct student
{char num;
char name[20];
int score;
float ave;
}stu[N];
/*全新保存函数*/
save(int n) /*保存函数,保存n个记录*/
{FILE *fp;
int i;
if((fp=fopen("score.txt","wb"))==NULL) /*以输出打开方式,在此前的记录被覆盖*/
{printf("\nCannot open file\n");
return NULL;
}
for(i=0;i<n;i++)
if(stu[i].ave!=0) /*stu[i].ave=0表此记录已删除*/
if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
printf("file write error\n");
fclose(fp);
}
/*加载记录或可以计算记录个数的函数*/
load() /*加载记录或可以计算记录个数的函数*/
{FILE *fp;
int i;
if((fp=fopen("score.txt","rb"))==NULL) /*以输出打开方式,在此前的记录被覆盖*/
{printf("\nCannot open file\n");
return NULL;
}
for(i=0;!feof(fp);i++)
fread(&stu[i],sizeof(struct student),1,fp);
fclose(fp);
return(i-1); /*返回记录个数*/
}
/*一个任务结束时的选择浏览还是返回的函数*/
void printf_back() /*一个任务结束时的选择浏览还是返回*/
{int k,w;
printf("\n\n\tSuccessful. ^_^\n\n");
printf("What do you want to do? \n\n\t1).Browse all now\t2).Back: [ ]\b\b");
scanf("%d",&w);
if(w==1) browse();
else menu();
}
/*显示数据结构项目函数*/
void printf_face() /*显示数据结构项目*/
{printf("\n\tNO. name score1 score2 score3 average\n");
}
average(int i) /*对第i个记录的分数求平均值*/
{int j,sum;
for(sum=0,j=0;j<3;j++)
sum+=stu[i].score[j];
stu[i].ave=sum/3.0;
}
/*学号输入函数*/
no_input(int i,int n) /*i表示第i个的学生信息,n表示比较到第n个学生*/
{int j,k,w1;
do
{w1=0;
printf("NO.:");
scanf("%s",stu[i].num);
for(j=0;stu[i].num[j]!=''\0'';j++) /*学号输入函数,作了严格规定*/
if(stu[i].num[j]<''0''||stu[i].num[j]>''9'') /*判断学号是否为数字*/
{puts("Input error! Only be made up of (0-9).Please reinput!\n");
w1=1;break;
}
if(w1!=1)
for(k=0;k<n;k++) /*比较到第n个学生*/
/*排除第i个学生记录即你要修改的*/
if(k!=i&&strcmp(stu[k].num,stu[i].num)==0) /*判断学号是否有雷同*/
{puts("This record is exist. please reinput!\n");
w1=1;break;
}
}
while(w1==1);
}
/*对分数输入*/
score_input(int i)
{int j;
for(j=0;j<3;j++)
{printf("score %d:",j+1);
scanf("%d",&stu[i].score[j]);
}
}
/*输入一个记录函数*/
input(int i) /*输入一个记录函数*/
{
no_input(i,i); /*调用学号输入函数*/
printf("name:");
scanf("%s",stu[i].name);
score_input(i); /*调用分数输入函数*/
average(i); /*调用求平均值函数*/
}
/*显示一个记录的函数*/
printf_one(int i) /*显示一个记录的函数*/
{int j;
printf("%11s %-17s",stu[i].num,stu[i].name);
for(j=0;j<3;j++)
printf("%9d",stu[i].score[j]);
printf("%9.2f\n",stu[i].ave);
}
void puts___() /*显出---函数*/
{puts("\n--------------------------------------------------------------------");
}
/*修改记录函数*/
modify_data(int i,int n) /*修改数据函数,修改第i个记录*/
{int c,w1;
do /*输入选择作个判断*/
{puts("\nmodify by =>\n\n 1).NO. 2.name 3).score1 4).score2\n 5).score3 6).all score 7).all data 8).cancel and back");
printf("Which you needed?: [ ]\b\b");
scanf("%d",&c);
if(c>8||c<1)
{puts("\nChoice error! Please again!"); /*判断选择是否错误,若是则重新选择性*/
getchar(); /*当输入是字符时可以防止死循环*/
}
}
while(c>8||c<1);
do
{switch(c) /*选择要修改的项目*/
{case 1:no_input(i,n);break; /*调用学号输入函数*/
case 2:printf("name:");scanf("%s",stu[i].name);break;
case 3:printf("score1:");scanf("%d",&stu[i].score[0]);break;
case 4:printf("score2:");scanf("%d",&stu[i].score);break;
case 5:printf("score3:");scanf("%d",&stu[i].score);break;
case 6:score_input(i);break; /*调用分数输入函数*/
case 7:input(i);break; /*调用输入整条学生记录*/
case 8:menu(); /*直接返回主介面*/
}
if(c>2&&c<7)
average(i); /*调用求平均值函数*/
puts("\nNow:\n");
printf_face(); /*调用显示数据结构项目函数*/
printf_one(i); /*修改后的记录让用户确认*/
printf("\nAre you sure?\n\n\t1).Sure 2).No and remodify 3).Back without save in this time [ ]\b\b"); /*是否确定*/
scanf("%d",&w1); /*选择2则表示这次修改错误要重新修改*/
}
while(w1==2);
return(w1); /*返回控制值*/
}
/****************输入模块****************/
enter() /*输入模块*/
{int i,n;
printf("How many students(0-%d)?:",N);
scanf("%d",&n); /*要输入的记录个数*/
printf("\nEnter data now\n\n");
for(i=0;i<n;i++)
{printf("\nInput %dth student record.\n",i+1);
input(i); /*调用输入函数*/
}
if(i!=0) save(n); /*调用保存函数*/
printf_back(); /*一个任务结束时让用户选择是浏览还是返回*/}
/****************追加模块****************/
add() /*追加模块*/
{int i,n,m,k;
FILE *fp;
n=load();
printf("How many students are you want to add(0-%d)?:",N-n);
scanf("%d",&m); /*输入要追加的记录个数*/
k=m+n;
for(i=n;i<k;i++)
{printf("\nInput %dth student record.\n",i-n+1);
input(i); /*调用输入函数*/
}
if((fp=fopen("score.txt","ab"))==NULL) /*以ab方式打开文件,追加保存*/
{printf("cannot open file\n");
return;
}
for(i=n;i<k;i++) /*输入出到文件*/
if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
printf("file write error\n");
fclose(fp);
printf_back(); /*一个任务结束时的选择浏览还是返回*/
}
/****************修改模块****************/
modify() /*修改模块*/
{struct student s;
FILE *fp;
int i,n,k,w0=1,w1,w2=0;
n=load();
do
{clrscr();
k=-1;
/*给用户看全部记录以便确认要修改的记录*/
puts___(); /*显示-----*/
printf_face(); /*调用显示数据结构项目函数*/
for(i=0;i<n;i++)
{if((i!=0)&&(i%10==0)) /*目的是分屏显示*/
{printf("\n\nRemember NO.which needed modify. pass any key to contiune . . .");
getch();
puts("\n\n");
}
printf_one(i); /*调用显示一个记录的函数*/
}
puts___();
do
{printf("\n\nEnter NO. that you want to modify! NO.:");
scanf("%s",s.num); /*输入要修改的数据的学号*/
for(i=0;i<n;i++) /*查找要修改的数据*/
if(strcmp(s.num,stu[i].num)==0)
{k=i; /*找到要修改的记录*/
s=stu[i]; /*把stu[i](即当次修改的学生记录)备份给s,以便用户反悔时恢复名誉*/
}
if(k==-1) printf("\n\nNO exist! please again");
}
while(k==-1); /*当K=-1表示没有找到*/
printf_face(); /*调用显示数据结构项目函数*/
printf_one(k); /*调用显示一个记录的函数*/
w1=modify_data(k,n); /*修改学生记录并且返回保存控制值w1,w1=1则表示用户已确认修改*/
if(w1==1) /*W1等于1时则表示用户确定这次修改*/
{printf("\nSuccessful ^_^.\n\nAre you modify another?\n\n\t1).Yes 2).Back with save\t[ ]\b\b");
scanf("%d",&w0);
w2=1; /*来控制保存,使w2=1是标记已有过修改*/
}
else
{w0=0;
if(w2==1)
stu[k]=s;
} /*走到这里是由于用户没有确认这次修改(在调用修改函数w1=modify_data(k,n);时没有确认). 使W0=0,为了让终止循环,
stu[k]=s,则把备份的s恢复给stu[k](即当次修改的),这样的好处是确保在此之前修改过的成功保存,而本次(用户没有确认的)不修改*/
if(w0!=1&&w2==1) /*W0不等于1则表示正常返回,w2=1表示在此之前有过修改,这时就保存用户已确认修改的并返回*/
save(n); /*w2不等于1表示在此次之前没有修改过(即:第一次),而又反悔这次修改,则不保存返回*/
}
while(w0==1);
menu();
}


