C语言编写学生成绩管理系统

大耗子 2020年06月04日 190次浏览

文章链接:https://codemouse.online/archives/2020-06-04-16-07-48

需求

用C语言编写学生成绩管理系统,要求该系统可
对学生操作:添加和删除操作。
可对3门成绩中各门成绩进行
成绩操作:录入、修改、排序、筛选、求平均分、数据保存为文件。
学生具备学号、姓名、性别和住址属性。

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 学科的编号
#define CHINESE 0
#define MATH	1
#define ENGLISH 2

#define OTHER 3

// 学生人数,暂定只能输入100个,链表可以做无数个,但是怕你看不懂
#define STUNUM	100

// 成绩结构体
typedef struct grade_t{
	int subject[3];
}Grade,*Pgrade;

// 学生信息结构体
typedef struct stu_t{
	char sno[20]; // 学号
	char name[20];// 名字
	char sex[10];// 性别
	char address[50];//地址
	Grade grade; // 成绩
}Stu,*Pstu;

// 学生信息
Pstu globleStu[STUNUM];
unsigned int current = 0; // 用来作为学生结构体的下标

// 各科成绩排行榜
int sortStuChinese[STUNUM];
int sortStuMath[STUNUM];
int sortStuEnglish[STUNUM];
int sortAll[STUNUM];
/*
用C语言编写学生成绩管理系统,要求该系统可
对学生操作:添加和删除操作。
可对3门成绩中各门成绩进行
成绩操作:录入、修改、排序、筛选、求平均分、数据保存为文件。
学生具备学号、姓名、性别和住址属性。
*/

void save(char* name)
{
	FILE *file = fopen(name, "w");
	for (int i = 0; i < current; i++)
	{
		// 写入学生信息
		fprintf(file, "%s %s %s %s ", globleStu[i]->sno, globleStu[i]->name, globleStu[i]->sex, globleStu[i]->address);
		for (int j = 0; j < 3; j++)
		{
			fprintf(file, "%d ", globleStu[i]->grade.subject[j]);
		}
		fprintf(file, "\n");
	}
	
	fclose(file);
	return;

}



// 获取这人的总分
int getGradetotal(Pstu* temp,int index){
	int sum = 0;
	for (int i = 0; i < 3; i++)
	{
		sum += temp[index]->grade.subject[i];
	}
	return sum;
}

// 选择排序哪个科目
void Sort_Select(int subject)
{
	int len = current;
	Pstu sortArr[STUNUM]; // 申请一个临时数组作为排序
	memcpy(sortArr, globleStu, sizeof(Pstu)*STUNUM);
	// 保存下标
	int arr[STUNUM];
	for (int i = 0; i < STUNUM; i++)
	{
		arr[i] = i;
	}
	if (subject == 3){
		for (int i = 0; i < len - 1; i++)
		{
			int max = i;
			for (int j = i + 1; j < len; j++)
				//判断最小值并记录
			if (getGradetotal(sortArr, max) < getGradetotal(sortArr, j))
				max = j;
			if (max != i)
			{
				Pstu temp = sortArr[max];
				sortArr[max] = sortArr[i];
				sortArr[i] = temp;
				int tempArr = arr[max];
				arr[max] = arr[i];
				arr[i] = tempArr;
			}
		}
	}
	else if (subject == 1 || subject == 0 || subject == 2){
		for (int i = 0; i < len - 1; i++)
		{
			int max = i;
			for (int j = i + 1; j < len; j++)
				//判断最小值并记录
			if (sortArr[max]->grade.subject[subject] < sortArr[j]->grade.subject[subject])
				max = j;
			if (max != i)
			{
				Pstu temp = sortArr[max];
				sortArr[max] = sortArr[i];
				sortArr[i] = temp;
				int tempArr = arr[max];
				arr[max] = arr[i];
				arr[i] = tempArr;
			}
		}
	}
	

	// 更新对应排行榜的信息
	switch (subject){
	case 0:
		memcpy(&sortStuChinese, &arr, sizeof(int)*STUNUM);
		break;
	case 1:
		memcpy(&sortStuMath, &arr, sizeof(int)*STUNUM);
		break;
	case 2:
		memcpy(&sortStuEnglish, &arr, sizeof(int)*STUNUM);
		break; 
	case 3:
		memcpy(&sortAll, &arr, sizeof(int)*STUNUM);
		break;
	}
}

// 获取某科目的平均分
double getAverage(int subject){
	double sum = 0;
	for (int i = 0; i < current; i++)
	{
		sum += globleStu[i]->grade.subject[subject];
	}
	return sum / current;
}

//index是学生下标, mode作为打印科目的选择,0是语文,1是数学,2是英语,3是全打印
void printStu(int index,int mode){
	switch (mode){
	case 0:
		printf("name:%s \t  Chinese:%3d \n",globleStu[index]->name, globleStu[index]->grade.subject[mode]);
		break;
	case 1:
		printf("name:%s \t  Math:%3d  \n", globleStu[index]->name, globleStu[index]->grade.subject[mode]);
		break;
	case 2:
		printf("name:%s \t  English:%3d \n", globleStu[index]->name, globleStu[index]->grade.subject[mode]);
		break;
	case 3:
		printf("name:%s \t  Chinese:%3d  Math:%3d  English:%3d  total:%d \n", globleStu[index]->name,
			globleStu[index]->grade.subject[CHINESE], globleStu[index]->grade.subject[MATH], globleStu[index]->grade.subject[ENGLISH], getGradetotal(globleStu,index));
		break;
	}
}

// 输出所有学生成绩
void printAllStu(){
	for (int i = 0; i < current; i++)
	{
		printStu(i, 3);
	}
}


// 打印排序的学生成绩
void printSort(int mode){
	switch (mode){
	case CHINESE:
		for (int i = 0; i < current; i++)
		{
			printStu(sortStuChinese[i], mode);
		}
		break;
	case MATH:
		for (int i = 0; i < current; i++)
		{
			printStu(sortStuMath[i], mode);
		}
		break;
	case ENGLISH:
		for (int i = 0; i < current; i++)
		{
			printStu(sortStuEnglish[i], mode);
		}
		break;
	case OTHER:
		for (int i = 0; i < current; i++)
		{
			printStu(sortAll[i], mode);
		}
		break;
	}
}


// 打印学生信息
void printAllInfo(){
	for (int i = 0; i < current; i++)
	{
		printf("sno:%s \t name:%s \t sex:%s \t address:%s \n", globleStu[i]->sno, globleStu[i]->name, globleStu[i]->sex, globleStu[i]->address);
	}
}


// 输入分数段,和要筛选的科目,筛选出学生,打印学生信息,
void selectStu(int gradeStart, int gradeEnd , int subject){
	for (int i = 0; i < current; i++)
	{
		if (globleStu[i] == NULL)
			continue;
		// 判断是否符合成绩
		if (globleStu[i]->grade.subject[subject] >= gradeStart && 
			globleStu[i]->grade.subject[subject] < gradeEnd){
			// 输出这个学生信息
			printStu(i, subject);
		}
	}
	
}


// 找到返回学生结构体的下标,没找到就返回-1
int findStu(char* sno){
	for (int i = 0; i < current; i++)
	{
		if (globleStu[i] == NULL)
			continue;
		// 找到学生
		if (!strcmp(globleStu[i]->sno, sno)){
			return i;
		}
	}
	return -1;
}

// 输入学生的成绩,传入学生的结构体指针
void inputStuGrade(Pstu stu){
	printf("请输入学生的 语文 数学 英语的成绩,用空格隔开\n");
	scanf("%d %d %d", &stu->grade.subject[CHINESE], &stu->grade.subject[MATH], &stu->grade.subject[ENGLISH]);
}

// 修改学生的成绩,传入学生的结构体指针
void updateStuGrade(Pstu stu){
	printf("修改%s同学的成绩\n",stu->name);
	inputStuGrade(stu);
	printf("成绩修改成功\n");
}

// 1成功, 0不成功
int addStuGrade(){
	printf("请输入添加成绩的同学的学号");
	char sno[20];
	scanf("%s", sno);
	int index = -1;
	if ((index = findStu(sno)) != -1){
		inputStuGrade(globleStu[index]);
		printf("输入成功\n");
		return 1;
	}
	else{
		printf("未找到该同学\n");
		return 0;
	}
}


int updateStuGrade(){
	printf("请输入修改成绩的同学的学号");
	char sno[20];
	scanf("%s", sno);
	int index = -1;
	if ((index = findStu(sno)) != -1){
		inputStuGrade(globleStu[index]);
		printf("输入成功\n");
		return 1;
	}
	else{
		printf("未找到该同学\n");
		return 0;
	}
}

// 成功返回1,失败返回0
int deleteStu(){
	printf("请输入要踢出学籍的同学的学号");
	char sno[20];
	scanf("%s", sno);
	int index = -1;
	if ((index = findStu(sno)) != -1){
		char name[20];
		memcpy(name, globleStu[index]->name, 20);
		free(globleStu[index]);
		if (index < STUNUM - 1){
			// 数据前移
			memcpy(&globleStu[index], &globleStu[index + 1], sizeof(Pstu)*(current - 1 - index));
			globleStu[current - 1] = NULL;
		}
		else{ // 如果是最后一个数据
			globleStu[index] = NULL;
		}
		printf("成功将学号为%s的%s同学移除学籍\n", sno, name);
		current--;
		return 1;
	}
	printf("未找到该学生,无法删除!!\n");
	return 0;
}


// 添加学员成功返回0,失败返回1,并及时释放内存
int addStu(){
	if (current >= STUNUM){
		printf("班级已经满员,抱歉你不能加入\n");
		return 0;
	}
	// 添加学员
	Pstu stu = (Pstu)malloc(sizeof(Stu));
	memset(stu, 0, sizeof(Stu));
	printf("请输入学员的 学号 姓名 性别 家庭住址 内容用空格分开\n");
	scanf("%s %s %s %s", stu->sno, stu->name, stu->sex, stu->address);
	globleStu[current] = stu;
	current++;
	printf("成功添加学生信息!!\n");
	return 1;
}

void main()
{
	int num = 0;
	printf("输入要录入的学员个数\n");
	scanf("%d",&num);
	for (int i = 0; i < num; i++)
	{
		addStu();
	}
	printAllInfo();

	// 添加某同学的成绩
	for (int i = 0; i < num; i++)
	{
		addStuGrade();
	}

	printAllStu();

	// 删除某同学的成绩
	deleteStu();
	printAllStu();

	// 修改
	updateStuGrade();
	printAllStu();
	// 排序
	Sort_Select(CHINESE);
	Sort_Select(MATH);
	Sort_Select(ENGLISH);
	Sort_Select(OTHER);
	// 打印排序信息
	printf("语文排行榜\n");
	printSort(CHINESE);
	printf("数学排行榜\n");
	printSort(MATH);
	printf("英语排行榜\n");
	printSort(ENGLISH);
	printf("总排行榜\n");
	printSort(OTHER);


	// 筛选学生成绩
	selectStu(60, 100, MATH);

	// 获得平均分
	double grade = getAverage(MATH);
	printf("平均分%f \n",grade);

	//保存
	save("信息.txt");
}

/*
用C语言编写学生成绩管理系统,要求该系统可
对学生操作:添加和删除操作。
可对3门成绩中各门成绩进行
成绩操作:录入、修改、排序、筛选、求平均分、数据保存为文件。
学生具备学号、姓名、性别和住址属性。
*/