学生成绩管理系统设计与测试
你好! 这是你第一次为解决uestc学生计算机编程实验课程代码参考的博客。
实验目的
1.练习结构、数组、指针、函数、文件等知识的综合运用;
2.理解全局变量、局部变量、静态变量等内容。
3.了解字符串函数的使用和预处理的作用。
4.理解结构化程序设计方法,利用结构化程序设计方法,综合运用函数、数组、指针、结构等进行较复杂程序设计,能够实现一些简单的功能型程序。
实验内容
1.设计表示学生信息的结构;
2. 确定函数流程,清楚函数实现功能;
3.熟悉文件的操作,编写函数从文件读取学生信息;
4.编写统计函数,对读取的信息进行统计;
5.编写输出函数,熟悉格式控制符的使用;
6.设计测试文件,测试设计的结构和编写的函数;
7.给出测试结果,程序评价。
实验流程图
1.设计一个表示学生信息的结构 struct student;
2.编写函数从文件读入所有学生信息:
a) 函数定义 int ReadStudentInfo(const char* filename, struct
student** pStudents); 函数返回值:返回学生个数,失败返回-1。输入参数const char* filename:数据文件名;struct student** pStudents:返回读取的学生信息,内存由ReadStudentInfo函数分配,main函数释放。
b) 建议函数流程:
i.打开数据文件,失败返回-1;
ii.从头到尾扫描数据文件(即预读一遍)获得学生人数;
iii.根据学生人数,利用malloc和sizeof等函数或运算符为struct student** pStudents分配内存;
iv.利用remind函数,定位到文件头;
v.读取数据文件,并把每一条记录通过数组下标法或指针法保存到结构体数组pStudents中;
vi.关闭文件;
vii. 返回学生人数。
c) 数据文件格式说明:
一行一条学生信息的记录,不同属性用空格隔开,输入数据中无总成绩记录。
3. 编写统计函数:
a) 函数定义void Count(struct student pStudents[], int num)。输入参数分别为保存学生的结构数组和学生人数。
b) 功能为:统计所有学生的总成绩和每个班(根据学号判断班级)的平均成绩;输入参数包括学生信息结构数组,学生人数,计算的每个学生的总成绩直接填充到对应的输入结构数组对应字段中。统计信息包括每个班的总人数、平均成绩数组,用全局变量来表示。访问每个学生信息的时候,用指针来指向当前正在处理的学生。
c) 设计一个函数,实现根据学号计算班级,并在函数Count中使用。
4. 编写信息输出函数:
要求通过一定的格式控制符,使得输出美观。输出格式为:
5. 编写main函数实现:
a) 定义变量,其中保存学生信息的数据文件直接在源代码中初始化;
b) 读取学生信息,如果失败,打印失败信息并退出程序;
c) 统计学生信息;
d) 输出统计信息。
e) 释放内存。
实验数据格式
实验代码(C/C++)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
struct student {
char name[8];//姓名
char major[13]; //班级
int test_sco;//实验成绩
int paper_sco;//卷面成绩
int sum;//总成绩
char number[13];//学号
};
int yi_per = 0, yi_ave, yi_sum = 0;
int er_per = 0, er_ave, er_sum = 0;
int san_per = 0, san_ave, san_sum = 0;
int si_per = 0, si_ave, si_sum = 0;
int wu_per = 0, wu_ave, wu_sum = 0;
int liu_per = 0, liu_ave, liu_sum = 0;//6个班的三种成绩初始值为0
int ReadStudentInfo(const char* filename, struct student** pStudents);
//打开数据文件,失败返回 - 1;
//从头到尾扫描数据文件(即预读一遍)获得学生人数;
//根据学生人数,利用malloc和sizeof等函数或运算符为struct student * *pStudents分配内存;
//利用rewind函数,定位到文件头;
//读取数据文件,并把每一条记录通过数组下标法或指针法保存到结构体数组pStudents中;
//关闭文件;
//返回学生人数。
void Count(struct student pStudents[], int num);
int main()
{
int count;
int m;
struct student* list;//定义结构体指针list
count = ReadStudentInfo("C:\\Users\\Jungle
Chen\\Desktop\\data.txt", &list);//计算学生人数,并把文本中的数据存储到结构体中
printf("\n学生信息管理系统: \n\n");
printf("学生信息: \n");
printf("----------------------------------------------------\n");
printf("序号 姓名 学号 班级 C成绩 C实验成绩 总成绩\n");
for (m = 1; m <
count; m++)
{
printf("%2d %8s
%8s %8s %5d
%5d %5d\n", m, (list + m -
1)->name, (list + m - 1)->number, (list + m - 1)->major, (list + m -
1)->paper_sco, (list + m - 1)->test_sco, (list + m - 1)->sum);//打印学生信息
}
Count(list, count);//计算班级学生人数和平均成绩
printf("\n统计信息 :\n");
printf("----------------------------------------------------\n");
printf("序号 班级 班级学生人数 平均成绩\n");
printf("1
2017020901 %3d %3d\n", yi_per, yi_ave);
printf("2
2017020902 %3d %3d\n", er_per, er_ave);
printf("3
2017020903 %3d %3d\n", san_per, san_ave);
printf("4
2017020904 %3d %3d\n", si_per, si_ave);
printf("5
2017020905 %3d %3d\n", wu_per, wu_ave);
printf("6
2017020906 %3d %3d\n", liu_per, liu_ave);//打印统计信息
return 0;
}
void ClassFun(char* buf, char* temp, char sp);
int ReadStudentInfo(const char* filename, struct student** pStudents)
{
FILE* fp;
char row;
int i = 0, j;
fp
= fopen(filename, "r");//打开文件
//打开数据文件,失败返回-1
if (fp == NULL)
{
printf("cann't open the file");
exit(-1);
}
row
= fgetc(fp);//从文件指针fp指向的文件中读取一个字符并返回
//从头到尾扫描数据文件获得学生人数
while (row != EOF)//EOF是end
of file的意思,用来判断是否到了文件的结尾处
{
if (row == '\n')//读到回车
{
i++;//i为文件行数
}
row = fgetc(fp);//继续读取下一行
}
rewind(fp);
//将文件内部的位置指针重新指向文件的开头
row
= fgetc(fp);
*pStudents = (struct student*)malloc(sizeof(**pStudents) * i);//分配动态内存空间
char buf[512] = { 0 };//缓冲
char str[100];
fgets(str, sizeof(str), fp); //文件的第一行是无效的数据,跳过第一行
for (j = 0; j < i-1;
j++)
{
memset(*pStudents + j, 0, sizeof(struct student));//结构体初始化
fgets(buf,512, fp);//读取第j+1行的数据,遇到\n结束
int len = strlen(buf);//计算该行字符数组buf的长度
buf[len] = ' ';//该字符串后补充空格,以便下一步Cutstring作为结束标志
ClassFun(buf, (*pStudents + j)->number, ' ');//第1个‘
’前为学号
ClassFun(buf, (*pStudents + j)->name, ' ');//第2个‘
’前为姓名
char test_Score[12], paper_Score[12];
memset(test_Score, 0, 12);//初始化数组
memset(paper_Score, 0, 12);//初始化数组
ClassFun(buf, test_Score, ' ');//第3个‘
’前为实验成绩
(*pStudents + j)->test_sco = atoi(test_Score);//将实验成绩转化为整形数,赋给结构体地址(*pStudents + j)->test_sco
ClassFun(buf, paper_Score, ' ');//第4个‘
’前为卷面成绩
(*pStudents + j)->paper_sco = atoi(paper_Score);//将卷面成绩转化为整形数,赋给结构体地址(*pStudents + j)->paper_sco
(*pStudents + j)->sum = ((*pStudents +
j)->test_sco)*0.4 + ((*pStudents +
j)->paper_sco)*0.6;//计算总成绩
memcpy((*pStudents + j)->major, (*pStudents + j)->number,
10);
}
fclose(fp);//关闭文件
return (i);//返回i值,i为学生人数
}
void ClassFun(char* buf, char* temp, char sp)//函数功能:读取文本文件每一行,将数据进行分类,赋给结构体各成员
{
int len = strlen(buf);
for (int i = 0; i < len;
i++)
{
if (buf[i] == sp)
{
memcpy(buf, buf + i + 1, strlen(buf + i + 1));//若第i+1个字符为‘sp’则判断上一个字符串结束,将后面一个字符串拷贝下来覆盖buf
break;//覆盖之后跳出if语句,此时指针位置在buf[i+1]
}
temp[i] = buf[i];//将buf中的一个字符存入temp中
}
}
void Count(struct student pStudents[], int num)//函数功能:统计班级学生人数和平均成绩
{
int n = 1;
char yi[10] = "2017020901";
char er[10] = "2017020902";
char san[10] = "2017020903";
char si[10] = "2017020904";
char wu[10] = "2017020905";
char liu[10] = "2017020906"; //用于后面根据学号判断学生的班级
for (n = 1; n <= num; n++)
{
if (!strncmp((pStudents + n -
1)->major,yi,10))//比较字符串‘学号’‘班级’前十位,判断班级
{
yi_per++;//判断为1,则相应班级人数+1
yi_sum = yi_sum + (pStudents + n - 1)->sum;
yi_ave = yi_sum / yi_per; //班级平均分
}
if (!strncmp((pStudents + n -
1)->major,er,10))
{
er_per++;
er_sum = er_sum + (pStudents + n - 1)->sum;
er_ave = er_sum / er_per;
}
if (!strncmp((pStudents + n - 1)->major,
san, 10))
{
san_per++;
san_sum = san_sum + (pStudents + n - 1)->sum;
san_ave = san_sum / san_per;
}
if (!strncmp((pStudents + n - 1)->major,
si, 10))
{
si_per++;
si_sum = si_sum + (pStudents + n - 1)->sum;
si_ave = si_sum / si_per;
}
if (!strncmp((pStudents + n - 1)->major,wu, 10))
{
wu_per++;
wu_sum = wu_sum + (pStudents + n - 1)->sum;
wu_ave = wu_sum / wu_per;
}
if (!strncmp((pStudents + n - 1)->major,liu, 10))
{
liu_per++;
liu_sum = liu_sum + (pStudents + n - 1)->sum;
liu_ave = liu_sum / liu_per;
}
}
free(pStudents);//释放内存
}
代码上传格式有点问题,懒得改了