【开发细节】用C语言基础写学生管理系统(四)

前情回顾


自定义kernel_list.h头文件。作用:提供顺序线性表的相关操作方法

一、本次目标


构建学生信息浏览系统,实现相关功能

图片名称 GitHub:https://github.com/ITchujian/StudentManagementSystem_2022_C

注:为方便分享本次开发的经历,我把分析过程以及代码书写过程,以文字、图片形式合计放于开发记录中,但是一些非常基础的行为动作我将不会讲解或者阐述。
当前位置:【开发细节】用C语言基础写学生管理系统(四)
可跳转:

二、开发记录


步骤1

创建头文件sysbrowse.h
在这里插入图片描述
引入自定义头文件kernel_list.h`。

#include "kernel_list.h"

步骤2

因为这里属于学生管理系统中的信息浏览系统
在这里插入图片描述
所以,我们应该先做一个控制台打印的菜单,我们将采用制表符打印,这样看起来会更好看一点,正好这里我共享一下常用的制表符:

// 第一套
┌ ┬ ┐
├ ┼ ┤
└ ┴ ┘
// 第二套
┏ ┳ ┓
┣ ╋ ┫
┗ ┻ ┛
// 第三套
╔ ╦ ╗
╠ ╬ ╣
╚ ╩ ╝
// 第四套
╭ ─ ╮
│ ╳ ┃
╰ ━ ╯

对了,这里我们需要改变一下VS2022中的字体,单击工具>选项
在这里插入图片描述
在这里插入图片描述
设置成Consolas等宽字体。
在这里插入图片描述
不过VS中这样设置依然没有达到我的需求:直接通过代码编辑的界面,调整制表符的嵌合度。幸好我有Code:Blocks,不然得多次打印,多次调整,就有点脑溢血。在Code:Blocks中,依然设置上述字体,然后就会发现
在这里插入图片描述
啊这🤣未免太美好了吧,相比之下,VS2022:
在这里插入图片描述
好吧,没关系的,这不影响大局,这一段代码就这样写吧。

Status browseMenu(void)
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃                            【副】信 息 浏 览 系 统                            ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃请选择操作:                                                                    ┃\n");
	printf("┃                             1 > 查看所有学生信息                              ┃\n");
	printf("┃                             2 > 根据学号搜索学生                              ┃\n");
	printf("┃                             3 > 排序学生信息                                  ┃\n");
	printf("┃                             4 > 名次查询学生                                  ┃\n");
	printf("┃                             5 > 一键统计所有信息                              ┃\n");
	printf("┃                             0 > 返回主系统                                    ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	printf("\nINPUT:");
	return OK;
}

步骤3

实现功能1,浏览所有学生的信息,那就得设法打印我们学生信息表中的数据,而且还要保持一定的格式。
暂且就通过循环来解决吧,通过多次尝试,以下格式化打印后还算不错的🥰

Status putAllList(SqList* L)
{
	int i = 0;
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  姓名        学号        性别        年龄        语文        数学        英语        平均分        总分   ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	while (i < L->length)
	{
		printf("┃  %-9s%-16d%-12s%-11d%-12.2f%-12.2f%-12.2f%-13.2f%-8.2f┃\n", (L->elem[i]).name, (L->elem[i]).num, (L->elem[i]).sex, (L->elem[i]).age, (L->elem[i]).score_literature, (L->elem[i]).score_math, (L->elem[i]).score_english, (L->elem[i]).average_score, (L->elem[i]).sum_score);
		++i;
	}
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	return OK;
}

步骤4

实现功能2,根据学号搜索学生。我多次强调了学号的唯一性,不可重复的,它是每一个学生的特定标识,那这里肯定只需要根据学号,搜索到学生后,输出一行该学生的所有信息即可,那我们就可以借用上面的函数putAllList(SqList* L),毕竟它已经被调校好了格式。

Status putSingleList(ElemType* e)
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  姓名        学号        性别        年龄        语文        数学        英语        平均分        总分   ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃  %-9s%-16d%-12s%-11d%-12.2f%-12.2f%-12.2f%-13.2f%-8.2f┃\n", e->name, e->num, e->sex, e->age, e->score_literature, e->score_math, e->score_english, e->average_score, e->sum_score);
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	return OK;
}

而打印单行信息前的搜索,直接使用我们在kernel_list.h头文件中写好的方法SearchElem(SqList* L, int cur_e, ElemType* e, int mode_manner),搜索到学号后,将搜索的信息传给e,然后通过单行打印e的数据内容。

步骤5

实现功能3,排序,这里不用多说,也是通过调用kernel_list.h头文件中写好的方法ListSort(SqList* L, int sort_manner, char key),到时候在SMS_2022.cpp中调整函数参数即可。

步骤6

实现功能4,名次查询学生。
这里就比较简单了,如果我要查询总分正数第二名,那么就先对数据项总分进行降序排序,然后根据kernel_list.h头文件中的方法Status GetElem(SqList* L, int i, ElemType* e)获取第二个元素,然后进行单行打印。

Status rankSearch(SqList* L, int sort_manner, char key, int i, ElemType* e)
{
	if (key != 'l' && key != 'm' && key != 'e' && key != 'a' && key != 's')
		return ERROR;
	ListSort(L, sort_manner, key);
	GetElem(L, i, e);
	putSingleList(e);
	return OK;
}

步骤7

实现功能5,统计学生信息,这里依据需求来说,我们先定义5个函数(用于比较分数)
寻找语文、数学、英语的及格人数,寻找平均分、总分达到一定分数的人数。

Status passLiterature(ElemType a, ElemType b)
{
	if (a.score_literature <= b.score_literature)
		return OK;
	else
		return 0;
}

Status passMath(ElemType a, ElemType b)
{
	if (a.score_math <= b.score_math)
		return OK;
	else
		return 0;
}

Status passEnglish(ElemType a, ElemType b)
{
	if (a.score_english <= b.score_english)
		return OK;
	else
		return 0;
}

Status compAveScore(ElemType a, ElemType b)
{
	if (a.average_score <= b.average_score)
		return OK;
	else
		return 0;
}

Status compSumScore(ElemType a, ElemType b)
{
	if (a.sum_score <= b.sum_score)
		return OK;
	else
		return 0;
}

定义一个函数,统计男女各有多少人:

Status countSex(SqList* L)
{
	char boy[4] = "男";
	int boy_count = 0, girl_count = 0;
	for (int i = 0; i < L->length; ++i)
		if (strcmp(boy, (L->elem)[i].sex))
			++girl_count;
		else
			++boy_count;
	printf("男同学:%d\n女同学:%d\n", boy_count, girl_count);
	return OK;
}

然后定义一个总统计的数组,到时候在SMS_2022.cpp中调用

Status statistic(SqList* L, float* compScore)
{
	// L是传入函数的线性表,comScore表示对应的比较分数的数组,如{60, 60, 60, 60, 180}
	return OK;
}

statistic函数中统计学生总人数:

printf("当前学生总人数:%d\n", L->length);

然后定义一个数组,用于表示:语文、数学、英语、平均分、总分

char key[5] = { 'l', 'm', 'e', 'a', 's' };

再去申请一块动态内存空间,其类型是ElemType*,使用它来存储float* compScore对应的比较分数

ElemType* r = (ElemType*)malloc(sizeof(ElemType));
	if (r == NULL)
		exit(INFEASIBLE);
r->sum_score = *(compScore + 4);
r->average_score = *(compScore + 3);
r->score_english = *(compScore + 2);
r->score_math = *(compScore + 1);
r->score_literature = *(compScore + 0);

然后通过for循环,调用kernel_list.h头文件中的方法LocateElem(SqList* L, ElemType* e, Status(*compare)(ElemType, ElemType)),可以理解这个函数就是个条件筛选器,不断的通过上方定义的比较分数的函数,再略加的修改,就达到我们了的预期效果。

for (int i = 0, sort_manner = 1; i < 5; ++i)
	{
		ListSort(L, sort_manner, key[i]);
		switch (i)
		{
		case 0:
			printf("语文及格的人数有:%d\n", L->length - LocateElem(L, r, passLiterature) + 1);
			break;
		case 1:
			printf("数学及格的人数有:%d\n", L->length - LocateElem(L, r, passMath) + 1);
			break;
		case 2:
			printf("英语及格的人数有:%d\n", L->length - LocateElem(L, r, passEnglish) + 1);
			break;
		case 3:
			printf("平均分达到及格线的有:%d人\n", L->length - LocateElem(L, r, compAveScore) + 1);
			break;
		case 4:
			printf("总分达到%.2f的有:%d人\n", *(compScore + 4), L->length - LocateElem(L, r, compSumScore) + 1);
			break;
		}
	}

对了,别忘记在statistic方法中调用countSex(SqList* L)函数,实行男女人数统计,然后释放r的内存空间。

countSex(L);
free(r);

到此我们的sysbrowse.h编写完毕。

sysbrowse.hの完整代码:

#pragma once
/*********************************************************************
 * 转载请注明来源/Reprint please indicate the source
 * @FileName sysbrowse.h
 * @Description 学生信息浏览系统/Student Information Browsing System
 * @History
 * version      author      data       introduction and operations
 *  1.0         初见     2022-01-22             Create
 *  ***         ***      ****-**-**             *******
 */

#include "kernel_list.h"
 /*********************************************************************
  * @chujian(cn) 引入自定义头文件
  * @chujian(en) Import custom header files
  */

Status browseMenu(void)
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃                            【副】信 息 浏 览 系 统                            ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃请选择操作:                                                                    ┃\n");
	printf("┃                             1 > 查看所有学生信息                              ┃\n");
	printf("┃                             2 > 根据学号搜索学生                              ┃\n");
	printf("┃                             3 > 排序学生信息                                  ┃\n");
	printf("┃                             4 > 名次查询学生                                  ┃\n");
	printf("┃                             5 > 一键统计所有信息                              ┃\n");
	printf("┃                             0 > 返回主系统                                    ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	printf("\nINPUT:");
	return OK;
}
/*********************************************************************
 * @chujian(cn) 信息浏览系统
 * @chujian(en) Information browsing system
 */

Status putAllList(SqList* L)
{
	int i = 0;
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  姓名        学号        性别        年龄        语文        数学        英语        平均分        总分   ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	while (i < L->length)
	{
		printf("┃  %-9s%-16d%-12s%-11d%-12.2f%-12.2f%-12.2f%-13.2f%-8.2f┃\n", (L->elem[i]).name, (L->elem[i]).num, (L->elem[i]).sex, (L->elem[i]).age, (L->elem[i]).score_literature, (L->elem[i]).score_math, (L->elem[i]).score_english, (L->elem[i]).average_score, (L->elem[i]).sum_score);
		++i;
	}
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	return OK;
}
/*********************************************************************
 * @chujian(cn) 打印表内全部信息
 * @chujian(en) Print all the information in the form
 */

Status putSingleList(ElemType* e)
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃  姓名        学号        性别        年龄        语文        数学        英语        平均分        总分   ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃  %-9s%-16d%-12s%-11d%-12.2f%-12.2f%-12.2f%-13.2f%-8.2f┃\n", e->name, e->num, e->sex, e->age, e->score_literature, e->score_math, e->score_english, e->average_score, e->sum_score);
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	return OK;
}
/*********************************************************************
 * @chujian(cn) 打印表内单行信息
 * @chujian(en) Print a single row of information in the table
 */

Status rankSearch(SqList* L, int sort_manner, char key, int i, ElemType* e)
{
	if (key != 'l' && key != 'm' && key != 'e' && key != 'a' && key != 's')
		return ERROR;
	ListSort(L, sort_manner, key);
	GetElem(L, i, e);
	putSingleList(e);
	return OK;
}
/*********************************************************************
 * @chujian(cn) 名次查询引擎
 * @chujian(en) Ranking query engine
 */

Status passLiterature(ElemType a, ElemType b)
{
	if (a.score_literature <= b.score_literature)
		return OK;
	else
		return 0;
}

Status passMath(ElemType a, ElemType b)
{
	if (a.score_math <= b.score_math)
		return OK;
	else
		return 0;
}

Status passEnglish(ElemType a, ElemType b)
{
	if (a.score_english <= b.score_english)
		return OK;
	else
		return 0;
}

Status compAveScore(ElemType a, ElemType b)
{
	if (a.average_score <= b.average_score)
		return OK;
	else
		return 0;
}

Status compSumScore(ElemType a, ElemType b)
{
	if (a.sum_score <= b.sum_score)
		return OK;
	else
		return 0;
}

Status countSex(SqList* L)
{
	char boy[4] = "男";
	int boy_count = 0, girl_count = 0;
	for (int i = 0; i < L->length; ++i)
		if (strcmp(boy, (L->elem)[i].sex))
			++girl_count;
		else
			++boy_count;
	printf("男同学:%d\n女同学:%d\n", boy_count, girl_count);
	return OK;
}

Status statistic(SqList* L, float* compScore)
{
	printf("当前学生总人数:%d\n", L->length);
	char key[5] = { 'l', 'm', 'e', 'a', 's' };
	ElemType* r = (ElemType*)malloc(sizeof(ElemType));
	if (r == NULL)
		exit(INFEASIBLE);
	r->sum_score = *(compScore + 4);
	r->average_score = *(compScore + 3);
	r->score_english = *(compScore + 2);
	r->score_math = *(compScore + 1);
	r->score_literature = *(compScore + 0);
	for (int i = 0, sort_manner = 1; i < 5; ++i)
	{
		ListSort(L, sort_manner, key[i]);
		switch (i)
		{
		case 0:
			printf("语文及格的人数有:%d\n", L->length - LocateElem(L, r, passLiterature) + 1);
			break;
		case 1:
			printf("数学及格的人数有:%d\n", L->length - LocateElem(L, r, passMath) + 1);
			break;
		case 2:
			printf("英语及格的人数有:%d\n", L->length - LocateElem(L, r, passEnglish) + 1);
			break;
		case 3:
			printf("平均分达到及格线的有:%d人\n", L->length - LocateElem(L, r, compAveScore) + 1);
			break;
		case 4:
			printf("总分达到%.2f的有:%d人\n", *(compScore + 4), L->length - LocateElem(L, r, compSumScore) + 1);
			break;
		}
	}
	countSex(L);
	free(r);
	return OK;
}
/*********************************************************************
 * @chujian(cn) 学生信息统计
 * @chujian(en) Student Information Statistics
 */

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顾平安6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值