linux下使用C语言实现简易的学生信息管理系统

学生管理系统的文件总共有 5 个: main.c、stuSystem.h、stuSystem.c、ArrayLib.h 和 ArrayLib.c

其中 ArrayLib.h 和 ArrayLib.c 为程序所用到的数据存储方式:动态数组。具体代码在我的另一篇博客上:C语言实现自己的动态数组库,进去里面把代码拷贝下来就得到 ArrayLib.h 和 ArrayLib.c 这两个代码文件了。

剩下的三个代码文件:main.c、stuSystem.h、stuSystem.c 就在这篇博客中,分别拷贝下来。然后把这 5 个代码文件放在同一个地方(相同的文件夹下),然后进去这个文件夹中,运行编译命令:

gcc main.c -o output

然后就得到了可执行文件 output,运行它就可以了!


main.c

/***************************************************
 * 文件名:main.c
 * 文件描述:学生管理系统框架 需要配合stuSystem.c
 * 			 stuSystem.h 以及动态数组库函数一起编译
 * 编辑人:王廷云
 * 编辑日期:2017-10-10
 * 修改日期:2018-2-10
****************************************************/

#include 
#include 
#include "stuSystem.h"
#include "arrayLib.h"

int main(void)
{
	int index = 0; 		  // 菜单功能索引
	int key;	   		  // 用户按键输入
	FILE *fp;
	Array_t *ar;
	char *mainMenu[] = {  // 菜单选项
		"1.注册学生信息",
		"2.查询学生信息",
		"3.删除学生信息",
		"4.退出管理系统",
	};
	int NR = sizeof(mainMenu)/sizeof(mainMenu[0]);// 菜单选项数

	/* 打开文件获取数据 */
	fp = fopen("./stuInfo.db", "r");
	if (NULL == fp)					// 文件不存在则创建
	{
		fp = fopen("./stuInfo.db", "w+");
	}
	if (fread(&key, 1, 1, fp) != 1)	// 如果文件为空
	{
		ar = initArray(sizeof(Student_t));
	}
	else							// 文件不为空
	{
		fclose(fp);					// 先关闭打开的文件
		ar = loadArrayFromFile("./stuInfo.db"); // 从文件中加载数据
		if (ar == NULL)
		{
			fprintf(stderr,"load info failed.\n");
			return -2;
		}
	}

	/* 初始化学生管理系统 */
	initStuSysem();
	while (1)
	{
	    /* 显示学生管理系统主菜单 */
	    showMenu(mainMenu,NR,index);

		/* 获取用户输入 */
		key = getInput();

		/* 根据用户输入进行功能选择 */
		switch (key)
		{
			/* 上移 */
			case UP    : index -= 1;
				     if (index == -1) index = NR-1; break;
			/* 下移 */
			case DOWN  : index = (index+1)%NR;   	break;
			/* 功能确认 */
			case ENTER :
				switch (index)
		     	{
				/* 注册学生信息 */
				case 0: addStuInfo(ar);    break;
				/* 查询学生信息 */
				case 1: queryStuInfo(ar);  break;
				/* 删除学生信息 */
				case 2: deleteStuInfo(ar); break;
				/* 退出学生系统 */
				case 3: exitStuSystem(ar);   break;
			}									   break;
			/* 其它按键 */
			default    : continue;
		}
	}

	return 0;
}


stuSystem.h

/********************************************
 * 文件名: stuSystem.h
 * 文件描述: 学生管理系统工程头文件,包含了该工程所有
 * 	      需要用到的枚举,结构体定义,方法函数的声明
 * 编辑人:王廷云
 * 编辑日期:2017-10-1
 * 修改日期:2018-1-10
********************************************/

#ifndef _STUSYSTEM_H_
#define _STUSYSTEM_H_

#include "arrayLib.h"

/* 用户输入按键枚举 */
enum Key_e {
	UP,		  /* 上键 */
	DOWN,	  /* 下键 */
	RIGHT,	  /* 右键 */
	LEFT,	  /* 左键 */
	ENTER,	  /* 确认键 */
	YES,	  /* 肯定键 */
	NO,		  /* 取消键 */
	QUIT,	  /* 退出键 */
	UNKNOW,	  /* 其它未知键 */
};

/* 学生结构体封装 */
typedef struct {
	int   id;       // 学生学号:id
	char  name[10]; // 学生姓名
	float grade;	// 学生成绩
} Student_t;

/* 初始化学生管理系统 */
void initStuSysem(void);

/* 显示功能选择菜单 */
void showMenu(char *menu[], int NR, int index);

/* 注册学成信息 */
void addStuInfo(Array_t *ar);

/* 查询学生信息 */
void queryStuInfo(Array_t *ar);

/* 查询所有学生信息 */
void showAllStuInfo(Array_t *ar);

/* 根据学生学号显示信息 */
void showStuInfoById(Array_t *ar);

/* 根据学生姓名显示信息 */
void showStuInfoByName(Array_t *ar);

/* 根据学生成绩显示信息 */
void showStuInfoByGrade(Array_t *ar);

/* 显示学生信息 */
void showStuInfo(void *data);

/* 退出显示学生信息界面 */
void exitStuInfo(void);

/* 用于回调的比较函数 */
/* 1、根据学号 */
int compFunById(const void *data1, const void *data2);
/* 2、根据名字 */
int compFunByName(const void *data1, const void *data2);
/* 3、根据成绩 */
int compFunByGrade(const void *data1, const void *data2);

/* 删除学生信息 */
void deleteStuInfo(Array_t *ar);

/* 删除所有学生信息 */
void deleteAllStu(Array_t *ar);

/* 根据学号删除学生信息 */
void deleteStuById(Array_t *ar);

/* 根据姓名删除学生信息 */
void deleteStuByName(Array_t *ar);

/* 根据成绩删除学生信息 */
void deleteStuByGrade(Array_t *ar);



/* 获取用户输入 */
int getInput(void);

/* 退出学生管理系统 */
void exitStuSystem(Array_t *ar);

#endif // _STUSYSTEM_H_


stySystem.c

/******************************************
 * 文件名: stuSystem.c
 * 文件描述: 学生管理系统项目里所有方法函数的实现
 * 编辑人:王廷云
 * 编辑日期:2017-10-1
 * 修改日期:2018-1-10
******************************************/

#include 
#include 
#include 
#include 
#include "stuSystem.h"
#include "arrayLib.h"

/*
 * 函数名: initStuSysem
 * 函数功能: 对学生管理系统进行初始化
 * 参数: 无
 * 返回值: 无
*/
void initStuSysem(void)
{
	/* 对终端界面进行配置 */
	fprintf(stdout, "\033[2J");	// 清屏
	system("stty -icanon");		// 关闭缓冲
	system("stty -echo");		// 关闭回显
	printf("\033[?25l");		// 隐藏鼠标光标
	fflush(stdout);				// 刷新
}

/*
 * 函数名: showMenu
 * 函数描述: 显示学生管理系统功能菜单
 * 参数: 1.菜单内容 2.菜单功能数目 3.功能索引值
 * 返回值: 无
*/
void showMenu(char *menu[], int NR, int index)
{
	int i;

	/* 屏幕设置 */
	for (i = 0; i < 100; i++)	// 清除屏幕
	{
		printf("\033[%d;1H\033[K", i);
	}
	printf("\033[1;1H");		// 定位到第一行第一列
	fflush(stdout);
	
	/* 打印菜单 */
	for (i = 0; i < NR; i++)
	{
		if (i == index)
		{
			/* 显示绿底黑字 */
			printf("\033[42;30m%s\033[0m\n",menu[i]);
		}
		else
		{
			/* 显示白底黑字 */
			printf("\033[47;30m%s\033[0m\n",menu[i]);
		}
	}
}

/*
 * 函数名: getInput
 * 函数功能: 获取用户输入
 * 参数: 无
 * 返回值: 返回用户输入对应值
*/
int getInput(void)
{
	int key;
	char ch;

	ch = getchar();
	if (ch == '\033' && getchar() == '[')   // 方向键
	{
		ch = getchar();
		switch (ch)
		{
			case 'A': key = UP;    break;
			case 'B': key = DOWN;  break;
			default : key = UNKNOW; break;
		}
	}
	else if (ch == '\n')                   // 确认键
	{
		key = ENTER;
	}
	else if (ch == 'y' && getchar() == '\n')
	{
		key = YES;
	}
	else if (ch == 'n' && getchar() == '\n')
	{
		key = NO;
	}
	else
	{
		key = UNKNOW;
	}

	return key;
}

/*
 * 函数名: addStuInfo
 * 函数功能: 注册学生信息菜单功能
 * 参数: 保存数据的数组指针
 * 返回值: 无
*/
void addStuInfo(Array_t *ar)
{
	Student_t stu;
	int key;

	/* 开启缓冲、显示和鼠标闪烁 */
	system("stty echo");
	system("stty icanon");
	printf("\033[?25h");
	fflush(stdout);
	
	/* 注册学生 */
	printf("\n******\033[34m学生信息注册\033[0m*******\n");
	fprintf(stdout,"学生学号:\033[32m ");
	fscanf(stdin,"%d",&(stu.id));
	printf("\033[0m");
	fflush(stdout);

	fprintf(stdout,"学生姓名: \033[32m");
	fscanf(stdin,"%s",(stu.name));
	printf("\033[0m");
	fflush(stdout);

	fprintf(stdout,"学生成绩: \033[32m");
	fscanf(stdin,"%f",&(stu.grade));
	printf("\033[0m");
	fflush(stdout);

	/* 确认是否录入学生注册信息 */
	getchar(); /* 去除回车符 */
	while (1)
	{
		printf("\033[34m确认是否录入学生注册信息(y/n):\033[0m");
		key = getInput();
		if (key == YES)     /* 确认注册 */
		{
			int ret;
			ret = appendArrayTail(ar,&stu);
			if (ret != 0)
			{
				fprintf(stdout,"\033[31m录入信息失败\033[0m\n");
			}
			else
			{
				fprintf(stdout,"\033[32m录入信息成功\033[0m\n");
			}
			break;
		}
		else if (key == NO) /* 取消注册 */
		{
			printf("\033[32m录入信息取消\033[0m\n");
			break;
		}
		else  /* 输入错误 */
		{
			printf("\033[31m输入错误!\033[0m\n");
			while(getchar() != '\n'); /* 去掉多余字符 */
			sleep(1);
		}
	}

	system("stty -echo");
	system("stty -icanon");
	printf("\033[?25l");
	fflush(stdout);

	sleep(1);  /* 稍等1秒 */
}

/*
 * 函数名: queryStuInfo
 * 函数功能: 查询学生信息子菜单
 * 参数: 存储数据的数组指针
 * 返回值: 无
*/
void queryStuInfo(Array_t *ar)
{
	int index = 0;
	int i;
	int key;

	/* 如果没有任何学生信息则没有必要进行下一步 */
	if (ar->n == 0)
	{
		printf("*****\033[31m没有任何注册学生信息\033[0m****\n");
		sleep(1);
		return;
	}

	char *childMenu[] = {
		"**查询所有**",
		"*按学号查询*",
		"*按名字查询*",
		"*按成绩查询*",
		"*返回主菜单*",
	};
	
	/* 计算菜单功能选项数 */
	int NR = sizeof(childMenu)/sizeof(childMenu[0]);
	
	/* 进入子菜单 */
	while (1)
	{
		showMenu(childMenu,NR,index);
		key = getInput();
		/* 根据用户输入进行功能选择 */
		switch (key)
		{
			/* 上移 */
			case UP    : index -= 1;
				     if (index == -1) index = NR-1; break;
			/* 下移 */
			case DOWN  : index = (index+1)%NR;   	break;
			/* 功能确认 */
			case ENTER :
				switch (index)
		     	{
				/* 显示所有学生信息 */
				case 0: showAllStuInfo(ar);     break;
				/* 根据学号显示学生信息 */
				case 1: showStuInfoById(ar);    break;
				/* 根据姓名显示学生信息 */
				case 2: showStuInfoByName(ar);  break;
				/* 根据成绩显示学生信息 */
				case 3: showStuInfoByGrade(ar); break;
				/* 返回上一层菜单 */
				case 4: return;
	   	    	} 									break;
			/* 其它按键 */
			case UNKNOW: continue;
		}

	}
}

/*
 * 函数名:showAllStuInfo
 * 函数功能:显示所有学生信息
 * 参数:学生信息数据指针
 * 返回值:无
*/
void showAllStuInfo(Array_t *ar)
{
	printf("\n*********以下为全部学生信息*********\n");
	travelArray(ar,showStuInfo);
	exitStuInfo();
}

/*
 * 函数名:exitStuInfo
 * 函数功能:退出显示学生信息界面
 * 参数:无
 * 返回值:无
*/
void exitStuInfo(void)
{
	int key;
	printf("***********\033[32m请按确认键返回\033[0m***********\n");

	/* 关缓冲回显和鼠标闪烁 */
	system("stty -echo");
	system("stty -icanon");
	printf("\033[?25l");
	fflush(stdout);

	while (1) /* 等待的确认键 */
	{
		key = getInput();
		if (key == ENTER)
		{
			return;
		}
	}
}

/*
 * 函数名:showStuInfoById
 * 函数功能:根据学号显示学生信息
 * 参数:学生信息数组
 * 返回值:无
*/
void showStuInfoById(Array_t *ar)
{
	void *temp;
	int id;

	/* 开启回显、缓冲和鼠标闪烁 */
	system("stty echo");
	system("stty icanon");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入学生学号:\033[32m");
	scanf("%d",&id);
	printf("\033[0m");
	fflush(stdout);
	temp = searchArrayOneByCond(ar,compFunById,&id);
	if (temp == NULL)
	{
		printf("***********\033[31m没有该学生信息\033[0m***********\n");
	}
	else
	{
		printf("***********以下为查询结果***********\n");
		showStuInfo(temp);
	}
	getchar(); /* 去掉输入id时所输入的回车符 */
	exitStuInfo();
}

/*
 * 函数名:showStuInfoByName
 * 函数功能:根据姓名显示学生信息
 * 参数:学生信息数组
 * 返回值:无
*/
void showStuInfoByName(Array_t *ar)
{
	void *temp;
	char name[10];

	system("stty echo");
	system("stty icanon");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入学生姓名:\033[32m");
	scanf("%s",name);
	printf("\033[0m");
	fflush(stdout);
	
	temp = searchArrayOneByCond(ar,compFunByName,name);
	if (temp == NULL)
	{
		printf("***********\033[31m没有该学生信息\033[0m***********\n");
	}
	else
	{
		printf("***********以下为查询结果***********\n");
		showStuInfo(temp);
	}
	getchar(); /* 去掉输入name时所输入的回车符 */
	exitStuInfo();
}

/*
 * 函数名:showStuInfoByGrade
 * 函数功能:根据成绩显示学生信息
 * 参数:学生信息数组
 * 返回值:无
*/
void showStuInfoByGrade(Array_t *ar)
{
	void *temp;
	float grade;

	system("stty echo");
	system("stty icanon");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入学生成绩:\033[32m");
	scanf("%f",&grade);
	printf("\033[0m");
	fflush(stdout);
	
	temp = searchArrayOneByCond(ar,compFunByGrade,&grade);
	if (temp == NULL)
	{
		printf("***********\033[31m没有该学生信息\033[0m***********\n");
	}
	else
	{
		printf("***********以下为查询结果***********\n");
		showStuInfo(temp);
	}
	getchar(); /* 去掉输入grade时所输入的回车符 */
	exitStuInfo();
}

/*
 * 函数名:showStuInfo
 * 函数功能:显示学生信息
 * 参数:数据地址指针
 * 返回值:无
*/
void showStuInfo(void *data)
{
	Student_t *stu;
	stu = (Student_t *)data;
	printf("id: \033[32m%03d\033[0m name: \033[32m%-6s" \
	             "\033[0m grade: \033[32m%.2f\033[0m\n",\
	                      stu->id,stu->name,stu->grade);
}

/*
 * 函数名:compFunById
 * 函数功能:比较回调函数,根据条件比较结果
 * 参数:需要比较的两个数据指针
 * 返回值:无
*/
int compFunById(const void *data1, const void *data2)
{
	Student_t *stu = (Student_t *)data1;
	if (stu->id == *(int *)data2)
	{
		return 1;
	}
	else
		return 0;
}

/*
 * 函数名:compFunByIdName
 * 函数功能:比较回调函数,根据条件比较结果
 * 参数:需要比较的两个数据指针
 * 返回值:无
*/
int compFunByName(const void *data1, const void *data2)
{
	Student_t *stu = (Student_t *)data1;
	if (strcmp(stu->name,(char*)data2) == 0)
	{
		return 1;
	}
	else
		return 0;
}

/*
 * 函数名:compFunByGrade
 * 函数功能:比较回调函数,根据条件比较结果
 * 参数:需要比较的两个数据指针
 * 返回值:无
*/
int compFunByGrade(const void *data1, const void *data2)
{
	Student_t *stu = (Student_t *)data1;
	if (stu->grade == *(float *)data2)
	{
		return 1;
	}
	else
		return 0;
}

/*
 * 函数名: deleteStuInfo
 * 函数功能: 删除学生信息
 * 参数: 1.子菜单的行坐标 2.子菜单的列坐标
 * 返回值: 无
*/
void deleteStuInfo(Array_t *ar)
{
	int index = 0;
	int i;
	int key;

	/* 如果没有任何学生信息则没有必要进行下一步 */
	if (ar->n == 0)
	{
		printf("*****\033[31m没有任何注册学生信息\033[0m****\n");
		sleep(1);
		return;
	}

	char *childMenu[] = {
		"**删除所有**",
		"*按学号删除*",
		"*按名字删除*",
		"*按成绩删除*",
		"*返回主菜单*",
	};
	
	int NR = sizeof(childMenu)/sizeof(childMenu[0]);
	
	while (1)
	{
		showMenu(childMenu,NR,index);
		key = getInput();
		/* 根据用户输入进行功能选择 */
		switch (key)
		{
			/* 上移 */
			case UP    : index -= 1;
				     if (index == -1) index = NR-1; break;
			/* 下移 */
			case DOWN  : index = (index+1)%NR;   break;
			/* 功能确认 */
			case ENTER : switch (index)
				     	{
							case 0: deleteAllStu(ar);    break;
							case 1: deleteStuById(ar);   break;
							case 2: deleteStuByName(ar); break;
							case 3: deleteStuByGrade(ar);break;
							case 4: return;
			   	    	} break;
			/* 其它按键 */
			case UNKNOW: continue;
		}
	}
}

/*
 * 函数名:deleteAllStu
 * 函数功能:删除所有学生信息
 * 参数:存储数据的数组指针
 * 返回值:无
*/
void deleteAllStu(Array_t *ar)
{
	int key;			// 用户输入按键
	int sum = ar->n;	// 学生总数
	int i, ret;

	system("stty icanon");
	system("stty echo");
	printf("\033[?25h");
	fflush(stdout);

	printf("\033[31m是否确定要删除所有学生信息(y/n):\033[0m");
	key = getInput();
	if (key == YES)
	{	
		for (i = 0; i < sum; i++)
		{
			ret = deleteArrayByIndex(ar, 0);
			if (ret != 0)
			{
				printf("***********\033[31m删除失败,请重试\033[0m**********\n");
				exitStuInfo();
			}
		}
		printf("\033[32m成功删除所有学生信息\033[0m\n");
		exitStuInfo();
	}
	else if (key == NO)
	{
		printf("*************\033[32m删除已取消\033[0m*************\n");
		exitStuInfo();
	}
}

/*
 * 函数名:deleteStuById
 * 函数功能:根据学号删除学生信息
 * 参数:存储数据的数组指针
 * 返回值:无
*/
void deleteStuById(Array_t *ar)
{
	int key;
	int id;
	void *temp;

	system("stty icanon");
	system("stty echo");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入要删除学生的学号:\033[32m");
	scanf("%d",&id);
	printf("\033[0m");
	fflush(stdout);
	getchar(); /* 去掉回车符 */
	temp = searchArrayOneByCond(ar,compFunById,&id);
	if (temp == NULL)
	{
		printf("\033[31m没有该学生\033[0m\n");
		exitStuInfo();
		return;
	}
	printf("\033[31m是否确定要删除该学生信息(y/n):\033[0m");
	key = getInput();
	if (key == YES)
	{
		int ret;
		ret = deleteArrayOneByCond(ar,compFunById,&id);
		if (ret != 0)
		{
			printf("***********\033[31m删除失败,请重试\033[0m**********\n");
			exitStuInfo();
			return;
		}
		printf("\033[32m成功删除该学生信息\033[0m\n");
		exitStuInfo();
	}
	else if (key == NO)
	{
		printf("*************\033[32m删除已取消\033[0m*************\n");
		exitStuInfo();
	}
}

/*
 * 函数名:deleteStuByName
 * 函数功能:根据姓名删除学生信息
 * 参数:存储数据的数组指针
 * 返回值:无
*/
void deleteStuByName(Array_t *ar)
{
	int key;
	char name[10];
	void *temp;

	system("stty icanon");
	system("stty echo");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入要删除学生的姓名:\033[32m");
	scanf("%s",name);
	printf("\033[0m");
	fflush(stdout);
	getchar(); /* 去掉回车符 */
	temp = searchArrayOneByCond(ar,compFunByName,name);
	if (temp == NULL)
	{
		printf("\033[31m没有该学生\033[0m\n");
		exitStuInfo();
		return;
	}
	printf("\033[31m是否确定要删除该学生信息(y/n):\033[0m");
	key = getInput();
	if (key == YES)
	{
		int ret;
		ret = deleteArrayOneByCond(ar,compFunByName,name);
		if (ret != 0)
		{
			printf("***********\033[31m删除失败,请重试\033[0m**********\n");
			exitStuInfo();
		}
		printf("\033[32m成功删除该学生信息\033[0m\n");
		exitStuInfo();
	}
	else if (key == NO)
	{
		printf("*************\033[32m删除已取消\033[0m*************\n");
		exitStuInfo();
	}
}

/*
 * 函数名:deleteStuByGrade
 * 函数功能:根据成绩删除学生信息
 * 参数:存储数据的数组指针
 * 返回值:无
*/
void deleteStuByGrade(Array_t *ar)
{
	int key;
	float grade;
	void *temp;

	system("stty icanon");
	system("stty echo");
	printf("\033[?25h");
	fflush(stdout);

	printf("请输入要删除学生的成绩:\033[32m");
	scanf("%f",&grade);
	printf("\033[0m");
	fflush(stdout);
	getchar(); /* 去掉回车符 */
	temp = searchArrayOneByCond(ar,compFunByGrade,&grade);
	if (temp == NULL)
	{
		printf("\033[31m没有该学生\033[0m\n");
		exitStuInfo();
		return;
	}
	printf("\033[31m是否确定要删除该学生信息(y/n):\033[0m");
	key = getInput();
	if (key == YES)
	{
		int ret;
		ret = deleteArrayOneByCond(ar,compFunByGrade,&grade);
		if (ret != 0)
		{
			printf("***********\033[31m删除失败,请重试\033[0m**********\n");
			exitStuInfo();
		}
		printf("\033[32m成功删除该学生信息\033[0m\n");
		exitStuInfo();
	}
	else if (key == NO)
	{
		printf("*************\033[32m删除已取消\033[0m*************\n");
		exitStuInfo();
	}
}



/*
 * 函数名: exitStuSystem
 * 函数功能: 退出学生管理系统前进行一些终端配置
 * 参数: 无
 * 返回值: 无
*/
void exitStuSystem(Array_t *ar)
{
	char ch;

	/* 恢复终端配置 */
	system("stty icanon");	// 恢复缓冲
	system("stty echo");	// 恢复回显示
	printf("\033[?25h");	// 显示鼠标
	fflush(stdout);			// 刷新

	/* 询问是否保存修改 */
	fprintf(stdout, "是否保存修改?(y/n):");
	ch = getchar();
	if (ch == 'y')	// 确认保存
	{
		saveArrayToFile(ar, "stuInfo.db");
	}

	exit(0);				// 退出程序
}

你可能感兴趣的:(C语言实例)