student.c
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.h"
void makeMenu() // 制作菜单
{
// 排序+文件
printf("---------【链式学生管理系统】---------\n");
printf("\t\t0.退出功能\n");
printf("\t\t1.录入功能\n");
printf("\t\t2.浏览功能\n");
printf("\t\t3.查找功能\n");
printf("\t\t4.修改功能\n");
printf("\t\t5.删除功能\n");
printf("\t\t6.按照分数进行排序\n");
printf("\t\t7.保存到文件\n");
printf("-------------------------------------\n");
printf("请输入(0~7):");
}
// 根据分数排序
void sort_sorce(Node *headnode)
{
Node *temp;
Node *e_pre = headnode; // 外层前一个节点
Node *e_index = headnode->next; // 外层当前节点
Node *pre = headnode; // 前一个节点
Node *index = headnode->next; // 当前节点
if (e_index == NULL)
{
printf("没有数据\n");
return;
}
while (e_index->next) // 预防野指针
{
while (index)
{
if (e_index->data.sorce > index->data.sorce) // 如果前面的大于后面的
{
if (e_index != pre)
{
detelt_node(list, index); // 删除当前节点
detelt_node(list, e_index);
index->next = e_pre->next; // 内层这个跑到外层
e_pre->next = index;
e_index->next = pre->next; // 外层跑到内层
pre->next = e_index;
}
else if (e_index == pre) // 挨边两个进行交换了
{
detelt_node(list, index);
index->next = e_pre->next;
e_pre->next = index;
pre = index;
}
temp = e_index; // 两个指针进行交换
e_index = index;
index = temp;
}
pre = pre->next;
index = index->next;
}
e_index = e_index->next; // 更新外层指针指向节点
e_pre = e_pre->next;
index = e_index->next; // 更新内层指针指向的节点
pre = e_index;
}
}
// 删除指定节点
void detelt_node(Node *headnode, Node *dest)
{
Node *pre = headnode; // 头节点
Node *cur = headnode->next; // 第一个节点
while ((cur != NULL) && cur != dest)
{
pre = cur;
cur = cur->next;
}
if (cur != NULL)
{
Node *node = cur;
pre->next = cur->next;
}
else
printf("删除失败,没有目标节点\n");
}
// 创建节点
Node *creatNode(struct student data)
{
Node *newNode = (Node *)malloc(sizeof(Node));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 创建头节点
Node *creatHead()
{
Node *headHead = (Node *)malloc(sizeof(Node));
assert(headHead);
headHead->next = NULL;
return headHead;
}
// 插入节点 头插法
void insertData(Node *headnode, struct student stu)
{
Node *newData = creatNode(stu);
newData->next = headnode->next;
headnode->next = newData;
}
// 根据名字删除节点
void detelenode(Node *headnode, const char *name)
{
Node *pre = headnode; // 头节点
Node *cur = headnode->next; // 第一个节点
while ((cur != NULL) && (strcmp(cur->data.name, name)))
{
pre = cur;
cur = cur->next;
}
if (cur != NULL)
{
Node *node = cur;
pre->next = cur->next;
free(node);
}
else
printf("删除失败,没有找到数据\n");
}
// 查询
Node *searchByName(Node *headnode, const char *name)
{
Node *searchnode = headnode;
while (searchnode != NULL && (strcmp(searchnode->data.name, name)))
{
searchnode = searchnode->next;
}
if (searchnode != NULL)
{
return searchnode;
}
else
printf("查询错误,没有该信息");
return NULL;
}
// 打印节点
void printList(Node *headnode)
{
Node *pmove = headnode->next; // 第一个节点
printf("姓名\t分数\t年龄\n");
while (pmove != NULL)
{
printf("%s\t%d\t%d\n", pmove->data.name,
pmove->data.sorce, pmove->data.age);
pmove = pmove->next;
}
}
// 修改节点
void update_node(Node *headnode, const char *name)
{
struct student stu;
Node *node = searchByName(headnode, name);
if (node)
{
printf("请重新输入学生的信息:\n");
printf("name:\n");
scanf("%s", stu.name);
printf("sorce:\n");
scanf("%d", &stu.sorce);
printf("age:\n");
scanf("%d", &stu.age);
memcpy(&node->data, &stu, sizeof(stu));
}
else
printf("不存在该学生信息\n");
}
// 保存到文件
void saveToFile(Node *headnode, const char *fileName)
{
Node *index = headnode->next;
FILE *fp = fopen(fileName, "w");
if (fp == NULL)
{
printf("打开失败\n");
return;
}
while (index)
{
fprintf(fp, "%s\t%d\t%d\n", index->data.name,
index->data.sorce, index->data.age);
index = index->next;
}
printf("保存成功\n");
fclose(fp);
}
void readFromFile(Node *headNode, const char *fileName)
{
stu student;
FILE *fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("打开失败\n");
return;
}
while (fscanf(fp, "%s\t%d\t%d\n", student.name, &student.sorce, &student.age) != EOF)
{
insertData(headNode, student);
}
fclose(fp);
}
void keyDown()
{
int key;
struct student stu;
char *name;
scanf("%d", &key);
switch (key)
{
case 0:
printf("退出模块....\n");
system("pause");
exit(0);
break;
case 1:
printf("录入信息...\n");
printf("请输入学生信息(name,sorce,age)\n");
scanf("%s%d%d", stu.name, &stu.sorce, &stu.age);
insertData(list, stu);
break;
case 2:
printf("----【浏览功能】----\n");
printList(list);
break;
case 3:
printf("请输入要查询的学生姓名:\n");
scanf("%s", name);
printf("name:%s sorce:%d age:%d\n", searchByName(list, name)->data.name,
searchByName(list, name)->data.sorce, searchByName(list, name)->data.age);
break;
case 4:
printf("请输入要修改的学生姓名:\n");
scanf("%s", name);
update_node(list, name);
break;
case 5:
printf("请输入要删除的学生姓名:\n");
scanf("%s", name);
detelenode(list, name);
break;
case 6:
sort_sorce(list);
break;
case 7:
saveToFile(list, "student.txt");
break;
default:
break;
}
}
int main()
{
list = creatHead();
stu init1[5] = {
{"ta1", 30, 10},
{"ta4", 50, 10},
{"ta2", 10, 10},
{"ta5", 40, 10},
{"hah", 9, 10},
};
for (int i = 0; i < 5; i++)
{
insertData(list, init1[i]);
}
while (1)
{
makeMenu();
keyDown();
}
}
student.h
#ifndef _STUDENT_H
#define _STUDENT_H
typedef struct student
{
char name[20];
char sorce;
char age;
} stu;
typedef struct Node
{
struct student data;
struct Node *next;
} Node;
Node *list;
// 创建节点
Node *creatNode(struct student data);
// 创建头节点
Node *creatHead();
// 插入节点 头插法
void insertData(Node *headnode, struct student stu);
// 根据名字删除节点
void detelenode(Node *headnode, const char *name);
// 查询
Node *searchByName(Node *headnode, const char *name);
// 打印
void printList(Node *headnode);
// 按键输入
void keyDown();
void makeMenu(); // 制作菜单
// 根据分数排序
void sort_sorce(Node *headnode);
// 删除指定节点
void detelt_node(Node *headnode, Node *dest);
// 修改节点
void update_node(Node *headnode, const char *name);
#endif