学生成绩管理系统(链表版)

某班同学(具体人数由键盘输入)参加期末考试,最多不超过6门(具体门数由键盘输入)。使用链表编程成实现如下菜单驱动的学生成绩管理系统。
1.从文件读入每个学生个人信息和成绩信息,可以由键盘输入文件名。读入成功提示读入学生记录的个数,不成功提示相应出错信息。
2.增量式手动录入每个学生的学号(8位数字)、姓名和各科考试成绩。不考虑中文姓名,不考虑重名情况下的处理,学生的学号是唯一的。
3.计算每门课程的总分和平均分; 
4.计算每个学生的总分和平均分;
5.按每个学生的总分由高到低排出名次表; 
6.按每个学生的总分由低到高排出名次表; 
7.按学号由小到大排出成绩表; 
8.按姓名的字典顺序排出成绩表; 
9.按学号查询学生排名及其考试成绩; 
10.按姓名查询学生排名及其考试成绩;需要考虑学生重名的情况。
11.按优秀(100-90)、良好(89-80)、中等(79-70)、及格(69-60)、不及格(59-0)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比;并将计算结果输出到文件,文件名可由键盘输入。
12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分;
13.将每个学生的个人信息和成绩写入文件,可由键盘输入文件名;

要求程序运行后先显示如下菜单,并提示用户输入选项(菜单式循环显示,直到选择0.exit 整个程序退出):

1.Read from a file
2.Append record manually
3.Calculate total and average score of every course
4.Calculate total and average score of every student
5.Sort in descending order by total score of every student
6.Sort in ascending order by total score of every stuednet
7.Sort in ascending order by number
8.Sort in dictionary order by name
9.Search by number
10.Search by name
11.Statistic analysis for every course
12.List record
13.Write to a file
0 .  Exit
Please input your choice:

然后根据用户输入的选项进行相应的操作。
 

界面展示:

下面是代码,代码有点长,好在我都写有详细的注释,请耐心一点:

主函数:

定义两个结构体:

typedef struct _SCORE  //储存学生每科学习成绩结构体
{
	//各学科成绩:
	float maths;      //数学
	float English;    //英语
	float Politics;   //政治
	float Physics;    //物理
	float computer;   //计算机
	
}SCORE;
typedef struct _STUDENT //储存学生信息的结构体
{
	//学生信息_数据域
	char stName[20];     //姓名
	char StudentId[10];  //学号
	int Rank;            //总分排名
	float TotalScore;    //总分数
	float Average;       //平均分
	SCORE Score;         //各科成绩
	struct _STUDENT* pNext;	//_指针域:指向各节点的指针
}STUDENT;

初始化学生信息,并写入磁盘文件中:

STUDENT* InitStudentInfo()                  //初始化学生信息并写入磁盘
{	
	STUDENT* pList = NULL;  //链表头
	int i;
	STUDENT* pTemp = (STUDENT*)malloc(sizeof(STUDENT));//创建首节点
	if (pTemp == NULL)
	{
		printf("申请创建首元节点空间失败:\n");
		return pTemp;
	}
	pList = pTemp;      //头指针指向首节点
	pTemp->pNext = NULL; //首节点指针域赋空值
	printf("请输入要录入学生的人数:\n");
	scanf("%d", &N);

	printf("请输入第1个学生的信息:(姓名栏请输入汉字或英文,学号栏以及分数栏请输入数字)\n");   
	printf("输入学生姓名:\n");         //第一个学生的信息录入首节点
	scanf("%s", pTemp->stName);
	printf("输入学生学号:\n");
	scanf("%s", pTemp->StudentId);
	printf("输入数学分数:\n");
	scanf("%f",&pTemp->Score.maths);
	printf("输入英语分数:\n");
	scanf("%f", &pTemp->Score.English);
	printf("输入物理分数:\n");
	scanf("%f", &pTemp->Score.Physics);
	printf("输入政治分数:\n");
	scanf("%f", &pTemp->Score.Politics);
	printf("输入计算机分数:\n");
	scanf("%f", &pTemp->Score.computer);
	pTemp->Rank = 0;   //初始化学生名次
	pTemp->TotalScore = pTemp->Score.maths + pTemp->Score.English + pTemp->Score.Physics + pTemp->Score.Politics + pTemp->Score.computer;
	pTemp->Average = pTemp->TotalScore / 5.0;
	printf("------------------\n");

	for (i = 2; i <= N; i++)      //从第二个节点开始录入
	{
		//创建一个新节点并初始化
		STUDENT* a = (STUDENT*)malloc(sizeof(STUDENT));
		if (a == NULL)
		{
			printf("创建新节点空间失败:\n");
			return a;
		}
  INSPECT:
		printf("请输入第%d个学生的信息:(姓名栏请输入汉字或英文,学号栏以及分数栏请输入数字)\n",i);      //首节点先初始化
		printf("输入学生姓名:\n");
		scanf("%s", a->stName);
		printf("输入学生学号:\n");
		scanf("%s", a->StudentId);

		STUDENT* pInspect = pList; //新建一个头指针。用来遍历链表,检查学号是否被录入过
		while (pInspect)
		{

			if (strcmp(pInspect->StudentId,a->StudentId)==0)   //检查学号是否存在
			{
				printf("该学生信息已经录入,请重新输入学生信息:\n");
					goto INSPECT;
			}
			pInspect = pInspect->pNext;
		}
		printf("输入数学分数:\n");
		scanf("%f", &a->Score.maths);
		printf("输入英语分数:\n");
		scanf("%f", &a->Score.English);
		printf("输入物理分数:\n");
		scanf("%f", &a->Score.Physics);
		printf("输入政治分数:\n");
		scanf("%f", &a->Score.Politics);
		printf("输入计算机分数:\n");
		scanf("%f", &a->Score.computer);
		printf("------------------\n");
		a->Rank = 0;       //初始化学生名次
		a->TotalScore = a->Score.maths + a->Score.English + a->Score.Physics + a->Score.Politics + a->Score.computer;
		a->Average = a->TotalScore / 5.0;
		a->pNext = NULL;      //将新节点的指针域置NULL

		pTemp->pNext = a;      //将pTemp节点与新建立的a节点建立逻辑关系
		pTemp = pTemp->pNext;   //指针pTemp每次都指向新链表的最后一个节点,其实就是 a节点,这里写pTemp=a也可以
	}
	system("CLS");  //清除屏幕内容
	OutMenu();  //重新在屏幕显示菜单项
	WriteToFile(pList);//调用写入文件到磁盘的函数,将链表信息写入文件
	return pList;
}

菜单选项函数:

VOID InTab()                              //从键盘输入菜单选项(数字0-13)
{
	printf("**********************************************************************\n");
	printf("* 如果您是第一次使用本系统,请首先选择 13 选项卡。对学生信息进行录入 *\n");
	printf("**********************************************************************\n");
	STUDENT* pList = NULL;     //建立链表头指针
	int Id = 0;
	while (TRUE)
	{
	Judge:
		printf("请选择菜单功能:(0--13)");
		scanf("%d", &Id);         //键盘输入数字
		if (Id < 0 || Id>13)      //判断输入的数字是否在规定范围内,不在范围则重新输入
		{
			printf("您输入的数字有误,");
			goto Judge;
		}	
		switch (Id)   //使用SWITCH判断输入的数字选项,按照选项来调用功能函数.各项功能见菜单
		{
			case 1:  {    pList = EnterInfo(); break;   }          //从文件读入每个学生个人信息和成绩信息
			case 2:  {    AddStudentInfo(pList); break;   }        //增加学生信息
			case 3:  {    EachCourseTotalScoreAndAver(pList); break;   }
			case 4:  {    EachStudentTotalScoreAndAver(pList); break;   }
			case 5:  {    TotalScoreSorting_hightolow(pList); break;   }
			case 6:  {    TotalScoreSorting_lowtohigh(pList); break;   }
			case 7:  {    Sort_StudentId(pList); break;   }
			case 8:  {    Sort_StudentName(pList); break;   }
			case 9:  {    LookUp_StudentId(pList); break;   }
			case 10: {    LookUp_StudentName(pList); break;   }
			case 11: {    StatScore(pList); break;   } 
			case 12: {    OutStudentInfo(pList); break;   }
			case 13: {    pList = StudentInfoToFile(); break;   }
			case 0:  {    printf("\t\t您输入了程序退出选项,程序即将退出:\n"); exit(0); break;  }
			default:break;
		}
	}
}

打印输出:

VOID PrintfStudentInfo(STUDENT* pList)                    //_遍历链表并输出信息到屏幕           
{
	if (pList == NULL)
	{
		printf("链表中没有录入学生信息\n");
		return;
	}
	STUDENT* pTemp = pList;
	//遍历链表并输出信息到屏幕
	while (pTemp)
	{
		printf("姓名: %s ", pTemp->stName);
		printf("学号:%s ", pTemp->StudentId);
		printf("名次: %d ", pTemp->Rank);
		printf("数学:%.2f ", pTemp->Score.maths);
		printf("英语:%.2f ", pTemp->Score.English);
		printf("政治:%.2f ", pTemp->Score.Politics);
		printf("物理:%.2f ", pTemp->Score.Physics);
		printf("计算机:%.2f ", pTemp->Score.computer);
		printf("总分数:%.2f ", pTemp->TotalScore);
		printf("平均分:%.2f\n", pTemp->Average);
		pTemp = pTemp->pNext;
	}
	printf("\n");
	return;
}

这个是写出文件函数,被上面的初始化函数所调用:

VOID WriteToFile(STUDENT* pList)                         //_将学生信息写出到文件
{
	
	printf("正在将学生信息写入文件,请输入要写入的文件名:");
	scanf("%s", g_FileName);  //接收键盘输入的文件名称
	strcat(g_FileName, ".txt");  //使用字符串拼接函数添加文件名后缀
	FILE* pFile = NULL;    // 定义文件指针
	fopen_s(&pFile, g_FileName, "wb"); //在磁盘中建立或打开一个文件
	if (!pFile)
	{
		printf("打开文件失败");
		return;
	}
	STUDENT* pTemp = pList;  //定义临时指针,指向链表头
	char strBuffer[200];  //存放分数转换为字符串的缓冲区
	while (pTemp)
	{
		fwrite(pTemp->stName, strlen(pTemp->stName), 1, pFile);  // 学生姓名写入文件
		fwrite(":", 1, 1, pFile);                                // 加入" :"用来分隔各项学生的信息。方便读文件时分割信息
		fwrite(pTemp->StudentId, strlen(pTemp->StudentId), 1, pFile);  // 学生学号写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%d", pTemp->Rank);              // 总成绩名次换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);     // 总成绩名次写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Score.maths);     // 数学成绩转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);     // 数学成绩写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Score.English);    // 英语成绩转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);     // 英语成绩写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Score.Politics); // 政治成绩转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);    // 政治成绩写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Score.Physics);  // 物理成绩转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);    // 物理成绩写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Score.computer); // 计算机成绩转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);    // 计算机成绩写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->TotalScore);     // 成绩总分数转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);    // 成绩总分数写入文件
		fwrite(":", 1, 1, pFile);

		sprintf(strBuffer, "%.2f", pTemp->Average);        // 成绩平均分转换成字符串
		fwrite(strBuffer, strlen(strBuffer), 1, pFile);    // 成绩平均分写入文件
		fwrite("\n", 1, 1, pFile);
		pTemp = pTemp->pNext;
	}
	fclose(pFile);   //关闭文件指针
	return;
}

排序函数,也是被调用的函数:

STUDENT* Sort_(STUDENT* pList)   //  排序函数。将每个学生的总分由高到低排出名次表,只排序不输出
{
	STUDENT* pb, * pf;
	STUDENT Temp;
	pf = pList;

	if (pList == NULL) //链表为空
	{
		printf("链表为空.\n");
		return;
	}
	if (pList->pNext == NULL) //链表有1个节点
	{
		printf("链表只有1个节点.\n");
		return;
	}
	while (pf->pNext != NULL)//以pf指向的节点为基准节点
	{
		pb = pf->pNext;//pb从基准点的下一个节点开始
		while (pb != NULL)
		{
			if (pf->TotalScore < pb->TotalScore)
			{
				Temp = *pf;
				*pf = *pb;
				*pb = Temp;   //互换指针中的地址
				Temp.pNext = pf->pNext;
				pf->pNext = pb->pNext;
				pb->pNext = Temp.pNext; //更改原指针域的指向
			}
			pb = pb->pNext;
		}
		pf = pf->pNext;
	}
	STUDENT* pTemp = pList;   //遍历链表。对学习信息中的 Rank(名次) 进行赋值
	int i=1;
	while (pTemp)   
	{
		pTemp->Rank = i;
		i++;
		pTemp = pTemp->pNext;
	}
	return pList;
}

下面的就是各种功能函数了:

1 从文件读入每个学生个人信息和成绩信息。

STUDENT* EnterInfo()                         //1.从文件读入每个学生个人信息和成绩信息。
{ 
	if (!strlen(g_FileName))
	{
		printf("您还没有写出过学生信息到文件,请首先使用 13 选项对学生信息进行录入后再使用此功能:\n");
		return NULL;
	}
	else
	{
		printf("您保存过的文件名是  %s :\n", strtok(g_FileName, "."));
	}
	char FileName[100] = {0 };  //要读的文件名
	printf("请输入要读取的文件名称:");
	scanf("%s", FileName);     //输入要打开的文件名
	strcat(FileName, ".txt");  //使用字符串拼接函数添加文件名后缀
	FILE* pFile = NULL;
	fopen_s(&pFile, FileName, "rb"); //在磁盘中建立或打开一个文件
	if (!pFile)
	{
		printf("打开文件失败,如果您是第一次使用本系统请选【13】功能录入学生信息");
		return;
	}
	char szBuffer[2048] = { 0 };
	DWORD dwNumber = 0;
	fread(szBuffer, 1, 2048, pFile);   //读取全部学生信息
	if (!szBuffer)
	{
		printf("读取文件失败");
		return;
	}
	char* student[100] = { 0 };
	//按学生人数进行分割
	student[0] = strtok(szBuffer, "\n");//第一次分割字符串
	int i = 0;
	while (student[i] != NULL)
	{
		i++;
		student[i] = strtok(NULL, "\n"); //第二次分割 学生信息分段读取
	}
	//将每个学生的信息详细分割
	
	STUDENT* pTemp = NULL;
	STUDENT* pList = NULL;
	STUDENT* pt = NULL;

	pTemp = (STUDENT*)malloc(sizeof(STUDENT));
	if (pTemp == NULL)
	{
		printf("申请创建首元节点空间失败:\n");
		return;
	}
	pList = pTemp;            //保存链表头指针

	//分割第一个学生信息
	i = 0;
	char* str[100] = { 0 };
	str[0] = strtok(student[0], ":");//第一次分割字符串
	while (str[i] != NULL)
	{
		i++;
		str[i] = strtok(NULL, ":");
	}
	strcpy(pTemp->stName, str[0]);  //姓名
	strcpy(pTemp->StudentId, str[1]);  //学号
	pTemp->Rank = atoi(str[2]);
	pTemp->Score.maths = atof(str[3]);
	pTemp->Score.English = atof(str[4]);
	pTemp->Score.Politics = atof(str[5]);
	pTemp->Score.Physics = atof(str[6]);
	pTemp->Score.computer = atof(str[7]);
	pTemp->TotalScore = atof(str[8]);
	pTemp->Average = atof(str[9]);
	pTemp->pNext = NULL;
	
	N = 1; //录入学生人数 + 1
	i = 1;
	while (student[i])
	{
		int j = 0;
		str[j] = strtok(student[i],":");//第一次分割字符串
		while (str[j] != NULL)
		{
			j++;
			str[j] = strtok(NULL, ":");
		}
		pt = (STUDENT*)malloc(sizeof(STUDENT));
		if (pt == NULL)
		{
			printf("申请创建首元节点空间失败:\n");
			return;
		}
		strcpy(pt->stName, str[0]);  //姓名
		strcpy(pt->StudentId, str[1]);  //学号
		pt->Rank = atoi(str[2]);
		pt->Score.maths = atof(str[3]);
		pt->Score.English = atof(str[4]);
		pt->Score.Politics = atof(str[5]);
		pt->Score.Physics = atof(str[6]);
		pt->Score.computer = atof(str[7]);
		pt->TotalScore = atof(str[8]);
		pt->Average = atof(str[9]);
		pTemp->pNext = pt;
		pTemp = pTemp->pNext;
		N++;
		i++;	
	}
	pTemp->pNext = NULL;
	fclose(pFile);
	PrintfStudentInfo(pList);
	printf("1.从文件读入每个学生个人信息和成绩成功,请选则其他功能:");
	return pList;
}

2.__增加学生信息

VOID AddStudentInfo(STUDENT* pList)                     //2.__增加学生信息
{
	printf("您选择的功能是  增加一个新学生的信息\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pTemp = pList;   //建立临时指针。保存头指针
	while (pTemp->pNext)
	{
		pTemp = pTemp->pNext;    //使临时指针指向最后一个节点.在末尾加入一个学生信息
	}
	STUDENT* pNewStudent = NULL;
	pNewStudent = (STUDENT*)malloc(sizeof(STUDENT));
	if (pNewStudent == NULL)
	{
		printf("录入新学生信息所需内存空间申请失败:\n");
		return;
	}
	//从键盘输入新学生的信息
INSPECT:
	printf("输入学生姓名:\n");         //新学生的信息录入
	scanf("%s", pNewStudent->stName);
	printf("输入学生学号:\n");
	scanf("%s", pNewStudent->StudentId);
		STUDENT* pInspect = pList;    //新建一个头指针。用来遍历链表,检查学号是否被录入过
		while (pInspect)
		{
			if (strcmp(pInspect->StudentId, pNewStudent->StudentId) == 0)//检查学号是否存在
			{
				printf("该学生信息已经录入,请重新输入学生信息:\n");
				goto INSPECT;
			}
			pInspect = pInspect->pNext;
		}
	printf("输入数学分数:\n");
	scanf("%f", &pNewStudent->Score.maths);
	printf("输入英语分数:\n");
	scanf("%f", &pNewStudent->Score.English);
	printf("输入物理分数:\n");
	scanf("%f", &pNewStudent->Score.Physics);
	printf("输入政治分数:\n");
	scanf("%f", &pNewStudent->Score.Politics);
	printf("输入计算机分数:\n");
	scanf("%f", &pNewStudent->Score.computer);

	pNewStudent->Rank = 0; //将新学生的名次置位 0 ;表示还没有对其进行排名
	pNewStudent->TotalScore = pNewStudent->Score.maths + pNewStudent->Score.English + pNewStudent->Score.Physics + pNewStudent->Score.Politics + pNewStudent->Score.computer;
	pNewStudent->Average = pNewStudent->TotalScore / 5.0;
	printf("------------------\n");

	pNewStudent->pNext = NULL;   //使新录入节点的指针域指向NULL
	pTemp->pNext = pNewStudent;  //新节点连接到原链表尾部 即将新学生信息添加至链表尾部
	N++;                         //录入学生人数 + 1;
	WriteToFile(pList);    //调用将链表信息存入文件的函数
	printf("2.新增学生信息并写入文件成功,请选则其他功能:");
	return;
}

3.__计算每门课程的总分和平均分;

VOID  EachCourseTotalScoreAndAver(STUDENT* pList)       //3.__计算每门课程的总分和平均分;
{
	printf("您选择的功能是  计算所有学生单科的总分和平均分;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pTemp = pList;   //建立临时指针。保存头指针
	float Sum_math = 0;
	float Sum_English = 0;
	float Sum_Politics = 0;
	float Sum_Physics = 0;
	float Sum_computer = 0;

	while (pTemp)                //遍历链表,计算出所有学生单科成绩的总分和平均分
	{
		Sum_math += pTemp->Score.maths;         
		Sum_English += pTemp->Score.English;
		Sum_Politics += pTemp->Score.Politics;
		Sum_Physics += pTemp->Score.Physics;
		Sum_computer += pTemp->Score.computer;
		pTemp = pTemp->pNext;    //使临时指针指向最后一个节点
	}

	float n = N;   //下面要用来求平均值,需要将整形值转换为浮点型
	float Ave_math = Sum_math/n;
	float Ave_English = Sum_English / n;
	float Ave_Politics = Sum_Politics / n;
	float Ave_Physics = Sum_Physics / n;
	float Ave_computer = Sum_computer / n;
	//输出计算结果
	printf("共记录学生%d人:\n", N);
	printf("所有学生数学总分:%.2f  平均分:%.2f\n", Sum_math, Ave_math);
	printf("所有学生英语总分:%.2f  平均分:%.2f\n", Sum_English, Ave_English);
	printf("所有学生政治总分:%.2f  平均分:%.2f\n", Sum_Politics, Ave_Politics);
	printf("所有学生物理总分:%.2f  平均分:%.2f\n", Sum_Physics, Ave_Physics);
	printf("所有学生计算机总分:%.2f  平均分:%.2f\n", Sum_computer, Ave_computer);
	printf("3.计算每门课程的总分和平均分并输出执行完毕,请选则其他功能:");
}

4.__计算每个学生的总分和平均分;

VOID EachStudentTotalScoreAndAver(STUDENT* pList)       //4.__计算每个学生的总分和平均分;
{
	printf("您选择的功能是  计算每个学生的总分和平均分;\n");//在录入时已经计算完毕,直接输出结果即可
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pTemp = pList; //新建临时指针。保留链表头
	while (pTemp)//遍历链表输出计算结果
	{
		printf("%s 同学的总分是:%.2f 平均分是:%.2f\n", pTemp->stName, pTemp->TotalScore, pTemp->Average);
		pTemp = pTemp->pNext;
	}
	printf("4.计算每个学生的总分和平均分执行完毕,请选则其他功能:");
}

5.__按每个学生的总分由高到低排出名次表;

STUDENT* TotalScoreSorting_hightolow(STUDENT* pList)        //5.__按每个学生的总分由高到低排出名次表
{
	printf("您选择的功能是 按每个学生的总分由高到低排出名次表;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}	
	pList = Sort_(pList);  //调用排序函数对学生成绩进行排名

	STUDENT* pTemp = pList;
	while (pTemp)    //遍历链表。输出排名后的学生成绩
	{
		printf("第%d名:学生姓名_ %s    总分_ %.2f\n", pTemp->Rank, pTemp->stName, pTemp->TotalScore);	
		pTemp = pTemp->pNext;
	}
	printf("5.总分由高到低排出名次执行完毕,请选则其他功能:\n");
	return pList;
}

6.__按每个学生的总分由低到高排出名次表;

VOID TotalScoreSorting_lowtohigh(STUDENT* pList)        //6.__按每个学生的总分由低到高排出名次表
{
	//按照总分数由低到高将链表排序
	printf("您选择的功能是 按每个学生的总分由低到高排出名次表;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pb, * pf, Temp;
	pf = pList;

	if (pList == NULL) //链表为空
	{
		printf("链表为空.\n");
		return;
	}
	if (pList->pNext == NULL) //链表有1个节点
	{
		printf("链表只有1个节点.\n");
		return;
	}
	while (pf->pNext != NULL)//以pf指向的节点为基准节点
	{
		pb = pf->pNext;//pb从基准点的下一个节点开始
		while (pb != NULL)
		{
			if (pf->TotalScore > pb->TotalScore)
			{
				Temp = *pf;
				*pf = *pb;
				*pb = Temp;   //互换指针中的地址
				Temp.pNext = pf->pNext;
				pf->pNext = pb->pNext;
				pb->pNext = Temp.pNext; //更改原指针域的指向
			}
			pb = pb->pNext;
		}
		pf = pf->pNext;
	}
	STUDENT* pTemp = pList;
	int i = 0;
	while (pTemp)
	{
		printf("学生姓名_%s     总分_%.2f\n", pTemp->stName, pTemp->TotalScore);
		pTemp = pTemp->pNext;
	}
	printf("6.总分由低到高排出名次执行完毕,请选则其他功能:");
}

7.__.按学号由小到大排出成绩表;

VOID Sort_StudentId(STUDENT* pList)                     //7.__.按学号由小到大排出成绩表;
{
	//按学号由小到大排出成绩表
	printf("您选择的功能是 按学号由小到大排出成绩表;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pb, * pf, Temp;
	pf = pList;

	if (pList == NULL) //链表为空
	{
		printf("链表为空.\n");
		return;
	}
	if (pList->pNext == NULL) //链表有1个节点
	{
		printf("链表只有1个节点.\n");
		return;
	}
	while (pf->pNext != NULL)//以pf指向的节点为基准节点
	{
		pb = pf->pNext;//pb从基准点的下一个节点开始
		while (pb != NULL)
		{
			if( atoi(pf->StudentId)>atoi( pb->StudentId)) //学号是字符数组。先要用函数atio()转换为整形数字才可以进行比较
			{
				Temp = *pf;
				*pf = *pb;
				*pb = Temp;   //互换指针中的地址
				Temp.pNext = pf->pNext;
				pf->pNext = pb->pNext;
				pb->pNext = Temp.pNext; //更改原指针域的指向
			}
			pb = pb->pNext;
		}
		pf = pf->pNext;
	}
	printf("**************** 按学号顺序输出学生成绩****************\n");
	PrintfStudentInfo(pList);
	printf("7.按学号由小到大排出成绩表执行完毕,请选则其他功能:");
}

8.按姓名的字符顺序排出成绩表;

VOID Sort_StudentName(STUDENT* pList)		            //8.按姓名的字符顺序排出成绩表;
{
	printf("您选择的功能是 按姓名的字符顺序排出成绩表;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pb, * pf, Temp;
	pf = pList;

	if (pList == NULL) //链表为空
	{
		printf("链表为空.\n");
		return;
	}
	if (pList->pNext == NULL) //链表有1个节点
	{
		printf("链表只有1个节点.\n");
		return;
	}
	while (pf->pNext != NULL)//以pf指向的节点为基准节点
	{
		pb = pf->pNext;//pb从基准点的下一个节点开始
		while (pb != NULL)
		{
			if (strcmp(pb->stName,pf->stName)<0) //姓名是字符数组。要使用字符串比较函数 strcmp()进行比较
			{
				Temp = *pf;
				*pf = *pb;
				*pb = Temp;   //互换指针中的地址
				Temp.pNext = pf->pNext;
				pf->pNext = pb->pNext;
				pb->pNext = Temp.pNext; //更改原指针域的指向
			}
			pb = pb->pNext;
		}
		pf = pf->pNext;
	}
	printf("**************** 按姓名字符顺序输出学生成绩****************\n");
	PrintfStudentInfo(pList);
	printf("8.按姓名的字符顺序排出成绩表执行完毕,请选则其他功能:");
}

9.__.按学号查询学生排名及其考试成绩;

VOID LookUp_StudentId(STUDENT* pList)	                //9.__.按学号查询学生排名及其考试成绩;
{
	printf("您选择的功能是 按学号查询学生排名及其考试成绩;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	pList = Sort_(pList);  //调用排序函数对学生成绩进行排名
	int StudentId = 0;
	printf("请输入要查找的学生学号:");
	scanf("%d", &StudentId);  //输入学号
	STUDENT* pTemp = pList;
	
	while (pTemp) //录入学生信息时已经验证过学号是否唯一,所以直接遍历链表,查找相同的学号
	{
		if (StudentId == atoi(pTemp->StudentId)) //atoi()字符串转换为整形进行比较
		{		
        	printf("第%d名:", pTemp->Rank);     //输出按学号查找到的学生的名次和信息
			printf("姓名: %s ", pTemp->stName);
			printf("学号:%s ", pTemp->StudentId);
			printf("数学:%.2f ", pTemp->Score.maths);
			printf("英语:%.2f ", pTemp->Score.English);
			printf("政治:%.2f ", pTemp->Score.Politics);
			printf("物理:%.2f ", pTemp->Score.Physics);
			printf("计算机:%.2f ", pTemp->Score.computer);
			printf("总分数:%.2f ", pTemp->TotalScore);
			printf("平均分:%.2f\n", pTemp->Average);	
			printf("9.按学号查询学生排名及其考试成绩执行完毕,请选则其他功能:");
			return;
		}
		pTemp = pTemp->pNext;
	}
	printf(" 未找到该学生信息,请确认输入信息是否正确:\n");
	printf("9.按学号查询学生排名及其考试成绩执行完毕,请选则其他功能:");
	return;
}

10.按姓名查询学生排名及其考试成绩;需要考虑学生重名的情况。

VOID LookUp_StudentName(STUDENT* pList)		            //10.按姓名查询学生排名及其考试成绩;需要考虑学生重名的情况。
{
	printf("您选择的功能是 按姓名查询学生排名及其考试成绩;\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	pList = Sort_(pList);  //调用排序函数对学生成绩进行排名
	char StudentName[20] = { 0 };
	printf("请输入要查找的学生姓名:");
	scanf("%s", StudentName);  //输入学生姓名
	STUDENT* pTemp = pList;
	int count = 0;
	while (pTemp)
	{
		if (strcmp(StudentName, pTemp->stName) == 0)
			    count++;
		pTemp = pTemp->pNext;
	}
	if (count > 1)    //判断是否有同名学生
	{
		printf("您输入的姓名有同名情况。请选择功能 9 输入学号进行查询\n");
		printf("10.按学号查询学生排名及其考试成绩执行完毕,请选则其他功能:");
		return;
	}
	pTemp = pList;
	while (pTemp)     //遍历链表,查找相同的学号
	{
		if (strcmp(StudentName,pTemp->stName) == 0) // 对比姓名字符串
		{
			printf("第%d名:", pTemp->Rank);    //输出按姓名查找到的学生的名次和信息
			printf("姓名: %s ", pTemp->stName);
			printf("学号:%s ", pTemp->StudentId);
			printf("数学:%.2f ", pTemp->Score.maths);
			printf("英语:%.2f ", pTemp->Score.English);
			printf("政治:%.2f ", pTemp->Score.Politics);
			printf("物理:%.2f ", pTemp->Score.Physics);
			printf("计算机:%.2f ", pTemp->Score.computer);
			printf("总分数:%.2f ", pTemp->TotalScore);
			printf("平均分:%.2f\n", pTemp->Average);
			printf("10.按学号查询学生排名及其考试成绩执行完毕,请选则其他功能:");
			return;
		}
		pTemp = pTemp->pNext;
	}
	printf(" 未找到该学生信息,请确认输入信息是否正确:\n");
	printf("10.按姓名查询学生排名及其考试成绩执行完毕,请选则其他功能:");
	return;
}		

11.对每门课程分别统计每个类别的人数以及所占的百分比;并将统计结果输出;

VOID StatScore(STUDENT* pList)		                    //11.对每门课程分别统计每个类别的人数以及所占的百分比;并将统计结果输出
{
	printf("您选择的功能是 对每门课程分别统计每个类别的人数以及所占的百分比");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	STUDENT* pTemp = pList;
	unsigned int Score = 0;
	int Math_A = 0, Math_B = 0, Math_C = 0, Math_D = 0, Math_E = 0;
	int English_A = 0, English_B = 0, English_C = 0, English_D = 0, English_E = 0;
	int Politics_A = 0, Politics_B = 0, Politics_C = 0, Politics_D = 0, Politics_E = 0;
	int Physics_A = 0, Physics_B = 0, Physics_C = 0, Physics_D = 0, Physics_E = 0;
	int computer_A = 0, computer_B = 0, computer_C = 0, computer_D = 0, computer_E = 0;

	while (pTemp)
	{
		Score = pTemp->Score.maths; //数学分数
		if (Score >= 90){Math_A++;}
		else if (Score < 90 && Score >= 80){Math_B++;}
		else if (Score < 80 && Score >= 70){Math_C++;}
		else if (Score < 70 && Score >= 60){Math_D++;}
		else if (Score < 60 && Score >= 0) {Math_E++;}
		Score = pTemp->Score.English; //英语分数
		if (Score >= 90) { English_A++; }
		else if (Score < 90 && Score >= 80) { English_B++; }
		else if (Score < 80 && Score >= 70) { English_C++; }
		else if (Score < 70 && Score >= 60) { English_D++; }
		else if (Score < 60 && Score >= 0) { English_E++; }
		Score = pTemp->Score.Politics; //政治分数
		if (Score >= 90) { Politics_A++; }
		else if (Score < 90 && Score >= 80) { Politics_B++; }
		else if (Score < 80 && Score >= 70) { Politics_C++; }
		else if (Score < 70 && Score >= 60) { Politics_D++; }
		else if (Score < 60 && Score >= 0) { Politics_E++; }
		Score = pTemp->Score.Physics; //物理分数
		if (Score >= 90) { Physics_A++; }
		else if (Score < 90 && Score >= 80) { Physics_B++; }
		else if (Score < 80 && Score >= 70) { Physics_C++; }
		else if (Score < 70 && Score >= 60) { Physics_D++; }
		else if (Score < 60 && Score >= 0) { Physics_E++; }
		Score = pTemp->Score.computer; //计算机分数
		if (Score >= 90) { computer_A++; }
		else if (Score < 90 && Score >= 80) { computer_B++; }
		else if (Score < 80 && Score >= 70) { computer_C++; }
		else if (Score < 70 && Score >= 60) { computer_D++; }
		else if (Score < 60 && Score >= 0) { computer_E++; }
		pTemp = pTemp->pNext;
	}
	float n = N;
	//A优秀 B良好 C中等 D及格 E不及格5个类别,
	printf("\n");
	printf("数学: 优秀 %d人,占比%.2f%%  良好 %d人,占比%.2f%%  中等 %d人,占比%.2f%%  及格 %d人,占比%.2f%%  不及格 %d人,占比%.2f%%\n",
		Math_A, Math_A /n*100.0, Math_B, Math_B /n*100.0, Math_C, Math_C /n*100.0, Math_D, Math_D /n*100.0, Math_E, Math_E /n*100.0);
	printf("英语: 优秀 %d人,占比%.2f%%  良好 %d人,占比%.2f%%  中等 %d人,占比%.2f%%  及格 %d人,占比%.2f%%  不及格 %d人,占比%.2f%%\n",
		English_A, English_A /n*100.0, English_B, English_B /n*100.0, English_C, English_C /n*100.0, English_D, English_D /n*100.0, English_E, English_E /n*100.0);
	printf("政治: 优秀 %d人,占比%.2f%%  良好 %d人,占比%.2f%%  中等 %d人,占比%.2f%%  及格 %d人,占比%.2f%%  不及格 %d人,占比%.2f%%\n",
		Politics_A, Politics_A /n*100.0, Politics_B, Politics_B /n*100.0, Politics_C, Politics_C /n*100.0, Politics_D, Politics_D /n*100.0, Politics_E, Politics_E /n*100.0);
	printf("物理: 优秀 %d人,占比%.2f%%  良好 %d人,占比%.2f%%  中等 %d人,占比%.2f%%  及格 %d人,占比%.2f%%  不及格 %d人,占比%.2f%%\n",
		Physics_A, Physics_A /n*100.0, Physics_B, Physics_B /n*100.0, Physics_C, Physics_C /n*100.0, Physics_D, Physics_D /n*100.0, Physics_E, Physics_E /n*100.0);
	printf("计算机:优秀 %d人,占比%.2f%% 良好 %d人,占比%.2f%%  中等 %d人,占比%.2f%%  及格 %d人,占比%.2f%%  不及格 %d人,占比%.2f%%\n",
		computer_A, computer_A /n*100.0, computer_B, computer_B /n*100.0, computer_C, computer_C /n*100.0, computer_D, computer_D /n*100.0, computer_E, computer_E /n*100.0);
	printf("11.对每门课程分别统计每个类别的人数以及所占的百分比,并将统计结果输出功能执行完毕,请选则其他功能:");
	return;
}

12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分;

VOID OutStudentInfo(STUDENT* pList)                     //12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分;
{	
	printf("您选择的功能是 12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分\n");
	if (pList == NULL)
	{
		printf("没有录入学生信息。请选择【功能13】将每个学生的信息和成绩写入文件或【功能1】从文件读入每个学生信息.在使用此选项:\n");
		return;
	}
	PrintfStudentInfo(pList);   //调用PrintfStudentInfo函数输出学生信息
	printf("12.输出每个学生的学号、姓名、各科考试成绩、总分和平均分功能执行完毕,请选则其他功能:");
	return;
}

13.将每个学生的个人信息和成绩写入文件,可由键盘输入文件名;

STUDENT* StudentInfoToFile()                  //13.将每个学生的个人信息和成绩写入文件,可由键盘输入文件名;
{
	STUDENT* pList = NULL;
	printf("您选择的功能是 将每个学生的个人信息和成绩写入文件,可由键盘输入文件名\n");
	pList = InitStudentInfo();    //调用读取函数 InitStudentInfot();进行初始化学生信息
	if (pList == NULL)
	{
		printf("录入学生信息失败:\n");
		return NULL;
	}
	printf("共录入了%d名学生信息",N);
	printf("将每个学生的个人信息和成绩写入文件功能执行完毕,请选则其他功能:");
	return pList;
}  

麻烦大家点赞关注,谢谢。有其他需要的同学可以私信留言!

  • 52
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值