话不多说先上源码,一会有哪些bug我再给你们一一叙述
#include
#include
#include
#include
#include
//课程信息
typedef struct _Course
{
int num;//课程编号
char name[20]; //课程名称
int item[1000]; //完成相应试题获得的分值
}Course;
//链表
typedef struct _Nodes
{
Course cor;
struct _Nodes* pNexts;
}Nodes;
Nodes* g_pHeads = NULL; //初始化头节点
//学生信息
typedef struct _Student
{
char name[20];// 姓名
int age; //年龄
int stuNum;//学号
double score=0;//成绩
}Student;
//链表(车厢)
typedef struct _Node
{
Student stu; //学生
struct _Node* pNext;//指向下一个节点的指针
}Node;
//头结点
Node* g_pHead = NULL; //头结点
void Welcome();
void InputStudent(); //录入学生信息
void PrintStudent(); //打印学生信息
void SaveStudent(); //保存学生信息
void ReadStudent(); //读取学生信息
int CountStudent(); //统计所有学生人数
Node* FindStudent(); //查找学生
void ModifyStudent(); //修改学生信息
void DeleteStudent(); //删除学生信息
void InputCourse(); //新增课程新增试题
void UpdataScore(); //更新学生积分
void Order(); //排序学生积分
void DeleteTest(); //删除试题
//主函数
int main() {
while (1) {
Welcome();
char ch = getch();//可以暂停一下循环,从键盘输入一个数字
switch (ch) {
case '1':InputStudent(); break;//输入1录入学生信息
case '2':PrintStudent(); break;//输入2打印学生信息
case '3':SaveStudent(); break;//输入3保存学生信息
case '4':ReadStudent(); break;//输入4读取学生信息
case '5':printf("学生总人数为:%d\n", CountStudent()); system("pause"); system("cls"); break;//输入5统计学生总人数
case '6'://输入6查找学生信息
{
system("pause");//画面停留
//清屏
system("cls");
Node* p = FindStudent();
if (p != NULL)
printf("学号: %d\t姓名: %s\t年龄: %d\t成绩: %.0f\n", p->stu.stuNum, p->stu.name, p->stu.age,p->stu.score );
else
printf("没有找到该学生\n");
; system("pause");
system("cls");
break;
}
case '7':ModifyStudent(); break;//修改学生信息
case '8':DeleteStudent(); break;//删除学生信息
case '0':printf("谢谢使用!!\n"); return 0; //退出管理系统
case 'a':InputCourse(); break;//新增课程新增试题
case 'c':UpdataScore(); break;//更新学生积分
case 'd':Order(); break; //排序学生积分
case 'e':DeleteTest(); break; //删除试题
default:printf("非法数据\n"); system("pause"); system("cls"); break;
}
}
return 0;
}
//封面
void Welcome()
{
printf("-----------------------------------------------------\n");
printf("-- 欢迎使用学生管理平台(超级无敌牛逼版vol.3) --\n");
printf("-----------------------------------------------------\n");
printf("-- 请选择功能列表 --\n");
printf("-----------------------------------------------------\n");
printf("-- 1.录入学生信息 a.新增课程 --\n");
printf("-- 2.打印学生信息 新增试题 --\n");
printf("-- 3.保存学生信息 c.更新积分 --\n");
printf("-- 4.读取学生信息 d.排序功能 --\n");
printf("-- 5.统计学生总数 e.删除试题 --\n");
printf("-- 6.查找学生信息 --\n");
printf("-- 7.修改学生信息 --\n");
printf("-- 8.删除学生信息 --\n");
printf("-- 0.退出管理系统 --\n");
printf("-----------------------------------------------------\n");
}
//新增试题
void InputCourse()
{
int a;//定义试题个数
//创建新节点
Nodes* pNewNodes = (Nodes*)malloc(sizeof(Nodes));
pNewNodes->pNexts = NULL;
//头插
if (g_pHeads == NULL) //无头
{
g_pHeads = pNewNodes; //定义头
}
else
{
pNewNodes->pNexts = g_pHeads; //从pNexts里抽出数据赋给头
g_pHeads = pNewNodes;
}
printf("请输入课程编号:\n");
scanf("%d", &pNewNodes->cor.num);
printf("请输入课程名称:\n");
scanf("%s", pNewNodes->cor.name);
printf("请输入试题个数\n");
scanf("%d", &a);
for (int i = 1; i <= a; i++) {
printf("请输入完成第%d道试题加多少分:\n",i);
scanf("%d", &pNewNodes->cor.item[i]);
}
//保存题目
FILE* fps = fopen("C:\\Users\\ROG\\Desktop\\作业\\学生管理系统平台vol.3\\test.dat", "w");//以写文件的形式打开文件
if (fps == NULL)
{
printf("打开文件失败.\n");
return;
}
//遍历链表
Nodes* p = g_pHeads;
while (p != NULL)
{
//写文件
fwrite(&p->cor, 1, sizeof(Course), fps);
p = p->pNexts;
}
//关闭文件
fclose(fps);
printf("课程录入成功\n");
system("pause");//画面停留
//清屏
system("cls");
}
//录入学生信息
void InputStudent() {
char charge; //准备打印学生信息
//创建一个新节点
Node* pNewNode = (Node*)malloc(sizeof(Node));
pNewNode->pNext = NULL;
//头插法,尾插法
//头插法
if (g_pHead == NULL) //没有头
{
g_pHead = pNewNode; //定义一个头
}
else
{
pNewNode->pNext = g_pHead;
g_pHead = pNewNode;
}
printf("请输入学生姓名:\n");
scanf("%s", pNewNode->stu.name);
printf("请输入学生的年龄:\n");
scanf("%d", &pNewNode->stu.age);
printf("请输入学生的学号:\n");
scanf("%d", &pNewNode->stu.stuNum);
printf("请输入学生的成绩:\n");
scanf("%lf", &pNewNode->stu.score);
printf("学生信息录入成功\n");
system("pause");//画面停留
//清屏
system("cls");
}
void PrintStudent() //打印学生信息
{
system("cls");
printf("-----------------------------------------------------——---------------\n");
printf("-- 欢迎使用学生管理平台(超级无敌牛逼版vol.3) --\n");
printf("------------------------------------------------------------------------\n");
printf("-- -学号- -姓名- -年龄- -成绩- -等级- -积分 --\n");
printf("------------------------------------------------------------------------\n");
//遍历链表
Node* p = g_pHead;
while (p != NULL)//只要节点不到头就一直往下打印
{
printf("-- -%d- -%s- -%d- -%.0lf- -%.0lf- -%.0lf- --\n",
p->stu.stuNum,
p->stu.name,
p->stu.age,
p->stu.score,
floor(log10(p->stu.score+1)),
p->stu.score);
p = p->pNext;
}
system("pause");//画面停留
//清屏
system("cls");
}
//保存学生信息
void SaveStudent()
{
//打开文件,利用文件指针
FILE* fp = fopen("C:\\Users\\ROG\\Desktop\\作业\\学生管理系统平台vol.3\\stuinfo.dat", "w");//以写文件的形式打开文件
if (fp == NULL)
{
printf("打开文件失败.\n");
return;
}
//遍历链表
Node* p = g_pHead;
while (p != NULL)
{
//写文件
fwrite(&p->stu, 1, sizeof(Student), fp);
p = p->pNext;
}
//关闭文件
fclose(fp);
printf("\n数据保存成功\n");
system("pause");//画面停留
//清屏
system("cls");
}
//读取学生和题库信息
void ReadStudent()
{
//打开文件
FILE* fps= fopen("C:\\Users\\ROG\\Desktop\\作业\\学生管理系统平台vol.3\\test.dat", "r"); //读取题库
FILE* fp = fopen("C:\\Users\\ROG\\Desktop\\作业\\学生管理系统平台vol.3\\stuinfo.dat", "r"); //读取学生
if (fp == NULL||fps==NULL)
{
printf("打开文件失败\n");
return;
}
//读文件
Course cor;
Student stu;
while (fread(&stu, 1, sizeof(Student), fp)) //如果读到的文件不是末尾继续读
{
//创建一个新节点
Node* pNewNode = (Node*)malloc(sizeof(Node));
pNewNode->pNext = NULL;
memcpy(pNewNode, &stu, sizeof(Student));
//头插法
if (g_pHead == NULL) //没有头
{
g_pHead = pNewNode; //定义一个头
}
else
{
pNewNode->pNext = g_pHead;
g_pHead = pNewNode;
}
}
while (fread(&cor, 1, sizeof(Course), fps)) //如果读到的文件不是末尾继续读
{
//创建一个新节点
Nodes* pNewNodes = (Nodes*)malloc(sizeof(Nodes));
pNewNodes->pNexts = NULL;
memcpy(pNewNodes, &cor, sizeof(Course));
//头插法
if (g_pHeads == NULL) //没有头
{
g_pHeads = pNewNodes; //定义一个头
}
else
{
pNewNodes->pNexts = g_pHeads;
g_pHeads = pNewNodes;
}
}
//关闭文件
fclose(fp);
fclose(fps);
printf("加载数据成功.\n");
system("pause");//画面停留
//清屏
system("cls");
}
//统计学生人数
int CountStudent()
{
int nCount = 0;//学生总数
//遍历链表
Node* p = g_pHead;
while (p != NULL)
{
nCount++;
p = p->pNext;
}
return nCount;
}
//查找学生
Node* FindStudent() {
int nStuNum;
char szName[20];
printf("请输入要查找的学生的学号:\n");
scanf("%d", &nStuNum);
printf("请输入要查找的学生的姓名:\n");
scanf("%s", szName);
Node* p = g_pHead;
while (p != NULL)
{
//strcmp字符串比较函数
if (p->stu.stuNum == nStuNum || 0 == strcmp(p->stu.name, szName))
return p;
p = p->pNext;
}
//没有找到
return NULL;
}
//排序学生积分
void Order()
{
struct _Student temp;
Node* p = g_pHead; //遍历链表
while (p != NULL)
{
while (p->pNext != NULL)
{
if (p->stu.score > p->pNext->stu.score)
{
temp=p->stu;
p->stu = p->pNext->stu;
p->pNext->stu = temp;
}
}
p = p->pNext;
}
printf("排序成功\n");
system("pause");//画面停留
//清屏
system("cls");
return;
}
//更新学生积分
void UpdataScore()
{
int StuNum;
int num;
printf("请输入需要更新的学生的学号:\n");//先查到该学生
scanf("%d", &StuNum);
//遍历链表
Node* p = g_pHead;
Nodes* ps = g_pHeads;
while (p != NULL)
{
if (p->stu.stuNum == StuNum)
{
while (ps != NULL) {
printf("请输入该学生做对了多少到%s题:\n", ps->cor.name);
scanf("%d", &num);
for (int i = 1; i <= num; i++)
{
p->stu.score += ps->cor.item[i];
}
ps = ps->pNexts;
}
printf("修改成功\n");
break;
}
p = p->pNext;
}
if (p == NULL)
{
printf("没有找到该学生的信息\n");
}
system("pause"); //画面停留
system("cls"); //清屏
}
//修改学生信息
void ModifyStudent()
{
int nStuNum;
printf("请输入需要修改学生信息的学号:\n");
scanf("%d", &nStuNum);
Node* p = g_pHead;
while (p != NULL)
{
if (p->stu.stuNum == nStuNum)
{
printf("请输入要修改的学生的姓名 年龄 成绩:\n");
scanf("%s %d %lf", p->stu.name, &p->stu.age, &p->stu.score);
printf("修改成功\n");
break;
}
p = p->pNext;
}
if (p == NULL)
{
printf("没有找到该学生的信息\n");
}
system("pause"); //画面停留
system("cls"); //清屏
}
//删除试题
void DeleteTest()
{
int nTestNum;
printf("请输入要删除的试题的课程编号:\n");
scanf("%d", &nTestNum);
Nodes* p1;
//判断是否为头节点
if (g_pHeads->cor.num == nTestNum) //如果对应的节点等于要删除的课程编号
{
p1 = g_pHeads; //备份
g_pHeads = g_pHeads -> pNexts;
free(p1); //释放
return;
}
//不是头节点
Nodes* p = g_pHeads;
Nodes* p2; //备份
while(p->pNexts!=NULL)
{
if (p->pNexts->cor.num == nTestNum)
{
p2 = p->pNexts; //备份
p->pNexts = p->pNexts->pNexts;
free(p2);
printf("删除成功\n");
system("pause");//画面停留
//清屏
system("cls");
return;
}
p = p->pNexts;
if (p->pNexts == NULL)
{
break;
}
}
if (p->pNexts == NULL)
{
printf("未找到该题目\n");
}
system("pause");//画面停留
//清屏
system("cls");
}
//删除学生信息
void DeleteStudent()
{
int nStuNum;
printf("请输入要删除学生的学号:\n");
scanf("%d", &nStuNum);
Node* p1;
//判断是不是头节点
if (g_pHead->stu.stuNum == nStuNum) //如果头节点等于删除学生的学号
{
p1 = g_pHead; //备份一下头
g_pHead = g_pHead->pNext;
free(p1); //释放内存即可删除学生信息
return;
}
//不是头节点
Node* p = g_pHead;
Node* p2; //备份的
while (p->pNext != NULL)
{
if (p->pNext->stu.stuNum == nStuNum)
{
p2 = p->pNext;
p->pNext = p->pNext->pNext;
free(p2); //释放内存
system("pause");//画面停留
//清屏
system("cls");
return;
}
p = p->pNext;
if (p->pNext == NULL) //如果节点到了尾部跳出
{
break;
}
}
if (p->pNext == NULL) //如果从到到尾都没有找到
{
printf("没有找到该学生\n");
}
system("pause");//画面停留
//清屏
system("cls");
}
经过我的一下午测试,我发现了一个bug,就是第d.个功能,这个排序的,我目前的水平还不能写出来链表排序,但是我把代码放上去,如果想要追求完美的朋友们,可以试着修复一下我这个bug,首先是bug源码
//学生信息
typedef struct _Student
{
char name[20];// 姓名
int age; //年龄
int stuNum;//学号
double score=0;//成绩
}Student;
//链表(车厢)
typedef struct _Node
{
Student stu; //学生
struct _Node* pNext;//指向下一个节点的指针
}Node;
//头结点
Node* g_pHead = NULL; //头结点
//排序学生积分
void Order()
{
struct _Student temp;
Node* p = g_pHead; //遍历链表
while (p != NULL)
{
while (p->pNext != NULL)
{
if (p->stu.score > p->pNext->stu.score)
{
temp=p->stu;
p->stu = p->pNext->stu;
p->pNext->stu = temp;
}
}
p = p->pNext;
}
printf("排序成功\n");
system("pause");//画面停留
//清屏
system("cls");
return;
}
先说一下运行这个bug之后,只能将 123 排序成 321 ,如果一乱就陷入死循环了,其实只要按一下那个d键就会出现死循环,所以这个功能还得小心点使用,如果为了美观那就把这个功能删掉吧,这个排序我是实在做不出来了,但是我还是希望能有知识渊博的人来指导一下我,之后我会放上测试过程与图片
//
首先测试第一个内容
第二个内容
第三个和第四个内容就是保存到一个文件里然后再使用的系统的时候记得先读取才能显示你之前录取的学生,这里不再展示
第五个内容
第六个内容
第七个内容
第八个内容
这里强调一下,新增试题的时候记得把课程名称设置成**简单,**普通,这样以便于后面的删除课题,不然你这么一删,直接把一个课程的所有试题都给删了,目前我的水平还做不到单独删除一道题,所以只能委屈一下大家了,例如我新增语文题,肯定得分难易度吧,课程编号1为 语文简单,给3个题,一题2分,然后课程编号2为 语文普通,给3个题,一题两分,这样才能说的过去。
第十个内容
第十一个内容有bug,有bug,有bug,这里无法展示,运行了会陷入死循环
第十二个内容
删除之后再次选择更新积分就没有这一试题了 。
好了,说完了,欢迎大家参考学习,欢迎大家修复我的那个排序函数的bug,如果能完善这个程序,那就@我一下,或者给我发私信,我随时在线,毕竟追求完美嘛~~