运行效果

在这里插入图片描述

main.cpp

/* ===================================成绩管理程序===================================
 * 注意:
 * 连续按三次ctrl z可以返回上一级菜单
 * 请按照正常顺序,一级一级退出,不要直接点击右上角关闭程序。否则,data.txt可能没有完全写入
 * 想即时保存也行,每次操作完成之后加一句writeData(&phead, &ptail);即可
 * 你可以直接在txt中进行修改成绩操作,且不必输入总分、平均分,但一定要保证:格式正确
 *
 * txt存储格式如下:
 * 总人数
 * 学号 姓名 班级 数学 英语 政治 体育 物理 总分 平均分
 *
 * 新增功能:
 * 1、首页动态效果
 * 2、模式选择功能【学生模式、教师模式、开发者模式】模式不同,权限不同。
 *    开发者具有所有权限,可自动生成学号不重复的学生及成绩,方便做测试使用。
 *    模式选择菜单下,如果输入数字非法,则默认无任何权限。
 *==================================================================================*/

#include"list.c"
#include"sort.c"
#include"read.c"
#include"write.c"
int main()
{
	srand((int)time(NULL));//产生随机数的种子 
	int i;

	pstu phead = NULL;
	pstu ptail = NULL;

	readData(&phead, &ptail);
	//更新数据(若用户直接操作txt文件,该函数可以自动计算新的总分、平均分)
	update(&phead, &ptail);

	//选择模式
	int mode;
	bool valid[7] = { false };

label1:
	mode = chooseMode();
	switch (mode)
	{	
	case 1:valid[0] = false; valid[1] = false; valid[2] = false; valid[3] = true; valid[4] = true; valid[5] = true; valid[6] = false; break;
	case 2:valid[0] = true; valid[1] = true; valid[2] = true; valid[3] = true; valid[4] = true; valid[5] = true; valid[6] = false; break;
	case 3:valid[0] = true; valid[1] = true; valid[2] = true; valid[3] = true; valid[4] = true; valid[5] = true; valid[6] = true; break;
	}


	//选择操作
	int choose;
	while (printHome(), printf("\n请输入你选择的操作:"), scanf("%d", &choose) != EOF)
	{
		rewind(stdin);

		//判断当前模式下权限
		system("cls");
		switch (valid[choose - 1])
		{
		case true:break;
		case false:
		{
			printf("对不起,当前模式下您没有访问权限,请切换模式!");
			system("pause");
			goto label1;
		}
		}

		system("cls");
		switch (choose)
		{
		case 1://while (system("cls"), list_print(phead, ptail), printf("(三次ctrl z返回上一级)\n请输入要添加的学号:"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				list_insert_sort(&phead, &ptail, i);
			}
			writeData(&phead, &ptail);
			break;
		case 2://while (system("cls"), list_print(phead, ptail), printf("(三次ctrl z返回上一级)\n请输入删除的学号:"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				list_delete(&phead, &ptail, i);
			}
			writeData(&phead, &ptail);
			break;
		case 3://while (system("cls"), list_print(phead, ptail), printf("(三次ctrl z返回上一级)\n请输入修改的学号:"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				list_modify(&phead, &ptail, i);
			}
			writeData(&phead, &ptail);
			break;
		case 4://while (system("cls"), printf("(三次ctrl z返回上一级)\n请输入查找的学号:"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				list_find(&phead, &ptail, i);
			}
			writeData(&phead, &ptail);
			break;
		case 5://排序
			while (system("cls"), printf("(三次ctrl z返回上一级)\n请输入排序依据:\n1总分 2数学 3英语 4政治 5体育 6物理 7学号 8班级\n"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				arr_select(&phead, &ptail, i);
				list_print(phead, ptail);
				system("pause");
			}
			writeData(&phead, &ptail);
			break;
		case 6://统计信息
			while (system("cls"), printf("(三次ctrl z返回上一级)\n请输入要查看的数据编号:\n(一)不及格名单(小于60分)\n11 数学\n12 英语\n13 政治\n14 体育\n15 物理\n\n(二) 成绩优秀名单(大于90分)\n21 数学\n22 英语\n23 政治\n24 体育\n25 物理\n\n(三) 课程平均成绩\n31 数学\n32 英语\n33 政治\n34 体育\n35 物理\n\n(四) 按班级分类\n41 输出某个班的成绩\n"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				statistics(&phead, &ptail, i);
			}
			break;
		case 7://自动生成
			while (system("cls"), printf("(三次ctrl z返回上一级)\n请输入生成学生的数量:"), scanf("%d", &i) != EOF)
			{
				rewind(stdin);
				newStu(&phead, &ptail, i);
				printf("生成成功!\n");
				list_print(phead, ptail);
				system("pause");
			}
			break;
		}
	}
	writeData(&phead, &ptail);//鸡肋的保存
}

head.h

#ifndef __FIRST__H_H
#define __FIRST__H_H
#define COURSENUM 5

typedef struct student
{
	int id;
	char name[20];
	int classnum;

	int math;
	int english;
	int politics;
	int sports;
	int physics;

	int total;
	int average;

	struct student *pnext;
}stu, *pstu;
#endif

list.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include <windows.h>
#include"head.h"
#define TIME 600
//打印首页
void printHome()
{
	system("cls");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *                                                              *\n");
	printf("          *                 学 生 成 绩 管 理 系 统                      *\n");
	printf("          *                                                              *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *        *                         *                           *\n");
	printf("          *        *      1.添 加 学 生      *      2.删 除 学 生        *\n");
	printf("          *   功   *                         *                           *\n");
	printf("          *        * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("          *        *                         *                           *\n");
	printf("          *   能   *      3.修 改 成 绩      *      4.查 找 学 生        *\n");
	printf("          *        *                         *                           *\n");
	printf("          *        * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("          *   菜   *                         *                           *\n");
	printf("          *        *      5.排 序 显 示      *      6.统 计 信 息        *\n");
	printf("          *        *                         *                           *\n");
	printf("          *   单   ** * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *        *                                                     *\n");
	printf("          *        *      7.( 高 级 模 式 ) 自 动 生 成 学 生 及 分 数   *\n");
	printf("          *        *                                                     *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *                                                              *\n");
	printf("          * 提 示 :任 意 界 面 下 , 连 续 三 次 ctrl z 返 回 上 一 级   *\n");
	printf("          *                                                              *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
}

//选择模式
int chooseMode()
{
	srand((int)time(NULL));//产生随机数的种子 
	char exitflag = '\0';
	for (int i = 1; ; i++)
	{
		Sleep(TIME);
		system("cls");
		{
			printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			printf("          * *                                                           **\n");
			printf("          * *          欢 迎 使 用 学 生 成 绩 管 理 系 统 !           **\n");
			printf("          * *                                                           **\n");
			printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			printf("          * * * * * * * * * * * * * *       * * * * * *       * * * * * **\n");
			printf("          * *   * * * * * * * * * *       * * * * * *           * * * * **\n");
			printf("          * *     * * * * * * * *       * * * * * *       *       * * * **\n");
			printf("          * *       * * * * * *       * * * * * *       * * *       * * **\n");
			printf("          * * *       * * * *       * * * * * *       * * * * *       * **\n");
			printf("          * * * *       * *       * * * * * *       * * * * * * *       **\n");
			printf("          * * * * *             * * * * * *       * * * * * * * * *     **\n");
			printf("          * * * * * *         * * * * * *       * * * * * * * * * * *   **\n");
			printf("          * * * * * * *     * * * * * *       * * * *       * * * * * * **\n");
			printf("          *     * * * * * * * * * * *       * * * * * *       * * * * * **\n");
			printf("          *       * * * * * * * * *       * * * * * * * *       * * * * **\n");
			printf("          * *       * * * * * * *       * * * * * * * * * *       * * * **\n");
			printf("          * * *       * * * * *       * * * * * * * * * * * *       * * **\n");
			printf("          * * * *       * * *       * * * * * * * * * * * * * *       * **\n");
			printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			printf("          *                                                              *\n");
			printf("          *             按     任     意     键     继     续            *\n");
			printf("          *                                                              *\n");
			printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			if (_kbhit())
			{
				//函数名: getch()
				//功能及返回值 : 从键盘上读取到的字符
				exitflag = _getch();
				if (exitflag)
				{
					break;
				}
			}
			Sleep(TIME);
			system("cls");
			{
				printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
				printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
				printf("          * *                                                           **\n");
				printf("          * *          欢 迎 使 用 学 生 成 绩 管 理 系 统 !           **\n");
				printf("          * *                                                           **\n");
				printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
				printf("          * * * * * * * * * * * * * *       * * * * * *       * * * * * **\n");
				printf("          * *   * * * * * * * * * *       * * * * * *           * * * * **\n");
				printf("          * *     * * * * * * * *       * * * * * *       *       * * * **\n");
				printf("          * *       * * * * * *       * * * * * *       * * *       * * **\n");
				printf("          * * *       * * * *       * * * * * *       * * * * *       * **\n");
				printf("          * * * *       * *       * * * * * *       * * * * * * *       **\n");
				printf("          * * * * *             * * * * * *       * * * * * * * * *     **\n");
				printf("          * * * * * *         * * * * * *       * * * * * * * * * * *   **\n");
				printf("          * * * * * * *     * * * * * *       * * * *       * * * * * * **\n");
				printf("          *     * * * * * * * * * * *       * * * * * *       * * * * * **\n");
				printf("          *       * * * * * * * * *       * * * * * * * *       * * * * **\n");
				printf("          * *       * * * * * * *       * * * * * * * * * *       * * * **\n");
				printf("          * * *       * * * * *       * * * * * * * * * * * *       * * **\n");
				printf("          * * * *       * * *       * * * * * * * * * * * * * *       * **\n");
				printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
				printf("          *                                                              *\n");
				printf("          *                                                              *\n");
				printf("          *                                                              *\n");
				printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
			}
		}
	}

	system("cls");
	int mode;
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *                                                              *\n");
	printf("          *                 学 生 成 绩 管 理 系 统                      *\n");
	printf("          *                                                              *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *        *                                                     *\n");
	printf("          *        *             1.   我   是   学   生                  *\n");
	printf("          *   选   *                                                     *\n");
	printf("          *        * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("          *        *                                                     *\n");
	printf("          *   则   *             2.   我   是   教   师                  *\n");
	printf("          *        *                                                     *\n");
	printf("          *        * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
	printf("          *   模   *                                                     *\n");
	printf("          *        *             3.   我   是   开   发   者             *\n");
	printf("          *        *                                                     *\n");
	printf("          *   式   ** * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *        *  <权 限 说 明>:学 生 只 能 查 看 成 绩             *\n");
	printf("          *        *  教 师 几 乎 拥 有 所 有 权 限 , 如: 修 改 成 绩  *\n");
	printf("          *        *  开 发 者 拥 有 最 高 权 限 ,可 自 动 生 成 学 生  *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("          *                                                              *\n");
	printf("          * 提 示 :任 意 界 面 下 , 连 续 三 次 ctrl z 返 回 上 一 级   *\n");
	printf("          *                                                              *\n");
	printf("          * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **\n");
	printf("请选择模式:\n");
	scanf("%d", &mode);
	return mode;
}


//打印总表
void list_print(pstu phead, pstu ptail)
{
	int flag = 0;
	pstu pcur = phead;
	printf("学号\t姓名\t班级\t数学\t英语\t政治\t体育\t物理\t总分\t平均分\n");
	while (pcur != NULL)
	{
		flag = 1;
		printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", pcur->id, pcur->name, pcur->classnum, pcur->math, pcur->english, pcur->politics, pcur->sports, pcur->physics, pcur->total, pcur->average);
		pcur = pcur->pnext;
	}
	flag == 0 || printf("\n");//空表时不打印换行
}

//打印当前学生
void printOne(stu one)
{
	printf("学号\t姓名\t班级\t数学\t英语\t政治\t体育\t物理\t总分\t平均分\n");
	printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", one.id, one.name, one.classnum, one.math, one.english, one.politics, one.sports, one.physics, one.total, one.average);
}
void printOneNoHead(stu one)
{
	printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", one.id, one.name, one.classnum, one.math, one.english, one.politics, one.sports, one.physics, one.total, one.average);
}
//打印统计信息
void statistics(pstu *pphead, pstu *pptail, int i)
{
	int flag = 0;
	pstu pcur = *pphead;
	if ((i >= 11 && i <= 15) || (i >= 21 && i <= 25))//输出成绩优秀名单
	{
		printf("学号\t姓名\t班级\t数学\t英语\t政治\t体育\t物理\t总分\t平均分\n");
		while (pcur != NULL)
		{
			flag = 1;
			switch (i)
			{
			case 11:if (pcur->math < 60)printOneNoHead(*pcur);  break;
			case 12:if (pcur->english < 60)printOneNoHead(*pcur);  break;
			case 13:if (pcur->politics < 60)printOneNoHead(*pcur);  break;
			case 14:if (pcur->sports < 60)printOneNoHead(*pcur);  break;
			case 15:if (pcur->physics < 60)printOneNoHead(*pcur);  break;

			case 21:if (pcur->math >= 90)printOneNoHead(*pcur); break;
			case 22:if (pcur->english >= 90)printOneNoHead(*pcur);  break;
			case 23:if (pcur->politics >= 90)printOneNoHead(*pcur);  break;
			case 24:if (pcur->sports >= 90)printOneNoHead(*pcur); break;
			case 25:if (pcur->physics >= 90)printOneNoHead(*pcur); break;
			}
			pcur = pcur->pnext;
		}
		system("pause");
	}

	//输出单科平均分
	else if (i >= 31 && i <= 35)
	{
		//遍历计算总数
		pcur = *pphead;//这句可能不需要
		int totalStu = 0;
		while (pcur != NULL)
		{
			totalStu++;
			pcur = pcur->pnext;
		}

		//计算
		pcur = *pphead;//pcur归位
		float average = 0;
		switch (i)
		{
		case 31:
			printf("数学");
			while (pcur != NULL)
			{
				average += pcur->math;
				pcur = pcur->pnext;
			}
			printf("平均分:%.2f", average /= totalStu);
			system("pause");
			break;

		case 32:
			printf("英语");
			while (pcur != NULL)
			{
				average += pcur->english;
				pcur = pcur->pnext;
			}
			printf("平均分:%.2f", average /= totalStu);
			system("pause");
			break;
		case 33:
			printf("政治");
			while (pcur != NULL)
			{
				average += pcur->politics;
				pcur = pcur->pnext;
			}
			printf("平均分:%.2f", average /= totalStu);
			system("pause");
			break;
		case 34:
			printf("体育");
			while (pcur != NULL)
			{
				average += pcur->sports;
				pcur = pcur->pnext;
			}
			printf("平均分:%.2f", average /= totalStu);
			system("pause");
			break;
		case 35:
			printf("物理");
			while (pcur != NULL)
			{
				average += pcur->physics;
				pcur = pcur->pnext;
			}
			printf("平均分:%.2f", average /= totalStu);
			system("pause");
			break;
		}
	}
	else if (i == 41)
	{
		pcur = *pphead;//pcur归位
		system("cls");
		printf("请输入班号:\n");
		scanf("%d", &i);
		printf("学号\t姓名\t班级\t数学\t英语\t政治\t体育\t物理\t总分\t平均分\n");
		while (pcur != NULL)
		{
			if (pcur->classnum == i)
			{
				printOneNoHead(*pcur);
			}
			pcur = pcur->pnext;
		}
		system("pause");
		return;
	}
}

//计算总分和平均分
void AddAndAverage(pstu one)
{
	one->total = one->english + one->math + one->physics + one->politics + one->sports;
	one->average = one->total / COURSENUM;
}
//更新总分、平均分
void update(pstu *pphead, pstu *pptail)
{
	pstu pcur = *pphead;
	while (pcur != NULL)
	{
		pcur->total = pcur->english + pcur->math + pcur->physics + pcur->politics + pcur->sports;
		pcur->average = pcur->total / COURSENUM;
		pcur = pcur->pnext;
	}
}
//增:有序插入
void list_insert_sort(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew;
	pnew = (pstu)calloc(1, sizeof(stu));

	pnew->id = i;
	printf("请输入姓名:");
	scanf("%s", pnew->name); rewind(stdin);
	printf("请输入班号:");
	scanf("%d", &pnew->classnum); rewind(stdin);
	pnew->math = pnew->english = pnew->politics = pnew->sports = pnew->physics = pnew->total = pnew->average = 0;

	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		*pphead = pnew;
		*pptail = pnew;
	}
	else
	{
		//从小到大
		if (i <= pcur->id)//如果小于第一个节点,头插
		{
			pnew->pnext = *pphead;//新节点的pnext成员指向原有链表头
			*pphead = pnew;//新节点成为新的链表头
			return;
		}
		else//向后遍历
		{
			while (NULL != pcur)//只要不是最后
			{
				if (i <= pcur->id)
				{
					pbefore->pnext = pnew;//小弟的pnext成员指向新节点
					pnew->pnext = pcur;//新节点的pnext成员指向大哥
					break;
				}
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
			if (NULL == pcur)//如果到最后,尾插
			{
				(*pptail)->pnext = pnew;//原有链表尾的pnext成员指向新节点
				*pptail = pnew;//新节点成为新的链表尾
			}
		}
	}
}

//删除
void list_delete(pstu *pphead, pstu *pptail, int i)
{
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
	}
	else if (i == (*pphead)->id)//如果等于第一个节点(此时可能仅剩一个节点)
	{
		*pphead = (*pphead)->pnext;//头指针指向下一个节点
		if (NULL == *pphead)
		{
			*pptail = NULL;
			free(pcur);
		}
	}
	else//如果不等于第一个节点
	{
		while (NULL != pcur)//只要不是最后
		{
			if (i == pcur->id)//如果等于当前节点
			{
				pcur = pcur->pnext;//大哥前进一步
				pbefore->pnext = pcur;//小弟的pnext成员指向大哥
				return;
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此学号\n");
		}
	}
}

//修改
void list_modify(pstu *pphead, pstu *pptail, int i)
{
	int score;
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
	}
	else
	{
		while (NULL != pcur)//只要不是最后
		{
			if (i == pcur->id)//如果等于当前节点,修改
			{
				int sub;
				printOne(*pcur);
				while (printf("请选择科目(输入科目代号):1高数 2英语 3政治 4体育 5物理\n"))
				{
					if (scanf("%d", &sub) == EOF)
					{
						rewind(stdin);
						return;
					}
					printf("请输入分数:");
					scanf("%d", &score);
					switch (sub)
					{
					case 1:pcur->math = score; AddAndAverage(pcur); printOne(*pcur); break;
					case 2:pcur->english = score; AddAndAverage(pcur); printOne(*pcur); break;
					case 3:pcur->politics = score; AddAndAverage(pcur); printOne(*pcur); break;
					case 4:pcur->sports = score; AddAndAverage(pcur); printOne(*pcur); break;
					case 5:pcur->physics = score; AddAndAverage(pcur); printOne(*pcur); break;
					}
				}
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此学号\n");
		}
	}
}
//查找
void list_find(pstu *pphead, pstu *pptail, int i)
{
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
		system("pause");
	}
	else
	{
		while (NULL != pcur)//只要不是最后
		{
			if (i == pcur->id)//如果等于当前节点,输出
			{
				printOne(*pcur);
				system("pause");
				return;
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此数字\n");
		}
	}
}

//自动生成一个学生
int rand_number()//生成成绩
{
	int num;
	num = rand() % 50 + 50;
	return num;
}
int rand_id(pstu phead, pstu ptail)//生成学号
{

	int num;
label2:
	num = rand() % 199 + 1;
	pstu pcur = phead;
	while (pcur != NULL)
	{
		if (pcur->id == num)
		{
			goto label2;
		}
		pcur = pcur->pnext;
	}
	return num;
}
void newStu(pstu *pphead, pstu *pptail, int i)
{
	int num;
	for (; i > 0; i--)
	{
		pstu pnew;
		pnew = (pstu)calloc(1, sizeof(stu));

		num = rand_id(*pphead, *pptail);
		pnew->id = num;

		pnew->name[0] = 'a';//迷之字符串赋值
		pnew->name[1] = 'u';
		pnew->name[2] = 't';
		pnew->name[3] = 'o';
		pnew->name[4] = 0;

		num = rand_number();
		pnew->classnum = num % 9 + 1;
		num = rand_number();
		pnew->math = num;
		num = rand_number();
		pnew->english = num;
		num = rand_number();
		pnew->politics = num;
		num = rand_number();
		pnew->sports = num;
		num = rand_number();
		pnew->physics = num;

		pnew->total = pnew->english + pnew->math + pnew->physics + pnew->politics + pnew->sports;
		pnew->average = pnew->total / COURSENUM;

		//头插法
		if (NULL == *pptail)
		{
			*pphead = pnew;
			*pptail = pnew;
		}
		else
		{
			(*pptail)->pnext = pnew;
			*pptail = pnew;
		}
	}
}

sort.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"head.h"

//按总分 选择排序
void arr_select(pstu *pphead, pstu *pptail, int subject)//sunject排序依据 1总分 2数学 3英语 4政治 5体育 6物理 7学号 8班级
{
	int t;
	pstu temp = (pstu)calloc(1, sizeof(stu));//这里不能强行将temp赋给任何(无意义的)变量,必须申请新的空间。否则temp的值会在swap的时候漂移
	pstu pleft = *pphead;
	pstu pright = *pphead;
	pstu prightmax = NULL;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
		system("pause");
	}
	else
	{
		for (; pleft != NULL; pleft = pleft->pnext)//最大的数放在左边
		{
			pright = pleft;
			for (prightmax = pright; pright != NULL; pright = pright->pnext)//从右边找出最大的数,用prightmax记录其位置
			{
				switch (subject)
				{
				case 1:
					if (pright->total > prightmax->total)
					{
						prightmax = pright;
					}
					break;
				case 2:
					if (pright->math > prightmax->math)
					{
						prightmax = pright;
					}
					break;
				case 3:
					if (pright->english > prightmax->english)
					{
						prightmax = pright;
					}
					break;
				case 4:
					if (pright->politics > prightmax->politics)
					{
						prightmax = pright;
					}
					break;
				case 5:
					if (pright->sports > prightmax->sports)
					{
						prightmax = pright;
					}
					break;
				case 6:
					if (pright->physics > prightmax->physics)
					{
						prightmax = pright;
					}
					break;
				case 7:
					if (pright->id < prightmax->id)
					{
						prightmax = pright;
					}
					break;
				case 8:
					if (pright->classnum < prightmax->classnum)
					{
						prightmax = pright;
					}
					break;
				}

			}
			//SWAP(*pleft, *prightmax)
			(*temp).id = pleft->id;
			for (t = 0; t < 20; t++)//迷之复制字符串
			{
				(*temp).name[t] = pleft->name[t];
			}
			(*temp).classnum = pleft->classnum;
			(*temp).math = pleft->math;
			(*temp).english = pleft->english;
			(*temp).politics = pleft->politics;
			(*temp).sports = pleft->sports;
			(*temp).physics = pleft->physics;
			(*temp).total = pleft->total;
			(*temp).average = pleft->average;

			pleft->id = prightmax->id;
			for (t = 0; t < 20; t++)//迷之复制字符串
			{
				pleft->name[t] = prightmax->name[t];
			}
			pleft->classnum = prightmax->classnum;
			pleft->math = prightmax->math;
			pleft->english = prightmax->english;
			pleft->politics = prightmax->politics;
			pleft->sports = prightmax->sports;
			pleft->physics = prightmax->physics;
			pleft->total = prightmax->total;
			pleft->average = prightmax->average;

			prightmax->id = (*temp).id;
			for (t = 0; t < 20; t++)//迷之复制字符串
			{
				prightmax->name[t] = (*temp).name[t];
			}
			prightmax->classnum = (*temp).classnum;
			prightmax->math = (*temp).math;
			prightmax->english = (*temp).english;
			prightmax->politics = (*temp).politics;
			prightmax->sports = (*temp).sports;
			prightmax->physics = (*temp).physics;
			prightmax->total = (*temp).total;
			prightmax->average = (*temp).average;
		}
	}
}

read.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"head.h"

void readData(pstu *pphead, pstu *pptail)
{
	int TOTAL;
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	pstu pnew;

	FILE *fpReadAgain = fopen("data.txt", "r");//读取
	fscanf(fpReadAgain, "%d", &TOTAL);

	for (int j = 0; j < TOTAL; j++)
	{
		pcur = *pphead;
		pbefore = *pphead;
		pnew = (pstu)calloc(1, sizeof(stu));//只申请一个
		fscanf(fpReadAgain, "%d %s %d %d %d %d %d %d %d %d", &pnew->id, &pnew->name, &pnew->classnum, &pnew->math, &pnew->english, &pnew->politics, &pnew->sports, &pnew->physics, &pnew->total, &pnew->average);
		if (NULL == *pptail)//如果链表为空
		{
			*pphead = pnew;
			*pptail = pnew;//不用担心尾节点不是NULL,因为calloc的pnew中的pnext成员本身就是null
		}
		else
		{
			(*pptail)->pnext = pnew;//原有链表尾的pnext成员指向新节点
			*pptail = pnew;//新节点成为新的链表尾
		}
	}
	fclose(fpReadAgain);
}

write.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"head.h"
void writeData(pstu *pphead, pstu *pptail)
{
	int TOTAL = 0;
	//计算链表长度
	pstu pcur = *pphead;
	while (pcur != NULL)
	{
		TOTAL++;
		pcur = pcur->pnext;
	}

	FILE *fpPrintAgain = fopen("data.txt", "w");//输出

	fprintf(fpPrintAgain, "%d\n", TOTAL);//输出总数据量,便于下一次读取

	pcur = *pphead;
	while (pcur != NULL)
	{
		fprintf(fpPrintAgain, "%d %s %d %d %d %d %d %d %d %d\n", pcur->id, pcur->name, pcur->classnum, pcur->math, pcur->english, pcur->politics, pcur->sports, pcur->physics, pcur->total, pcur->average);
		pcur = pcur->pnext;
	}

	fclose(fpPrintAgain);
}
Logo

快速构建 Web 应用程序

更多推荐