计算机编程实验实验一学生成绩管理系统设计与测试.docx
《计算机编程实验实验一学生成绩管理系统设计与测试.docx》由会员分享,可在线阅读,更多相关《计算机编程实验实验一学生成绩管理系统设计与测试.docx(11页珍藏版)》请在冰豆网上搜索。
![计算机编程实验实验一学生成绩管理系统设计与测试.docx](https://file1.bdocx.com/fileroot1/2023-4/21/269b6f08-1fc7-4ab7-ac90-e71df3219f83/269b6f08-1fc7-4ab7-ac90-e71df3219f831.gif)
计算机编程实验实验一学生成绩管理系统设计与测试
信息与通信工程学院
标准实验报告
计算机编程实验
一、实验室名称:
计算机实验中心
二、实验项目名称:
学生成绩管理系统设计与测试
三、实验学时:
4
四、实验原理:
利用C语言集成开发环境设计学生成绩管理系统软件,并进行测试
五、实验目的:
1.练习结构、数组、指针、函数、文件等知识的综合运用;
2.理解全局变量、局部变量、静态变量等内容。
3.了解字符串函数的使用和预处理的作用。
4.理解结构化程序设计方法,利用结构化程序设计方法,综合运用函数、
数组、指针、结构等进行较复杂程序设计,能够实现一些简单的功能型
程序。
六、实验内容:
1.设计表示学生信息的结构;
2.确定函数流程,清楚函数实现功能;
3.熟悉文件的操作,编写函数从文件读取学生信息;
4.编写统计函数,对读取的信息进行统计;
5.编写输出函数,熟悉格式控制符的使用;
6.设计测试文件,测试设计的结构和编写的函数;
7.给出测试结果,程序评价。
从文件中读取学生信息并打印。
完成以下编程实验,调试运行程序并完成报告。
设每个学生包含如下信息:
属性名
姓名
学号
C成绩
C实验成绩
C总成绩
类型
字符串
字符串
整数
整数
整数(初始化为0)
1.设计一个表示学生信息的结构structstuden;t
2.编写函数从文件读入所有学生信息:
a)函数定义intReadStudentInfo(constchar*filename,structstudent**
pStudents);函数返回值:
返回学生个数,失败返回-1。
输入参数const
char*filename:
数据文件名;structstudent**pStudents:
返回读取的学
生信息,内存由ReadStudentInfo函数分配,main函数释放。
b)建议函数流程:
i.打开数据文件,失败返回-1;
ii.从头到尾扫描数据文件(即预读一遍)获得学生人数;
iii.根据学生人数,利用malloc和sizeof等函数或运算符为struct
student**pStudents分配内存;
iv.利用fseek函数,定位到文件头;
v.读取数据文件,并把每一条记录通过数组下标法或指针法保存到结
构体数组pStudents中;
vi.关闭文件;
vii.返回学生人数。
c)数据文件格式说明:
一行一条学生信息的记录,不同属性用空格隔开,输入数据中无总成
绩记录。
3.编写统计函数:
a)函数定义voidCount(structstudentpStudents[],intnum)。
输入参数分别
为保存学生的结构数组和学生人数。
b)功能为:
统计所有学生的总成绩和每个班(根据学号判断班级)的平
均成绩;输入参数包括学生信息结构数组,学生人数,计算的每个学
生的总成绩直接填充到对应的输入结构数组对应字段中。
统计信息包
括每个班的总人数、平均成绩数组,用全局变量来表示。
访问每个学
生信息的时候,用指针来指向当前正在处理的学生。
c)设计一个函数,实现根据学号计算班级,并在函数Count中使用。
4.编写信息输出函数:
要求通过一定的格式控制符,使得输出美观。
输出格式为:
学生信息:
序号姓名学号班级C成绩C实验成绩总成绩
1张三
2⋯⋯
统计信息:
序号班级学生人数平均成绩
11班3283
2⋯⋯
5.编写main函数实现:
a)定义变量,其中保存学生信息的数据文件直接在源代码中初始化;b)读取学生信息,如果失败,打印失败信息并退出程序;c)统计学生信息;d)输出统计信息。
e)释放内存。
七、实验器材(设备、元器件):
微型计算机一台,含操作系统,集成开发环境,文字处理软件等;
八、实验步骤:
九、实验数据及结果分析:
代码结构及优化方案介绍:
代码总体分为ReadStudentInfo、Count、printinformation三部分,分别
执行读取txt文件各部分到结构体、按照学号判断班级、打印输出功能,最后集
中再main函数中调用。
优化方案:
代码里有大量调用结构体的语句,但是一些函数直接访问地址,
不确定会不会在之后改变地址,所以用了一些缓冲区,构建一些空的字符串,将
数据先读取到字符串里,再进行使用,减少对结构体地址造成的改变。
并且Count
部分的判断进行了调整,没有再多余用一个函数嵌套判断,而是直接判断,调用
了全局变量。
代码如下:
#include
#include
#include
//定义结构体形式
structstudent
{
charname[50];
charstuID[50];
intgrade_C;
intgrade_EXP;
intgrade_All;
};
//定义全局变量,per表示每班学生的个数,sum表示班级总成绩
intfirst_per=0,first_ave,first_sum=0;
intsecond_per=0,second_ave,second_sum=0;
intthird_per=0,third_ave,third_sum=0;
intforth_per=0,forth_ave,forth_sum=0;
intfifth_per=0,fifth_ave,fifth_sum=0;
intsixth_per=0,sixth_ave,sixth_sum=0;
intReadStudentInfo(constchar*filename,structstudent**pStudents)
{
FILE*fp;//文件指针
structstudent*p;
intstu_num=0,i=0;
chartemp,temp_line[100]={0};
chartemp_num[20]={0};//将读取数据缓存
fopen_s(&fp,filename,"r");
fseek(fp,0L,SEEK_SET);
if(fp==NULL)
{
printf("FailtoRead\n");
exit(-1);
}
else{
while((temp=fgetc(fp))!
=EOF)
{
if(temp=='\n')
{
stu_num++;
}
}
}
fseek(fp,0L,SEEK_SET);
*pStudents=(structstudent*)malloc(stu_num*sizeof(**pStudents));
p=*pStudents;
fgets(temp_line,100,fp);//读取了一行数据,光标直接跳到第一行没用的末尾了
while((!
feof(fp))&&(i{
fscanf_s(fp,"%s",p->stuID,_countof(p->stuID));//使用_countof是用来计算字符数而不是字节数,
赋值到每个p地址对应的部分
fscanf_s(fp,"%s",p->name,_countof(p->name));
fscanf_s(fp,"%s",temp_num,_countof(temp_num));
p->grade_C=atoi(temp_num);
fscanf_s(fp,"%s",temp_num,_countof(temp_num));
p->grade_EXP=atoi(temp_num);
p->grade_All=0.4*p->grade_EXP+0.6*p->grade_C;
p++;
i++;
}
fclose(fp);
returnstu_num;
}
voidCount(structstudentpStudents[],intnum)
{
inti;
charcompare[20]={0};
for(i=0;i{
strncpy_s(compare,sizeofcompare,pStudents[i].stuID,10);//将学号前十位存放到一个临时的字符
串里
if(!
strncmp(compare,"2017020901",10))
{
first_per++;
first_sum=first_sum+(pStudents+i)->grade_All;
first_ave=first_sum/first_per;
}
if(!
strncmp(compare,"2017020902",10))
{
second_per++;
second_sum=second_sum+(pStudents+i)->grade_All;
second_ave=second_sum/first_per;
}
if(!
strncmp(compare,"2017020903",10))
{
third_per++;
third_sum=third_sum+(pStudents+i)->grade_All;
third_ave=third_sum/third_per;
}
if(!
strncmp(compare,"2017020904",10))
{
forth_per++;
forth_sum=forth_sum+(pStudents+i)->grade_All;
forth_ave=forth_sum/forth_per;
}
if(!
strncmp(compare,"2017020905",10))
{
fifth_per++;
fifth_sum=fifth_sum+(pStudents+i)->grade_All;
fifth_ave=fifth_sum/fifth_per;
}
if(!
strncmp(compare,"2017020906",10))
{
sixth_per++;
sixth_sum=sixth_sum+(pStudents+i)->grade_All;
sixth_ave=sixth_sum/sixth_per;
}
}
//打印函数
voidprintinformation(structstudentpStudents[],intnum_stu)
{
printf("\n学生信息:
\n\n");
printf("\n");
printf("序号姓名学号班级C成绩C实验成绩总成绩\n");
inti;
for(i=0;i{
pStudents[i].stuID,
printf("%d%s%s%d%d%d\n",i+1,pStudents[i].name,pStudents[i].grade_C,pStudents[i].grade_EXP,pStudents[i].grade_All);
}
printf("\n\n统计信息:
\n\n");
printf("\n");
printf("序号
班级
学生人数
平均成绩\n");
printf("
1
1班
%d
%d\n",first_per,first_ave);
printf("
2
2班
%d
%d\n",second_per,second_ave);
printf("
3
3班
%d
%d\n",third_per,third_ave);
printf("
4
4班
%d
%d\n",forth_per,forth_ave);
printf("
5
5班
%d
%d\n",fifth_per,fifth_ave);
printf("
6
6班
%d
%d\n",sixth_per,sixth_ave);
}
voidmain()
{
intstu_num;
constcharlocation[]="data.txt";
structstudent*pStudents=NULL;
constchar*filename=location;
stu_num=ReadStudentInfo(filename,&pStudents);//返回跳过第一行后的行数,也就是学生的个数
printf("%d",stu_num);
Count(pStudents,stu_num);
printinformation(pStudents,stu_num);
free(pStudents);//释放内存
getchar();//使终端停留
return0;
}
十、实验结论:
十二、对本实验过程及方法、手段的改进建议:
报告评分:
指导教师签字: