项目描述:学生成绩管理系统为教师录入成绩、管理员进行信息维护等提供方便,为学校节省大量人力资源,该系统实现对若干个大学生的学习成绩进行管理,包括学生的学号、姓名、各科成绩等。
功能要求:
1.使用中文菜单,界面设计和用户输入输出要人性化些;
2. 将学生信息保存在文本文档中,具体对学生信息进行插入删除查询操作时,将保
存在文本文档中的学生信息提取出来,保存在自己定义的数据结构中,然后再对该
数据结构进行操作,所有操作完成,或者在相应的命令后,再将学生信息保存到文
本文档中;
3.具有数据输入功能,输入的数据能最终保存在文件中;
4.具有数据删除功能,能最终从文件中删除;
5.排序功能,根据自己设计的数据结构,设计排序算法;
6.具有多种查询(如按学号查询、按姓名查询、按成绩查询等)及输出功能;
7.其它功能(如各种统计,统计每个学生所有课程的平均分,统计某门课程所有
学生的平均分等等);
8. 学生信息的修改(比如修改学生姓名,修改学生某门课程的成绩)。
一共有两个界面,第一个是登入界面,第二个是功能操作界面,如下图所示:
头文件代码如下:
#pragma once
#include
#include
#include
#include
#include
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");
}
程序运行后的结果如图所示:
如果您觉得可以的话就给我点个赞吧~