使用链表实现成绩管理系统
完成的功能如下:
1.增加成绩信息
2.查询成绩信息
3.删除成绩信息
4.修改信息
5.成绩的打印
6.成绩信息的排序
7.成绩信息的统计
8.保存信息到文件
9.从文件中读取信息
一、为什么使用链表,链表是什么?
二、代码
1.定义数据的结构体和链表节点的结构体
代码如下(示例):
#define MAX_NAME 15
#define MAX_ID 15
typedef struct Student //定义结构体
{
char name[MAX_NAME];
char id[MAX_ID];
float score[3];
float total;
float average;
}Student;
typedef Student SLTDataType;
//单链表的定义
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next; //next指向当前节点的下一个节点
}SListNode;
2.创建表头函数,这里使用的是有头链表
代码如下(示例):
//创建表头
SListNode* CreateHead()
{
SListNode* plist = (SListNode *)malloc(sizeof(SListNode));
//判断申请是否成功
if (plist == NULL)
{
printf("创建表头失败!\n");
exit(-1);//退出
}
plist->next = NULL;
return plist;
}
返回plist表示头节点的地址,后面会频繁使用,每次都是从头节点开始进行一系列功能实现。
3.开辟一个新节点,返回节点的地址
代码如下(示例):
//动态申请一个节点,返回新申请结点的地址
SListNode* BuyListNode(const SLTDataType x)
{
SListNode* plist = (SListNode *)malloc(sizeof(SListNode));
//判断申请是否成功
if (plist == NULL)
{
printf("申请新节点失败!\n");
exit(-1);
}
plist->data = x;
plist->next = NULL;
return plist;
}
形参用于把数据传入,进行更新,返回地址用于将此地址,赋值给上一个节点的next。
4.尾插数据,调用开辟新节点函数
代码如下(示例):
//单链表尾插数据
void AddSystem(SListNode** pplist)
{
Student s;
printf("请输入名字:>");
scanf("%s", s.name);
getchar();
printf("请输入学号:>");
scanf("%s", s.id);
getchar();
printf("请输入语文成绩:>");
scanf("%f", &(s.score[0]));
getchar();
printf("请输入数学成绩:>");
scanf("%f", &(s.score[1]));
getchar();
printf("请输入英语成绩:>");
scanf("%f", &(s.score[2]));
getchar();
s.total = s.score[0] + s.score[1] + s.score[2];
s.average = s.total / 3;
printf("录入成功!\n");
//申请一个新节点
SListNode* NewNode = BuyListNode(s);
//定义一个当前节点tail去找链表的尾节点
SListNode* tail = *pplist;
//遍历节点找尾节点
while (tail->next != NULL)
{
tail = tail->next;
}
//尾节点的next指向新节点
tail->next = NewNode;
}
while循环用来找尾,找到NULL停止,则代表这个是尾巴,需要将新开辟的节点地址挂载到这个尾巴!
5.通过姓名查找 -> 查找到打印即可,查找同样是遍历找NULL的过程
代码如下(示例):
//查询人的信息
void SearchSystem(const SListNode* plist)
{
SListNode* cur = plist->next;
int flag = 0;
while (1)
{
char input[5];
printf("请输入你要查询的方式,学号 or 姓名:>");
scanf("%s", input);
getchar();
if (strcmp(input, "姓名") == 0)
{
char Name[MAX_NAME];
printf("请输入你要查询的名字:>");
scanf("%s", Name);
getchar();
//遍历链表
while (cur != NULL)
{
//如果找节点值等于x则返回
if (0 == strcmp(cur->data.name, Name))
{
flag = 1;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
break;
}
//没找到继续遍历
cur = cur->next;
}
if (0 == flag)
{
printf("查无此人!\n");
}
break;
}
else if (strcmp(input, "学号") == 0)
{
char Id[MAX_ID];
printf("请输入你要查询的学号:>");
scanf("%s", Id);
getchar();
while (cur != NULL)
{
//如果找节点值等于x则返回
if (0 == strcmp(cur->data.id, Id))
{
flag = 1;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
break;
}
//没找到继续遍历
cur = cur->next;
}
if (0 == flag)
{
printf("查无此人!\n");
}
break;
}
else
{
printf("输入错误,请重新输入!\n");
}
}
}
6.查找函数 -> 返回查找到的前一个地址(原因见下图)
代码如下(示例):
//单链表查找
static SListNode* SListFind(const SListNode* plist, char name[])
{
SListNode* cur = plist->next;
SListNode* pos = plist;
//1.空链表直接返回
if (cur == NULL)
{
return NULL;
}
//遍历链表
while (cur!= NULL)
{
//如果找节点值等于x则返回
if (strcmp(cur->data.name, name) == 0)
{
return pos;
}
//没找到继续遍历
pos = pos->next;
cur = cur->next;
}
return NULL;
}
7.删除函数 -> 通过查找名字函数返回的该删除的前一个地址对信息进行删除,并进行节点的更新!
代码如下(示例):
//删除人的信息
void DelSystem(SListNode** pplist)
{
assert(*pplist);
char name[MAX_NAME];
printf("请输入要删除人的名字:>");
scanf("%s", name);
getchar();
SListNode* cur = (*pplist)->next;
SListNode* del = SListFind(*pplist, name);
if (del == NULL)
{
printf("要删除的人不存在!\n");
}
else
{
SListNode* tmp = del->next->next;
free(del->next);//释放
del->next = tmp;
printf("删除成功!\n");
}
}
8.修改函数 -> 找到要修改的名字,通过查找函数函数前一个的地址,然后通过next找到这个要修改的节点
代码如下(示例):
//修改人的信息
void ModifySystem(SListNode** pplist)
{
assert(*pplist);
char name[MAX_NAME];
printf("请输入要修改人的名字:>");
scanf("%s", name);
getchar();
SListNode* mod = SListFind(*pplist, name);
if (NULL == mod)
{
printf("要修改的人不存在!\n");
}
else
{
mod = mod->next;
printf("请输入名字:>");
scanf("%s", mod->data.name);
getchar();
printf("请输入学号:>");
scanf("%s", mod->data.id);
getchar();
printf("请输入语文成绩:>");
scanf("%f", &(mod->data.score[0]));
getchar();
printf("请输入数学成绩:>");
scanf("%f", &(mod->data.score[1]));
getchar();
printf("请输入英语成绩:>");
scanf("%f", &(mod->data.score[2]));
getchar();
mod->data.total = mod->data.score[0] + mod->data.score[1] + mod->data.score[2];
mod->data.average = mod->data.total / 3;
printf("修改成功!\n");
}
}
9.打印函数 -> 方便我们及时观察录入的信息
代码如下(示例):
//成绩信息打印
void PrintSystem(const SListNode* plist)
{
SListNode* cur = plist->next;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
//打印链表
while (cur)
{
//printf("%d->", cur->data);
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
cur = cur->next; //节点指向下一个
}
}
10.排序,支持四种成绩的排序
代码如下(示例):
//语文成绩信息排序
static void SortChinese(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[0] < q->data.score[0])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//数学成绩信息排序
static void SortMath(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[1] < q->data.score[1])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//英语成绩信息排序
static void SortEnglish(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[2] < q->data.score[2])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//总分成绩信息排序
static void SortToal(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.total < q->data.total)
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
void SortSystem(SListNode** pplist)
{
assert(*pplist);
while (1)
{
char input[5];
printf("请输入按什么成绩排序, 语文 数学 英语 总分:>");
scanf("%s", input);
if (strcmp(input, "语文") == 0)
{
SortChinese(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "数学") == 0)
{
SortMath(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "英语") == 0)
{
SortEnglish(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "总分") == 0)
{
SortToal(pplist);
PrintSystem(*pplist);
break;
}
else
{
printf("输入错误!\n");
}
}
}
11.统计函数,统计科目以及一个分数段内的学生
代码如下(示例):
//成绩信息统计
void StatisticsSystem(const SListNode* plist)
{
char input[5];
int low = 0;
int high = 0;
int sum = 0;
printf("请输入统计信息的学科:>");
scanf("%s", input);
getchar();
printf("请输入学科成绩的下限:>");
scanf("%d", &low);
getchar();
printf("请输入学科成绩的上限:>");
scanf("%d", &high);
getchar();
SListNode* cur = plist->next;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
//打印链表
while (cur)
{
if (strcmp(input, "语文") == 0)
{
if (cur->data.score[0] >= low && cur->data.score[0] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else if (strcmp(input, "数学") == 0)
{
if (cur->data.score[1] >= low && cur->data.score[1] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else if (strcmp(input, "英语") == 0)
{
if (cur->data.score[2] >= low && cur->data.score[2] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else
{
printf("输入错误!\n");
break;
}
cur = cur->next; //节点指向下一个
}
printf(" **********************%s学科成绩在%d-%d之间共有%d个学生*********************** \n", input, low, high, sum);
}
12保存函数 ->保存信息到我们的文件
代码如下(示例):
//保存信息到文件
void SaveSystem(const SListNode* plist)
{
FILE* fp = fopen("Student_sorce.txt", "w+");
SListNode* cur = plist->next;
if (NULL == fp)
{
printf("打开文件失败!\n");
exit(-1);
}
else
{
while (cur)
{
fprintf(fp, "%s %s %.2f %.2f %.2f %.2f %.2f\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
cur = cur->next; //节点指向下一个
}
}
printf("保存成功!\n");
fclose(fp);
}
13读取函数 ->直接从文件内读取数据
代码如下(示例):
static void AddByRead(SListNode** pplist, const SLTDataType s)
{
//申请一个新节点
SListNode* NewNode = BuyListNode(s);
//定义一个当前节点tail去找链表的尾节点
SListNode* tail = *pplist;
//遍历节点找尾节点
while (tail->next != NULL)
{
tail = tail->next;
}
//尾节点的next指向新节点
tail->next = NewNode;
}
//读取信息到文件
void ReadSystem(SListNode** pplist)
{
FILE* fp = fopen("Student_sorce.txt", "r");
if (NULL == fp)
{
printf("打开%s文件失败!\n", "Student_sorce.txt");
exit(-1);
}
int i = 0;
int lineCount = 0;//行数
while (!feof(fp))
{
char flag = fgetc(fp);
if (flag == '\n')
lineCount++;
}
rewind(fp);//重新返回文件开头
Student s;
while (i < lineCount)
{
fscanf(fp, "%s %s %f %f %f %f %f", s.name, s.id, &(s.score[0]), &(s.score[1]), &(s.score[2]), &(s.total), &(s.average));
AddByRead(pplist, s);
i++;
}
printf("读取成功!\n");
fclose(fp);
}
三、所有代码
代码如下(示例):
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "score.h"
enum Optinon
{
Exit,//0
Add,//1
Del,//2
Search,//3
Show,//4
Modify,
Sort,
Statistics,
Save,
Read,
};
void menu()
{
printf("************* 成绩管理系统 ****************\n");
printf("***** 1. Add 2. Del *******\n");
printf("***** 3. Search 4. Show *******\n");
printf("***** 5. Modify 6. Sort *******\n");
printf("***** 7. Statistics 8. Save *******\n");
printf("***** 9. Read 0. Exit *******\n");
printf("*********************************************\n");
}
int main()
{
SListNode* Plist = CreateHead(); //定义一个单链表
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case Add:
AddSystem(&Plist);
break;
case Del:
DelSystem(&Plist);
break;
case Search:
SearchSystem(Plist);
break;
case Show:
PrintSystem(Plist);
break;
case Modify:
ModifySystem(&Plist);
break;
case Sort:
SortSystem(&Plist);
break;
case Statistics:
StatisticsSystem(Plist);
break;
case Save:
SaveSystem(Plist);
break;
case Read:
ReadSystem(&Plist);
break;
case Exit:
printf("退出该系统\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
score.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 15
#define MAX_ID 15
typedef struct Student //定义结构体
{
char name[MAX_NAME];
char id[MAX_ID];
float score[3];
float total;
float average;
}Student;
typedef Student SLTDataType;
//单链表的定义
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next; //next指向当前节点的下一个节点
}SListNode;
//创建表头
SListNode* CreateHead();
//动态申请一个节点,返回新申请结点的地址
SListNode* BuyListNode(const SLTDataType x);
//单链表尾插数据
void AddSystem(SListNode** pplist);
//查询成绩信息
void SearchSystem(const SListNode* plist);
//删除成绩信息
void DelSystem(SListNode** pplist);
//修改人的信息
void ModifySystem(SListNode** pplist);
//成绩信息打印
void PrintSystem(const SListNode* plist);
//成绩信息排序
void SortSystem(SListNode** pplist);
//成绩信息统计
void StatisticsSystem(const SListNode* plist);
//保存信息到文件
void SaveSystem(const SListNode* plist);
//读取信息到文件
void ReadSystem(SListNode** pplist);
score.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "score.h"
//创建表头
SListNode* CreateHead()
{
SListNode* plist = (SListNode *)malloc(sizeof(SListNode));
//判断申请是否成功
if (plist == NULL)
{
printf("创建表头失败!\n");
exit(-1);//退出
}
plist->next = NULL;
return plist;
}
//动态申请一个节点,返回新申请结点的地址
SListNode* BuyListNode(const SLTDataType x)
{
SListNode* plist = (SListNode *)malloc(sizeof(SListNode));
//判断申请是否成功
if (plist == NULL)
{
printf("申请新节点失败!\n");
exit(-1);
}
plist->data = x;
plist->next = NULL;
return plist;
}
//单链表尾插数据
void AddSystem(SListNode** pplist)
{
Student s;
printf("请输入名字:>");
scanf("%s", s.name);
getchar();
printf("请输入学号:>");
scanf("%s", s.id);
getchar();
printf("请输入语文成绩:>");
scanf("%f", &(s.score[0]));
getchar();
printf("请输入数学成绩:>");
scanf("%f", &(s.score[1]));
getchar();
printf("请输入英语成绩:>");
scanf("%f", &(s.score[2]));
getchar();
s.total = s.score[0] + s.score[1] + s.score[2];
s.average = s.total / 3;
printf("录入成功!\n");
//申请一个新节点
SListNode* NewNode = BuyListNode(s);
//定义一个当前节点tail去找链表的尾节点
SListNode* tail = *pplist;
//遍历节点找尾节点
while (tail->next != NULL)
{
tail = tail->next;
}
//尾节点的next指向新节点
tail->next = NewNode;
}
//查询人的信息
void SearchSystem(const SListNode* plist)
{
SListNode* cur = plist->next;
int flag = 0;
while (1)
{
char input[5];
printf("请输入你要查询的方式,学号 or 姓名:>");
scanf("%s", input);
getchar();
if (strcmp(input, "姓名") == 0)
{
char Name[MAX_NAME];
printf("请输入你要查询的名字:>");
scanf("%s", Name);
getchar();
//遍历链表
while (cur != NULL)
{
//如果找节点值等于x则返回
if (0 == strcmp(cur->data.name, Name))
{
flag = 1;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
break;
}
//没找到继续遍历
cur = cur->next;
}
if (0 == flag)
{
printf("查无此人!\n");
}
break;
}
else if (strcmp(input, "学号") == 0)
{
char Id[MAX_ID];
printf("请输入你要查询的学号:>");
scanf("%s", Id);
getchar();
while (cur != NULL)
{
//如果找节点值等于x则返回
if (0 == strcmp(cur->data.id, Id))
{
flag = 1;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
break;
}
//没找到继续遍历
cur = cur->next;
}
if (0 == flag)
{
printf("查无此人!\n");
}
break;
}
else
{
printf("输入错误,请重新输入!\n");
}
}
}
//单链表查找
static SListNode* SListFind(const SListNode* plist, char name[])
{
SListNode* cur = plist->next;
SListNode* pos = plist;
//1.空链表直接返回
if (cur == NULL)
{
return NULL;
}
//遍历链表
while (cur!= NULL)
{
//如果找节点值等于x则返回
if (strcmp(cur->data.name, name) == 0)
{
return pos;
}
//没找到继续遍历
pos = pos->next;
cur = cur->next;
}
return NULL;
}
//删除人的信息
void DelSystem(SListNode** pplist)
{
assert(*pplist);
char name[MAX_NAME];
printf("请输入要删除人的名字:>");
scanf("%s", name);
getchar();
SListNode* cur = (*pplist)->next;
SListNode* del = SListFind(*pplist, name);
if (del == NULL)
{
printf("要删除的人不存在!\n");
}
else
{
SListNode* tmp = del->next->next;
free(del->next);//释放
del->next = tmp;
printf("删除成功!\n");
}
}
//修改人的信息
void ModifySystem(SListNode** pplist)
{
assert(*pplist);
char name[MAX_NAME];
printf("请输入要修改人的名字:>");
scanf("%s", name);
getchar();
SListNode* mod = SListFind(*pplist, name);
if (NULL == mod)
{
printf("要修改的人不存在!\n");
}
else
{
mod = mod->next;
printf("请输入名字:>");
scanf("%s", mod->data.name);
getchar();
printf("请输入学号:>");
scanf("%s", mod->data.id);
getchar();
printf("请输入语文成绩:>");
scanf("%f", &(mod->data.score[0]));
getchar();
printf("请输入数学成绩:>");
scanf("%f", &(mod->data.score[1]));
getchar();
printf("请输入英语成绩:>");
scanf("%f", &(mod->data.score[2]));
getchar();
mod->data.total = mod->data.score[0] + mod->data.score[1] + mod->data.score[2];
mod->data.average = mod->data.total / 3;
printf("修改成功!\n");
}
}
//成绩信息打印
void PrintSystem(const SListNode* plist)
{
SListNode* cur = plist->next;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
//打印链表
while (cur)
{
//printf("%d->", cur->data);
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
cur = cur->next; //节点指向下一个
}
}
//语文成绩信息排序
static void SortChinese(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[0] < q->data.score[0])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//数学成绩信息排序
static void SortMath(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[1] < q->data.score[1])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//英语成绩信息排序
static void SortEnglish(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.score[2] < q->data.score[2])
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
//总分成绩信息排序
static void SortToal(SListNode** pplist)
{
for (SListNode* p = (*pplist)->next; p != NULL; p = p->next)
{
for (SListNode* q = p->next; q != NULL; q = q->next)
{
if (p->data.total < q->data.total)
{
SListNode tmp;
tmp.data = p->data;
p->data = q->data;
q->data = tmp.data;
}
}
}
}
void SortSystem(SListNode** pplist)
{
assert(*pplist);
while (1)
{
char input[5];
printf("请输入按什么成绩排序, 语文 数学 英语 总分:>");
scanf("%s", input);
if (strcmp(input, "语文") == 0)
{
SortChinese(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "数学") == 0)
{
SortMath(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "英语") == 0)
{
SortEnglish(pplist);
PrintSystem(*pplist);
break;
}
else if (strcmp(input, "总分") == 0)
{
SortToal(pplist);
PrintSystem(*pplist);
break;
}
else
{
printf("输入错误!\n");
}
}
}
//成绩信息统计
void StatisticsSystem(const SListNode* plist)
{
char input[5];
int low = 0;
int high = 0;
int sum = 0;
printf("请输入统计信息的学科:>");
scanf("%s", input);
getchar();
printf("请输入学科成绩的下限:>");
scanf("%d", &low);
getchar();
printf("请输入学科成绩的上限:>");
scanf("%d", &high);
getchar();
SListNode* cur = plist->next;
printf("%-15s\t%-15s\t%-8s\t%-8s\t%-8s\t%-8s\t%-8s\n", "名字", "学号", "语文", "数学", "英语", "总分", "平均分");
//打印链表
while (cur)
{
if (strcmp(input, "语文") == 0)
{
if (cur->data.score[0] >= low && cur->data.score[0] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else if (strcmp(input, "数学") == 0)
{
if (cur->data.score[1] >= low && cur->data.score[1] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else if (strcmp(input, "英语") == 0)
{
if (cur->data.score[2] >= low && cur->data.score[2] <= high)
{
printf("%-15s\t%-15s\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\t%-8.2lf\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
sum++;
}
}
else
{
printf("输入错误!\n");
break;
}
cur = cur->next; //节点指向下一个
}
printf(" **********************%s学科成绩在%d-%d之间共有%d个学生*********************** \n", input, low, high, sum);
}
//保存信息到文件
void SaveSystem(const SListNode* plist)
{
FILE* fp = fopen("Student_sorce.txt", "w+");
SListNode* cur = plist->next;
if (NULL == fp)
{
printf("打开文件失败!\n");
exit(-1);
}
else
{
while (cur)
{
fprintf(fp, "%s %s %.2f %.2f %.2f %.2f %.2f\n", cur->data.name,
cur->data.id,
cur->data.score[0],
cur->data.score[1],
cur->data.score[2],
cur->data.total,
cur->data.average);
cur = cur->next; //节点指向下一个
}
}
printf("保存成功!\n");
fclose(fp);
}
static void AddByRead(SListNode** pplist, const SLTDataType s)
{
//申请一个新节点
SListNode* NewNode = BuyListNode(s);
//定义一个当前节点tail去找链表的尾节点
SListNode* tail = *pplist;
//遍历节点找尾节点
while (tail->next != NULL)
{
tail = tail->next;
}
//尾节点的next指向新节点
tail->next = NewNode;
}
//读取信息到文件
void ReadSystem(SListNode** pplist)
{
FILE* fp = fopen("Student_sorce.txt", "r");
if (NULL == fp)
{
printf("打开%s文件失败!\n", "Student_sorce.txt");
exit(-1);
}
int i = 0;
int lineCount = 0;//行数
while (!feof(fp))
{
char flag = fgetc(fp);
if (flag == '\n')
lineCount++;
}
rewind(fp);//重新返回文件开头
Student s;
while (i < lineCount)
{
fscanf(fp, "%s %s %f %f %f %f %f", s.name, s.id, &(s.score[0]), &(s.score[1]), &(s.score[2]), &(s.total), &(s.average));
AddByRead(pplist, s);
i++;
}
printf("读取成功!\n");
fclose(fp);
}
四、总结
学习了链表,自己动手实现了这样一个简单的系统,需要源代码请留言!