数据结构课设——学生成绩管理系统

项目描述:学生成绩管理系统为教师录入成绩、管理员进行信息维护等提供方便,为学校节省大量人力资源,该系统实现对若干个大学生的学习成绩进行管理,包括学生的学号、姓名、各科成绩等。

功能要求: 

1.使用中文菜单,界面设计和用户输入输出要人性化些;

2. 将学生信息保存在文本文档中,具体对学生信息进行插入删除查询操作时,将保

存在文本文档中的学生信息提取出来,保存在自己定义的数据结构中,然后再对该

数据结构进行操作,所有操作完成,或者在相应的命令后,再将学生信息保存到文

本文档中;

3.具有数据输入功能,输入的数据能最终保存在文件中;

4.具有数据删除功能,能最终从文件中删除;

5.排序功能,根据自己设计的数据结构,设计排序算法;

6.具有多种查询(如按学号查询、按姓名查询、按成绩查询等)及输出功能;

7.其它功能(如各种统计,统计每个学生所有课程的平均分,统计某门课程所有

学生的平均分等等);

8.  学生信息的修改(比如修改学生姓名,修改学生某门课程的成绩)。

一共有两个界面,第一个是登入界面,第二个是功能操作界面,如下图所示:

头文件代码如下:

#pragma once
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include <string.h>
#include<ctype.h>

void createHeadNode();
void createUserHeadNode();
void createDeleteHeadNode();

//读取学生数据
void initData(struct node* phead);
//读取用户的登入 判断用户的账号是否正确
void initDataUser(struct unode* uhead);

void Menu2();
void Menu();
//录入学生信息
void InputStudent(struct node* phead);
//删除学生信息
void DeleteStudent(struct node* phead);
//查找学生
void SearchStudent(struct node* phead);
//修改学生成绩
void UpdataStudent(struct node* phead);
//打印学生信息
void PrintStudent(struct node* phead);
void info_output(struct node* pfind);
//学成成绩排序(出现两个排序表 总分排序表、平均分排序表)
void SortStudent1(struct node* phead);
void SortStudent2(struct node* phead);

//写入学生信息
void FushData(struct node* phead);
//写入用户的注册
void FushDataUser(struct unode* uhead);


//找到需要的学生地址
struct node* findTheStudent(struct node* phead, int sid);
struct unode* findTheUser(struct unode* uhead, int fkey, int fname);
struct unode* findTheUser(struct unode* uhead, int uname);


//删除记录
void Dlenode(struct node* dhead,int did);
void FushDeleteRecord(struct node* dhead);
void initDataDeleteRecord(struct node* dhead);

//登入
void inputuser(struct unode* uhead);

//注册
void Code(struct unode* uhead);


//定义一个学生
struct student
{
	int sid;
	char  name[20];
	float discrete;   //离散成绩
	float linear;     //代数成绩
	float gaoshu;     //高数成绩
	float ave;        //平均分
	float total;      //总分
};


//链表结点
struct node
{
	student stu;//链表中存学生
	struct node* pnext;//指向下一个结点的指针
};
//定义头结点
struct node* phead = NULL;
int count = 0;//用来记录当前文件中数据的条数
struct node* dhead = NULL;


//使用者
struct user
{
	int uname;
	int key;

};
//链表存储用户信息
struct unode
{
	user use;
	struct unode* unext;
};
struct unode* uhead = NULL;
int countuser = 0;//记录当前系统的使用人数

int drecord = 0;

源文件代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include"StudentMangerSystem.h"
int main() {
	createHeadNode();
	createUserHeadNode();
	createDeleteHeadNode();
	Menu2();
	return 0;
}


void createHeadNode() {
	phead = (struct node*)malloc(sizeof(struct node));
	if (!phead) {
		printf("头结点分配失败!\n");
		return;
	}
	phead->pnext = NULL;//现在头结点只有一个,即使头结点也是尾结点,所以设置为空
}
//用户结点的创建
void createUserHeadNode() {
	uhead = (struct unode*)malloc(sizeof(struct unode));
	if (!uhead) {
		printf("用户的头结点分配失败!\n");
		return;
	}
	uhead->unext = NULL;
}

//删除记录结点的创建
void createDeleteHeadNode() {
	dhead = (struct node*)malloc(sizeof(struct node));
	if (!dhead) {
		printf("删除记录的头结点分配失败!\n");
		return;
	}
	dhead->pnext = NULL;//现在头结点只有一个,即使头结点也是尾结点,所以设置为空
}

//从文件中读取学生数据到程序中
void initData(struct node* phead) {
	FILE* fp = NULL;//文件指针
	struct node* pnew = NULL;//用来接收数据 每当程序读一条数据 就初始化一个结点拿来装
	struct node* pfind = phead;
	fp = fopen("student.txt", "r");//把文件中的内容读到代码中
	if (fp == NULL) {
		printf("文件打开失败!");
		exit(0);
	}
	//将数据格式化写入结点中
	while (1) {
		pnew = (struct node*)malloc(sizeof(struct node));
		//格式化数据
		fscanf(fp, "%d%s%f%f%f%f%f",
			&pnew->stu.sid,
			pnew->stu.name,
			&pnew->stu.discrete,
			&pnew->stu.linear,
			&pnew->stu.gaoshu,
			&pnew->stu.total,
			&pnew->stu.ave);
		pnew->pnext = NULL;//这是新的节点 新节点的pnext赋值为空
		//用feof函数来判断fp指针是否指到了末尾  如果指到末尾就会返回1否则返回0
		if (feof(fp)) {
			break;
		}
		count++;
		//把新的结点接到尾结点的后面
		pfind->pnext = pnew;
		pfind = pfind->pnext;
	}
}

void Menu2() {
	int u = 0;
	initDataUser(uhead);
	printf("当前系统中有%d位使用者\n", countuser);
	printf("*************************\n");
	printf("****学生成绩管理系统*****\n");
	printf("*************************\n");
	printf("********登入界面*********\n");
	printf("*\t1、登入\t\n");
	printf("*\t2、注册\t\n");
	printf("*\t3、退出\t\n");
	printf("*************************\n");
	while (1) {
		printf("请选择您的操作:\n");
		scanf("%d", &u);
		switch (u)
		{
		case 1://登入
			inputuser(uhead);
			break;
		case 2://注册
			Code(uhead);
			FushDataUser(uhead);//存档用户数据
			break;
		case 3://退出系统
			printf("欢迎下次使用!\n");
			exit(0);
			break;
		default:
			printf("您的操作有误!\n");
			break;
		}
	}
}
void Menu() {
	int a = 0;
	initData(phead);
	printf("当前文件中有%d位学生\n", count);
	printf("*********************************\n");
	printf("*\t学生成绩管理系统\t*\n");
	printf("*********************************\n");
	printf("*\t   操作列表\t\t*\n");
	printf("*********************************\n");
	printf("*\t1、添加学生信息\t\t*\n");
	printf("*\t2、删除学生信息\t\t*\n");
	printf("*\t3、查找学生信息\t\t*\n");
	printf("*\t4、修改学生信息\t\t*\n");
	printf("*\t5、显示所有学生\t\t*\n");
	printf("*\t6、排序学生成绩\t\t*\n");
	printf("*\t7、存档学生信息\t\t*\n");
	printf("*\t8、查看删除记录\t\t*\n");
	printf("*\t0、退出系统\t\t*\n");
	printf("*********************************\n");

	while (1) {
		printf("请选择您的操作:");
		scanf("%d", &a);
		switch (a) {
		case 1://录入学生信息
			InputStudent(phead);
			break;
		case 2://删除学生信息
			DeleteStudent(phead);
			break;
		case 3://查找学生信息
			SearchStudent(phead);
			break;
		case 4://修改学生信息
			UpdataStudent(phead);
			break;
		case 5://显示学生信息
			PrintStudent(phead);
			break;
		case 6://排序学生成绩
			SortStudent1(phead);
			SortStudent2(phead);
			break;
		case 7://存档学生信息
			FushData(phead);
			break;
		case 8://查看删除记录
			initDataDeleteRecord(dhead);
			break;
		case 0://退出系统
			printf("欢迎下次使用!\n");
			exit(0);
			break;
		default:
			printf("操作有误!请重新输入!\n");
			break;
		}
	}

}


void InputStudent(struct node* phead) {
	struct node* pnew = NULL;
	struct node* pfind = phead;
	while (pfind->pnext != NULL) {
		pfind = pfind->pnext;

	}
	pnew = (struct node*)malloc(sizeof(struct node));

	pnew->stu.total = 0;
	pnew->stu.ave = 0;

	printf("学号:\n");//判断学号是否有重复的
	scanf("%d", &pnew->stu.sid);
	while (findTheStudent(phead, pnew->stu.sid)) {
		printf("学号不能重复!请重新输入:\n");
		scanf("%d", &pnew->stu.sid);
	}


	printf("姓名:\n");
	scanf("%s", pnew->stu.name);

	printf("离散成绩:\n");
	scanf("%f", &pnew->stu.discrete);
	while (pnew->stu.discrete < 0 || pnew->stu.discrete>150) {
		printf("您输入的成绩有误!请重新输入:\n");
		printf("离散成绩:\n");
		scanf("%f", &pnew->stu.discrete);
	}

	pnew->stu.total += pnew->stu.discrete;

	printf("代数成绩:\n");
	scanf("%f", &pnew->stu.linear);
	while (pnew->stu.linear < 0 || pnew->stu.linear>150) {
		printf("您输入的成绩有误!请重新输入:\n");
		printf("代数成绩:\n");
		scanf("%f", &pnew->stu.linear);
	}
	pnew->stu.total += pnew->stu.linear;

	printf("高数成绩:\n");
	scanf("%f", &pnew->stu.gaoshu);
	while (pnew->stu.gaoshu < 0 || pnew->stu.gaoshu>150) {
		printf("您输入的成绩有误!请重新输入:\n");
		printf("高数成绩:\n");
		scanf("%f", &pnew->stu.gaoshu);
	}
	pnew->stu.total += pnew->stu.gaoshu;

	pnew->stu.ave = pnew->stu.total / 3.0;

	pnew->pnext = NULL;
	pfind->pnext = pnew;

	printf("录入成功!\n\n");

}

//用户注册
void Code(struct unode* uhead) {
	struct unode* pnew = NULL;
	struct unode* pfind = uhead;

	while (pfind->unext != NULL) {
		pfind = pfind->unext;

	}
	pnew = (struct unode*)malloc(sizeof(struct unode));

	printf("请输入数字用户名:");
	scanf("%d", &pnew->use.uname);
	while (findTheUser(uhead, pnew->use.uname)) {
		printf("用户名重复!请重新输入:\n");
		scanf("%d", &pnew->use.uname);
	}
	printf("\n");

	printf("请输入整数密码:");
	scanf("%d", &pnew->use.key);
	printf("\n");

	pnew->unext = NULL;
	pfind->unext = pnew;

	printf("注册成功!请您前往登入!\n");
}

//开辟新的结点保存被删除的那个学生的信息---------删除记录
void Dlenode(struct node* dhead,int did) {
	struct node* pnew = NULL;
	struct node* pfind = dhead;
	while (pfind->pnext != NULL) {
		pfind = pfind->pnext;

	}
	pnew = (struct node*)malloc(sizeof(struct node));
	struct node* target = NULL;
	target=findTheStudent(phead, did);

	/*pnew->stu.sid = dhead->stu.sid;
	strcpy(pnew->stu.name, dhead->stu.name);
	pnew->stu.discrete = dhead->stu.discrete;
	pnew->stu.linear = dhead->stu.linear;
	pnew->stu.gaoshu = dhead->stu.gaoshu;
	pnew->stu.total = dhead->stu.total;
	pnew->stu.ave = dhead->stu.ave;*/
	pnew->stu.sid = target->stu.sid;
	strcpy(pnew->stu.name, target->stu.name);
	pnew->stu.discrete = target->stu.discrete;
	pnew->stu.linear = target->stu.linear;
	pnew->stu.gaoshu = target->stu.gaoshu;
	pnew->stu.total = target->stu.total;
	pnew->stu.ave = target->stu.ave;


	pnew->pnext = NULL;
	pfind->pnext = pnew;

	//写入删除记录文件中
	FushDeleteRecord(dhead);
}

//从文件中读取用户数据  在登入的时候使用
void initDataUser(struct unode* uhead) {
	FILE* up = NULL;
	struct unode* pnew = NULL;
	struct unode* pfind = uhead;
	up = fopen("user.txt", "r");
	if (up == NULL) {
		printf("用户的文件打开失败!");
		exit(0);
	}
	//将数据格式化写入结点中
	while (1) {
		pnew = (struct unode*)malloc(sizeof(struct unode));
		//格式化数据
		fscanf(up, "%d%d", &pnew->use.uname, &pnew->use.key);
		pnew->unext = NULL;
		if (feof(up)) {
			break;
		}
		countuser++;
		pfind->unext = pnew;
		pfind = pfind->unext;
	}

}
//用户登入  判断用户输入的用户名和密码

void inputuser(struct unode* uhead) {
	//从文件中读取用户数据
	int fkey;
	int fname;
	struct unode* target = NULL;

	printf("请输入用户名:");
	scanf("%d", &fname);

	printf("请输入密码:");
	scanf("%d", &fkey);

	target = findTheUser(uhead, fkey, fname);
	if (target == NULL) {
		printf("没有这个用户!\n");
		return;
	}
	else {
		system("cls");
		Menu();
	}

}

//判断用户输入的是否存在
struct unode* findTheUser(struct unode* uhead, int fkey, int fname) {
	struct unode* pfind = uhead;
	while (pfind != NULL) {
		if (pfind->use.key == fkey && pfind->use.uname == fname) {
			return pfind;
		}
		pfind = pfind->unext;
	}
	return pfind;
}

void DeleteStudent(struct node* phead) {
	int id = 0;
	struct node* target = NULL;
	struct node* pfind = phead;
	struct node* ptemp = NULL;//用来装想要删除的那个的后面的地址
	printf("请输入您想删除学生的学号:");
	scanf("%d", &id);
	target = findTheStudent(phead, id);
	if (target == NULL) {
		printf("查无此人!\n");
		return;
	}
	else {
		//将要删除的学生保存在新的结点中
		Dlenode(dhead,id);
		ptemp = target->pnext;
		while (pfind->pnext != target) {
			pfind = pfind->pnext;//循环结束 得到的是上一个的地址
		}
		free(target);//释放要删除的那个的空间
		target = NULL;//只是释放了结点的内存  指针依旧存在 
		pfind->pnext = ptemp;
		printf("删除成功!\n");
	}
}

//在文件中写入删除记录
void FushDeleteRecord(struct node* dhead) {
	FILE* fp = NULL;
	struct node* pfind = dhead->pnext;
	fp = fopen("deleterecord.txt", "w");
	while (pfind != NULL) {
		fprintf(fp, "%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", pfind->stu.sid, pfind->stu.name, pfind->stu.discrete, pfind->stu.linear, pfind->stu.gaoshu, pfind->stu.total, pfind->stu.ave);
		pfind = pfind->pnext;
	}
}

//从文件中读取删除记录,把删除记录显示出来(在第八个选项中用到)
void initDataDeleteRecord(struct node* dhead) {
	FILE* fp = NULL;
	struct node* pnew = NULL;
	struct node* pfind = dhead;
	fp = fopen("deleterecord.txt", "r");
	if (fp == NULL) {
		printf("删除记录的文件打开失败!");
		exit(0);
	}
	while (1) {
		pnew = (struct node*)malloc(sizeof(struct node));
		fscanf(fp, "%d%s%f%f%f%f%f", &pnew->stu.sid, pnew->stu.name, &pnew->stu.discrete, &pnew->stu.linear, &pnew->stu.gaoshu, &pnew->stu.total, &pnew->stu.ave);
		pnew->pnext = NULL;
		if (feof(fp)) {
			break;
		}
		drecord++;

		pfind->pnext = pnew;
		pfind = pfind->pnext;
	}
	//从新的结点中打印学生数据
	//printf("当前文件中共有%d条删除记录\n", drecord);
	printf("删除记录如下:\n");
	//打印
	PrintStudent(dhead);
}

void SearchStudent(struct node* phead) {
	int id;
	struct node* target = NULL;//用来接收返回值
	printf("请输入您要查找学生的学号:");
	scanf("%d", &id);
	target = findTheStudent(phead, id);
	if (target == NULL) {
		printf("查无此人!\n");
	}
	else {
		info_output(target);
	}
}

void UpdataStudent(struct node* phead) {
	int id;
	struct node* target = NULL;//用来接收返回值
	printf("请输入您要修改学生的学号:");
	scanf("%d", &id);
	target = findTheStudent(phead, id);
	if (target == NULL) {
		printf("查无此人!\n");
	}
	else {
		target->stu.total = 0;
		target->stu.ave = 0;
		printf("离散成绩:\n");
		scanf("%f", &target->stu.discrete);
		target->stu.total += target->stu.discrete;

		printf("代数成绩:\n");
		scanf("%f", &target->stu.linear);
		target->stu.total += target->stu.linear;

		printf("高数成绩:\n");
		scanf("%f", &target->stu.gaoshu);
		target->stu.total += target->stu.gaoshu;

		target->stu.ave = target->stu.total / 3.0;

		printf("修改成功!");
		info_output(target);
	}
}

void PrintStudent(struct node* phead) {
	struct node* pfind = phead->pnext;
	printf("*******************************************************************************************\n");
	while (pfind != NULL) {
		info_output(pfind);
		pfind = pfind->pnext;
	}
	printf("*******************************************************************************************\n\n");

}
void info_output(struct node* pfind) {

	printf("*学号:%d\t姓名:%s\t离散:%.2f\t线代:%.2f\t高数:%.2f\t总分:%.2f\t平均分:%.2f\n",
		pfind->stu.sid, pfind->stu.name, pfind->stu.discrete, pfind->stu.linear, pfind->stu.gaoshu,
		pfind->stu.total, pfind->stu.ave);
}

void SortStudent1(struct node* phead) {//根据选择排序   按照总分排序
	struct node* pfind1 = phead->pnext;
	struct node* pfind2 = phead->pnext;
	float max;
	struct node* p = NULL;
	student replace;//初始化一个结构体变量 用来储存数据 因为要交换 所以要有一个中间的来装原来的
	while (pfind1 != NULL) {
		max = pfind1->stu.total;
		p = pfind1;
		for (pfind2 = pfind1->pnext; pfind2 != NULL; pfind2 = pfind2->pnext)//pfind2总是指向pfind1的下一个结点
		{
			if (max < pfind2->stu.total) {
				max = pfind2->stu.total;
				p = pfind2;
			}
		}
		p->stu.total = pfind1->stu.total;
		pfind1->stu.total = max;

		//交换学号
		replace.sid = p->stu.sid;
		p->stu.sid = pfind1->stu.sid;
		pfind1->stu.sid = replace.sid;
		//交换姓名
		strcpy(replace.name, p->stu.name);
		strcpy(p->stu.name, pfind1->stu.name);
		strcpy(pfind1->stu.name, replace.name);
		//交换离散成绩
		replace.discrete = p->stu.discrete;
		p->stu.discrete = pfind1->stu.discrete;
		pfind1->stu.discrete = replace.discrete;
		//交换现代成绩
		replace.linear = p->stu.linear;
		p->stu.linear = pfind1->stu.linear;
		pfind1->stu.linear = replace.linear;
		//交换高数成绩
		replace.gaoshu = p->stu.gaoshu;
		p->stu.gaoshu = pfind1->stu.gaoshu;
		pfind1->stu.gaoshu = replace.gaoshu;
		//交换平均分
		replace.ave = p->stu.ave;
		p->stu.ave = pfind1->stu.ave;
		pfind1->stu.ave = replace.ave;

		pfind1 = pfind1->pnext;
	}
	printf("总分排序表:\n");
	PrintStudent(phead);
	printf("\n");

}
void SortStudent2(struct node* phead) {//按照平均分排序
	struct node* pfind1 = phead->pnext;
	struct node* pfind2 = phead->pnext;
	float max;
	struct node* p = NULL;
	student replace;
	while (pfind1 != NULL) {
		max = pfind1->stu.ave;
		p = pfind1;
		for (pfind2 = pfind1->pnext; pfind2 != NULL; pfind2 = pfind2->pnext)
		{
			if (max < pfind2->stu.ave) {
				max = pfind2->stu.ave;
				p = pfind2;
			}
		}
		p->stu.ave = pfind1->stu.ave;
		pfind1->stu.ave = max;

		//交换学号
		replace.sid = p->stu.sid;
		p->stu.sid = pfind1->stu.sid;
		pfind1->stu.sid = replace.sid;
		//交换姓名
		strcpy(replace.name, p->stu.name);
		strcpy(p->stu.name, pfind1->stu.name);
		strcpy(pfind1->stu.name, replace.name);
		//交换离散成绩
		replace.discrete = p->stu.discrete;
		p->stu.discrete = pfind1->stu.discrete;
		pfind1->stu.discrete = replace.discrete;
		//交换现代成绩
		replace.linear = p->stu.linear;
		p->stu.linear = pfind1->stu.linear;
		pfind1->stu.linear = replace.linear;
		//交换高数成绩
		replace.gaoshu = p->stu.gaoshu;
		p->stu.gaoshu = pfind1->stu.gaoshu;
		pfind1->stu.gaoshu = replace.gaoshu;
		//交换总分
		replace.total = p->stu.total;
		p->stu.total = pfind1->stu.total;
		pfind1->stu.total = replace.total;

		pfind1 = pfind1->pnext;
	}
	printf("平均分排序表:\n");
	PrintStudent(phead);
	printf("\n");
}

struct node* findTheStudent(struct node* phead, int id) {
	struct node* pfind = phead;
	while (pfind != NULL) {
		if (pfind->stu.sid == id) {
			return pfind;
		}
		pfind = pfind->pnext;
	}
	return pfind;
}
//注册时输入的用户名不能重复
struct unode* findTheUser(struct unode* uhead, int uname) {
	struct unode* pfind = uhead;
	while (pfind != NULL) {
		if (pfind->use.uname == uname) {
			return pfind;
		}
		pfind = pfind->unext;
	}
	return pfind;
}

void FushData(struct node* phead) {
	FILE* fp = NULL;
	struct node* pfind = phead->pnext;
	fp = fopen("student.txt", "w");
	while (pfind != NULL) {
		fprintf(fp, "%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", pfind->stu.sid, pfind->stu.name, pfind->stu.discrete, pfind->stu.linear, pfind->stu.gaoshu, pfind->stu.total, pfind->stu.ave);
		pfind = pfind->pnext;
	}
	printf("学生数据保存成功!\n");
}
//写入用户的注册  在注册的时候使用
void FushDataUser(struct unode* uhead) {

	FILE* up = NULL;
	struct unode* pfind = uhead->unext;
	up = fopen("user.txt", "w");
	while (pfind != NULL) {
		fprintf(up, "%d\t%d\t\n", pfind->use.uname, pfind->use.key);
		pfind = pfind->unext;
	}
	printf("注册成功!\n");
}

 程序运行后的结果如图所示:

 如果您觉得可以的话就给我点个赞吧~

 

版权声明:本文为博主作者:MayMarch原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/MayMarch/article/details/127729475

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年1月3日
下一篇 2024年1月3日

相关推荐