学生综合管理系统

//“linklist.h”

#pragma once		//防止头文件重复包含
 
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<conio.h>
#include<Windows.h>
#include<string.h>	
#include<graphics.h>	//图形库头文件
#include<mmsystem.h>	//音乐播放头文件
#pragma comment( lib,"winmm.lib" )	//静态库
//	学生信息定义为结构体作为,且作为单链表的数据域
 
 
struct Score				//成绩
{
	double Chinese, Math, English, Major, C, Cadd, Datastruct, History, Physics, Politics;
};
 
struct student                  //学生基本信息
{
	char name[20];				//姓名
	char birthday[20];			//出生日期
	char sex[10];				//性别
	char num[20];				//学号
	char major[30];				//系别
	char classes[20];			//班级
	char nativePlace[70];		//籍贯
	char date[20];				//入学日期
	struct Score score;
};
 
typedef struct node
{
	struct student data;	//数据域
 
	struct node* next;		//指针域
}Node, *pNode;
 
IMAGE bkImage, menuImage;	//图形变量
 
//创建表
pNode createList()
{
	pNode list = (pNode)malloc(sizeof(Node));
	if (NULL == list)	//防御措施,预防不成功的情况
	{
		return 0;
	}
	list->next = NULL;	//指向空,NULL作为链表结尾的标志
	return list;
}
 
 
 
//创建结点
pNode creatNode(struct student data)	//传入数据加到结点中
{
	pNode node = (pNode)malloc(sizeof(Node));	//malloc开辟堆内存,返回的是(void*),所以需要强转
	node->data = data;
	node->next = NULL;	//重置新的链表尾部为NULL
	return node;
}
 
 
 
/*--------------创建链表,存储数据信息-------------*/
pNode list = createList();		//头结点
 
/*
//插入结点:采用尾插法
void insertNodeByTail(pNode list, struct student data)
{
pNode newNode = creatNode(data);	//调用创建结点的函数
pNode p = list;
while (NULL != p->next)
{
p = p->next;
}
newNode->next = NULL;
p->next = newNode;
}
*/
 
 
 
void insertNodeByTail(pNode list, struct student data)
{
	pNode newNode = creatNode(data);	//调用创建结点的函数
	pNode p = list;
	while (NULL != p->next)
	{
		p = p->next;
	}
	newNode->next = NULL;
	p->next = newNode;
}
 
 
/*------------------学生管理系统的录入信息-------------*/
void addstudentInfo(pNode list)		//录入信息
{
	struct student data;
	FILE *fp = fopen("学生信息.xlsx", "r");
	fseek(fp, 8L, SEEK_SET);        // 从文件第二行开始读取
	while (!feof(fp))				//表示未到文件末尾
	{
		fscanf(fp, "%s%s%s%s%s%s%s%s", data.name, data.birthday, data.sex, data.num, data.major, data.classes, data.nativePlace, data.date);
		/*printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", data.name, data.birthday, data.sex, data.num, data.major, data.classes, data.nativePlace, data.date);*/
 
		insertNodeByTail(list, data);
	}
	fclose(fp);
}
 
 
 
//查找信息:通过num查找
pNode searchNodeByNum(pNode list, char* searchNum)
{
	pNode p = list;		//定义一个临时结点,不能用头结点直接操作,容易乱
	pNode pNext = p->next;
	while (NULL != pNext&&strcmp(pNext->data.num, searchNum))
	{									//通过遍历,比较链表中的num和要查找的num
		p = pNext;
		pNext = p->next;
	}
	if (NULL != pNext)		//判断是否找到了
	{
		return pNext;
	}
	else					//没找到
	{
		return NULL;
	}
}
 
/*----------------通过num查找信息------------*/
void searchInfoByNum()		//查找信息 
{
	putimage(0, 0, &bkImage);		//重贴背景图
	setlinecolor(RGB(249, 9, 20));
	//for (int i = 0; i < 2; i++)		//画表格
	//{
	//	rectangle(50, 50 + i * 35, 150, 85 + i * 35);
	//}
	char searchNum[20] = "";
	outtextxy(100, 52, "请输入要查找的学号:");
	int i = 0;
	int ch;
	int startX = 500;
	while (13 != (ch = _getch()))//不等于换行符
	{
		outtextxy(startX, 52, ch);
		startX += 13;	//第二个字符不能覆盖第一个
		searchNum[i++] = ch;
	}
	//字符到字符串的处理  注意'\0'
	searchNum[i] = '\0';
	if (NULL == searchNodeByNum(list, searchNum))		//没有信息
	{
		outtextxy(100, 88, "暂无信息,请添加");
		setcolor(RGB(249, 9, 20));
		outtextxy(130, 130, "请按下Enter键后回到主菜单");	 		//按下Enter键后结束
		while (13 != (ch = _getch()))
			;
		return;
	}
	else									//有信息时输出
	{
		printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", searchNodeByNum(list, searchNum)->data.name, searchNodeByNum(list, searchNum)->data.birthday, searchNodeByNum(list, searchNum)->data.sex, searchNodeByNum(list, searchNum)->data.num, searchNodeByNum(list, searchNum)->data.sex, searchNodeByNum(list, searchNum)->data.classes, searchNodeByNum(list, searchNum)->data.nativePlace, searchNodeByNum(list, searchNum)->data.date);
 
		outtextxy(100, 88, "姓名:");
		outtextxy(170, 88, searchNodeByNum(list, searchNum)->data.name);
 
		outtextxy(260, 88, "出生日期:");
		outtextxy(330, 88, searchNodeByNum(list, searchNum)->data.birthday);
 
		outtextxy(388, 88, "性别:");
		outtextxy(460, 88, searchNodeByNum(list, searchNum)->data.sex);
 
		outtextxy(550, 88, "学号:");
		outtextxy(600, 88, searchNodeByNum(list, searchNum)->data.num);
 
		outtextxy(100, 120, "系别:");
		outtextxy(170, 120, searchNodeByNum(list, searchNum)->data.sex);
 
		outtextxy(260, 120, "班级:");
		outtextxy(330, 120, searchNodeByNum(list, searchNum)->data.classes);
 
		outtextxy(388, 120, "籍贯:");
		outtextxy(460, 120, searchNodeByNum(list, searchNum)->data.nativePlace);
 
		outtextxy(550, 120, "入学日期:");
		outtextxy(600, 120, searchNodeByNum(list, searchNum)->data.date);
		//按下Enter键后返回主菜单
		setcolor(RGB(249, 9, 20));
		outtextxy(170, 130, "按下Enter键后回到主菜单");
		while (13 != (ch = _getch()))
			;
		return;
	}
}
 
//删除结点:通过num删除结点
 
int deleteNodeByNum(pNode list, char* searchNum)
{
	pNode p = list;			//临时结点,便于遍历
	pNode pNext = p->next;	//临时结点
	while (NULL != pNext&&strcmp(pNext->data.num, searchNum))
	{								//通过遍历,比较链表中的num和要查找的num
		p = pNext;
		pNext = p->next;
	}
	if (NULL == pNext)		//判断是否找到
	{
		return 0;           //返回删除失败
 
	}
	else
	{
		p->next = pNext->next;		//跨越要删除的结点
		free(pNext);		//删除结点
		return 1;			//删除成功		
	}
}
 
//删除
void deleteInfoByNum()
{
	//struct Student data;			//先查找,再删除,197~239行,为寻找过程,代码和查找一样
	putimage(0, 0, &bkImage);		//重贴背景图
	for (int i = 0; i < 2; i++)		//画表格
	{
		setlinecolor(RGB(249, 9, 20));
		rectangle(100, 50 + i * 35, 500, 85 + i * 35);
	}
	char searchNum[20];
	outtextxy(100, 52, "请输入要查找的学号:");
	int i = 0;
	int ch;
	int startX = 400;
	while (13 != (ch = _getch()))//不等于换行符
	{
		outtextxy(startX, 52, ch);
		startX += 13;	//第二个字符不能覆盖第一个
		searchNum[i++] = ch;
	}
	//字符到字符串的处理  注意'\0'
	searchNum[i] = '\0';
	if (NULL == searchNodeByNum(list, searchNum))		//没有信息
	{
		setcolor(RGB(249, 9, 20));
		outtextxy(100, 88, "暂无信息");
		outtextxy(130, 130, "请按下Enter键后回到主菜单");	 		//按下Enter键后结束
		while (13 != (ch = _getch()))
			;
		return;
 
	}
	else
	{
		outtextxy(100, 88, "姓名:");
		outtextxy(170, 88, searchNodeByNum(list, searchNum)->data.name);
 
		outtextxy(260, 88, "出生日期:");
		outtextxy(330, 88, searchNodeByNum(list, searchNum)->data.birthday);
 
		outtextxy(388, 88, "性别:");
		outtextxy(460, 88, searchNodeByNum(list, searchNum)->data.sex);
 
		outtextxy(550, 88, "学号:");
		outtextxy(600, 88, searchNodeByNum(list, searchNum)->data.num);
 
		outtextxy(100, 120, "系别:");
		outtextxy(170, 120, searchNodeByNum(list, searchNum)->data.sex);
 
		outtextxy(260, 120, "班级:");
		outtextxy(330, 120, searchNodeByNum(list, searchNum)->data.classes);
 
		outtextxy(388, 120, "籍贯:");
		outtextxy(460, 120, searchNodeByNum(list, searchNum)->data.nativePlace);
 
		outtextxy(550, 120, "入学日期:");
		outtextxy(600, 120, searchNodeByNum(list, searchNum)->data.date);
 
		//按下Enter键后返回主菜单
		setcolor(RGB(249, 9, 20));
		outtextxy(130, 130, "按下Enter键后回到主菜单");
		while (13 != (ch = _getch()))
			;
		deleteNodeByNum(list, searchNum);
		return;
 
	}
}
 
 
 
 
 
 
 
//打印结点信息
void printStudentInfo(pNode list)
{
	int ch;							//接住键盘消息
	putimage(0, 0, &bkImage);
	if (NULL == list->next)
	{
		settextcolor(RGB(249, 9, 20));
		outtextxy(100, 88, "暂无信息,请添加");
 
		//按下Enter键后返回主菜单
		outtextxy(130, 130, "请按下Enter键后回到上级菜单");
		while (13 != (ch = _getch()))
			;
		return;
	}
	else
	{
		fillrectangle(100, 50, 500, 330);
		for (int i = 0; i < 8; i++)			//画表格
		{
			setlinecolor(RGB(249, 9, 20));
			rectangle(100, 50 + i * 35, 500, 85 + i * 35);
		}
		line(233, 50, 233, 330);
		line(367, 50, 367, 330);
		setcolor(RGB(249, 9, 20));
		outtextxy(137, 53, "姓名");
		outtextxy(273, 53, "学号");
		outtextxy(400, 53, "等分");
 
		int lineWidth = 0;			//行高
		pNode p = list->next;
		setcolor(RGB(0, 104, 208));
		while (p)		//!=NULL
		{						//打印消息
			outtextxy(120, 90 + lineWidth, p->data.name);
			outtextxy(238, 90 + lineWidth, p->data.num);
			outtextxy(410, 90 + lineWidth, p->data.classes);
			p = p->next;
			lineWidth += 35;	//满了,换行
		}
		setcolor(RGB(249, 9, 20));
		outtextxy(130, 350, "按下Enter键后回到主菜单");	 		//按下Enter键后返回主菜单
		while (13 != (ch = _getch()))
			;
		return;
	}
}
 
 
 
 
 
 
 
 
 
/*----------------------窗口界面---------------------
贴图:
定义图片变量:IMAGE img;
加载图片:loadimage(&img,"图片的地址");
贴图:putimage(int x,int y,&img);//图片的长,宽,地址
*/
void studentSystemwindow()			//窗口界面
{
	loadimage(&bkImage, "bk.jpg", 900, 600);		//加载图片
	loadimage(&menuImage, "menubk.jpg", 300, 75);
	BeginBatchDraw();  //开始批量绘制 不显示
 
	//mciSendString("open 小情歌.mp3 alias bgm", NULL, NULL, NULL);		//加载音乐
	//mciSendString("play bgm repeat", NULL, NULL, NULL);                  //循环播放音乐
 
	//贴图
	putimage(0, 0, &bkImage);
	for (int i = 0; i < 4; i++)
	{
		putimage(300, 150 + 110 * i, &menuImage);
	}
	setcolor(RGB(249, 9, 20));		//用RGB设置颜色
	setbkmode(TRANSPARENT);			// 设置背景混合模式,1默认为TRANSPARENT
	settextstyle(50, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
 
	/*----------------------菜单内容--------------------*/
	outtextxy(100, 45, "北华大学学生综合测评管理系统");
	setcolor(RGB(0, 104, 208));
	settextstyle(40, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
	outtextxy(380, 170, "学生信息");
	outtextxy(420, 170 + 110 * 1, "成绩");
	outtextxy(400, 170 + 110 * 2, "创新分");
	outtextxy(380, 170 + 110 * 3, "活动奖惩");
 
	EndBatchDraw();  //结束绘制 把前面所有内容显示出来
}
 
void is_exit(pNode list)		//判断退出
{
	if (IDYES == MessageBox(NULL, "你确定退出吗?", "请按下按钮 ", MB_YESNO))
	{
		pNode p = list;				//定义两个临时结构体指针,便于释放结点内存,
		pNode q = list;				//而且让它们都指向第一个节点
		while (p != NULL)
		{
			p = p->next;
			free(q);//释放节点
			q = p;//移动q  开始下一轮循环
		}
		list = NULL;			//良好的习惯,虽然没什么卵用
 
 
		setbkcolor(WHITE);		//设置背景颜色为白色
		cleardevice();			//刷新屏幕
		setcolor(RGB(249, 9, 20));
		outtextxy(150, 150, "已保存,正在退出......");
		Sleep(2000);
		exit(0);				//直接结束程序
	}
	else
		return;
}
 
/*
模块一:  成绩管理
 
 
1)各学科成绩管理:
学生可以通过本模块查看其各个学科的成绩。
2) 活动加分管理
本模块是学生查询其参加各个活动所加的活动分记录。学生可以通过填写加分异常对自己的加分情况提出异议。
3) 体育分管理:
本模块是学生查询其体育所得的分的记录
4)综测分管理
本模块是通过对各学科分数,活动加分,体育分按一定换算公式获得的综测成绩。
综测成绩换算公式为:活动乘20% 学习75% 体育5 %= 综测成绩
 
*/
void init()
{
	MOUSEMSG m;				//鼠标变量,用于获取鼠标信息
	while (true)
	{
		m = GetMouseMsg();		//获得鼠标消息
		switch (m.uMsg)
		{
		case WM_LBUTTONDOWN:	//鼠标左键按下
			if (m.x > 300 && m.x<600 && m.y>150 && m.y < 225)//各学科成绩
			{
				BeginBatchDraw();  //开始批量绘制 不显示
				putimage(0, 0, &bkImage);
				for (int i = 0; i < 4; i++)
				{
					putimage(300, 150 + 110 * i, &menuImage);
				}
				setcolor(RGB(249, 9, 20));		//用RGB设置颜色
				setbkmode(TRANSPARENT);			// 设置背景混合模式,1默认为TRANSPARENT
				settextstyle(50, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
 
				/*----------------------成绩管理模块菜单内容--------------------*/
				setcolor(RGB(0, 104, 208));
				settextstyle(40, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
				outtextxy(380, 170, "按学号查找成绩");
				outtextxy(420, 170 + 110 * 1, "按姓名查找成绩");
				outtextxy(400, 170 + 110 * 2, "按班级浏览");
				outtextxy(380, 170 + 110 * 3, "退出");
 
				EndBatchDraw();  //结束绘制 把前面所有内容显示出来
			}
 
			break;
			if (m.x > 300 && m.x<600 && m.y>260 && m.y < 335)//活动加分
 
				break;
			if (m.x > 300 && m.x<600 && m.y>370 && m.y < 445)//体育分
 
				break;
			if (m.x > 300 && m.x<600 && m.y>480 && m.y < 555)//综测分
 
				break;
		default:
			break;
		}
	}
}
 
 
 
void initview()
{
	BeginBatchDraw();  //开始批量绘制 不显示
	putimage(0, 0, &bkImage);
	for (int i = 0; i < 4; i++)
	{
		putimage(300, 150 + 110 * i, &menuImage);
	}
	setcolor(RGB(249, 9, 20));		//用RGB设置颜色
	setbkmode(TRANSPARENT);			// 设置背景混合模式,1默认为TRANSPARENT
	settextstyle(50, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
 
	/*----------------------成绩管理模块菜单内容--------------------*/
	outtextxy(100, 45, "学生成绩管理模块");
	setcolor(RGB(0, 104, 208));
	settextstyle(40, 0, "新宋体");	// 设置当前字体样式,高30,宽0为自适应,字体为新宋体
	outtextxy(380, 170, "各学科成绩");
	outtextxy(420, 170 + 110 * 1, "活动加分");
	outtextxy(400, 170 + 110 * 2, "体育分");
	outtextxy(380, 170 + 110 * 3, "综测分");
 
	EndBatchDraw();  //结束绘制 把前面所有内容显示出来
	void init();
	MOUSEMSG m;
	while (true)
	{
		m = GetMouseMsg();		//获得鼠标消息
		switch (m.uMsg)
		{
		case WM_LBUTTONDOWN:	//鼠标左键按下
			if (m.x > 300 && m.x<600 && m.y>150 && m.y < 225)//按学号查找
			{
				searchInfoByNum();
			}
			break;
			if (m.x > 300 && m.x<600 && m.y>260 && m.y < 335)//活动加分
				studentSystemwindow();
			break;
			if (m.x > 300 && m.x<600 && m.y>370 && m.y < 445)//体育分
				rectangle(200, 500, 80, 60);
			break;
			if (m.x > 300 && m.x<600 && m.y>480 && m.y < 555)//综测分
				is_exit(list);
			break;
		default:			//其他情况
			break;
		}
	}
 
}
 
void addStudentScoe(pNode list)		//录入信息
{
	struct student data;
	putimage(0, 0, &bkImage);		//重贴背景图
	setlinecolor(RGB(249, 9, 20));
	for (int i = 0; i < 2; i++)		//画表格
	{
		rectangle(100, 50 + i * 35, 500, 85 + i * 35);
	}
	line(233, 50, 233, 120);
	line(367, 50, 367, 120);
	//长20,宽0表示自适应
	settextstyle(20, 0, "新宋体");
	outtextxy(140, 60, "语文");
	outtextxy(273, 60, "数学");
	outtextxy(406, 60, "英语");
	outtextxy(140, 110, "C语言");
	outtextxy(273, 110, "C++");
	outtextxy(406, 110, "数据结构");
	outtextxy(140, 160, "历史");
	outtextxy(273, 160, "物理");
	outtextxy(406, 160, "政治");
 
	char arr[20];
	sprintf(arr, "%lf", data.score.Chinese);
	InputBox(arr, 20, "请输入语文成绩: ");//弹出框,用于输入
	outtextxy(140, 90, data.score.Chinese);
 
	sprintf(arr, "%lf", data.score.Math);
	InputBox(arr, 20, "请输入数学成绩: ");
	outtextxy(140, 90, data.score.Math);
 
	sprintf(arr, "%lf", data.score.English);
	InputBox(arr, 20, "请输入英语成绩: ");
	outtextxy(140, 90, data.score.English);
 
	sprintf(arr, "%lf", data.score.C);
	InputBox(arr, 20, "请输入C语言成绩: ");
	outtextxy(140, 90, data.score.C);
 
	sprintf(arr, "%lf", data.score.Cadd);
	InputBox(arr, 20, "请输入C++成绩: ");
	outtextxy(140, 90, data.score.Cadd);
 
	sprintf(arr, "%lf", data.score.Datastruct);
	InputBox(arr, 20, "请输入数据结构: ");
	outtextxy(140, 90, data.score.Datastruct);
 
	sprintf(arr, "%lf", data.score.History);
	InputBox(arr, 20, "请输入历史成绩: ");
	outtextxy(140, 90, data.score.History);
 
	sprintf(arr, "%lf", data.score.Physics);
	InputBox(arr, 20, "请输入物理成绩: ");
	outtextxy(140, 90, data.score.Physics);
 
	sprintf(arr, "%lf", data.score.Politics);
	InputBox(arr, 20, "请输入政治成绩: ");
	outtextxy(140, 90, data.score.Politics);
	insertNodeByTail(list, data);	//把信息加入到链表
 
	outtextxy(180, 130, "保存中,请稍后......");//给一个假象,加强用户体验
}
 
 
 
/*----------------------用户用鼠标操作-------------------------*
 
1.定义鼠标消息	MOUSEMSG m;
2.获取鼠标消息  m=GetMouseMsg();
3.判断鼠标消息的类型	WM_LBUTTONDOWN
*/
 
void userKeyDown()
{
	MOUSEMSG m;				//鼠标变量,用于获取鼠标信息
	addstudentInfo(list);
	while (true)
	{
		m = GetMouseMsg();		//获得鼠标消息
		switch (m.uMsg)
		{
		case WM_LBUTTONDOWN:	//鼠标左键按下
			if (m.x > 300 && m.x<600 && m.y>150 && m.y < 225)//学生信息
			{
				initview();
				searchInfoByNum();
				studentSystemwindow();
			}
			break;
			if (m.x > 300 && m.x<600 && m.y>260 && m.y < 335)//成绩
				studentSystemwindow();
			break;
			if (m.x > 300 && m.x<600 && m.y>370 && m.y < 445)//创新分
				rectangle(200, 500, 80, 60);
			break;
			if (m.x > 300 && m.x<600 && m.y>480 && m.y < 555)//活动奖罚
				is_exit(list);
			break;
		default:			//其他情况
			break;
		}
	}
}
 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

淮城一只猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值