基于链表实现的链式管理系统(C语言课设)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct Logincheck

{

char account[1000];

int choose;

}Login;

typedef struct Student

{

char num[100];

char name[20];

int grade;

}Stu;

typedef struct ListNode

{

Stu student;

struct ListNode* next;

}ListNode;

//创建头节点

ListNode* createHead()

{

ListNode* Head = (ListNode*)malloc(sizeof(ListNode));

if (Head == NULL)

return NULL;

Head->next = NULL;

return Head;

}

//创建节点

ListNode* createNode(Stu student)

{

ListNode* pcur = (ListNode*)malloc(sizeof(ListNode));

if (pcur == NULL)

return NULL;

pcur->student = student;

pcur->next = NULL;

return pcur;

}

//数据判重

int is_repeat(char* num)

{

FILE* pf = fopen("学生数据.txt", "r");

while (1)

{

Stu judgedata = { 0 };

int judge = fscanf(pf, "%s%s%d", judgedata.num, judgedata.name, &judgedata.grade);

if (!strcmp(judgedata.num, num))

return 0;

if (judge == EOF)

return 1;

}

}

//插入节点

void insertNode(ListNode* head, Stu student)

{

ListNode* pcur = createNode(student);

pcur->next = head->next;

head->next = pcur;

}

//删除节点

void deleteNode(ListNode* head, char* num, FILE* pf)

{

ListNode* prev = head;

ListNode* pcur = head->next;

while (pcur && strcmp(pcur->student.num, num))

{

if (!strcmp(pcur->student.num, num))

{

prev->next = pcur->next;

free(pcur);

return;

}

prev = prev->next;

pcur = pcur->next;

}

if (!pcur)

{

printf("数据不存在,删除失败\n");

}

else

{

prev->next = pcur->next;

FILE* pfs = fopen("数据备份.txt", "a");//备份删除的数据,方便后续找回

fprintf(pfs, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);

fclose(pfs);

free(pcur);

pf = fopen("学生数据.txt", "w+");//打开一个临时文件,将删除后的数据拷贝在临时文件中,然后删除原文件

pcur = head->next;

while (pcur)

{

fprintf(pf, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);

pcur = pcur->next;

}

fclose(pf);

printf("删除成功!\n");

}

}

//打印链表

void printList(ListNode* head)

{

ListNode* pcur = head->next;

printf("编号\t姓名\t成绩\n");

while (pcur)

{

printf("%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);

pcur = pcur->next;

}

}

//查找节点

void seekNode(ListNode* head, char* num)

{

ListNode* pcur = head->next;

while (pcur && strcmp(pcur->student.num, num))

{

pcur = pcur->next;

}

if (pcur == NULL)

printf("数据不存在\n");

else

{

printf("编号姓名成绩\n");

printf("%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);

}

}

//修改节点

void modifyNode(ListNode* head, char* num, Stu student)

{

ListNode* pcur = head->next;

while (pcur && strcmp(pcur->student.num, num))

{

pcur = pcur->next;

}

if (pcur == NULL)

printf("要修改的数据不存在\n");

else if (!is_repeat(pcur->student.num))

printf("该编号已存在,请检查后重新修改!\n");

else

{

pcur->student = student;

FILE* pf = fopen("学生数据.txt", "w+");//将修改后的数据拷贝到文件中

pcur = head->next;

while (pcur)

{

fprintf(pf, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);

pcur = pcur->next;

}

printf("修改成功\n");

fclose(pf);

}

}

//登录界面

Login logInterface()

{

Login log;

printf("******************\n");

printf("请输入账户密码\n");

scanf("%s", log.account);

printf("请选择登录或注册(0.登录 1.注册)\n");

scanf("%d", &log.choose);

printf("******************\n");

return log;

}

//登录检测

char* loginCheck(Login log)

{

FILE* pf = NULL;

if (log.choose)//判断用户是要注册还是登录

{

pf = fopen("账户数据.txt", "a");

fprintf(pf, "%s\n", log.account);

printf("注册成功\n");

fclose(pf);

return "access";//注册成功,返回一个token

}

else if (log.choose == 0)

{

pf = fopen("账户数据.txt", "r");

if (pf == NULL)

printf("用户不存在!\n");

else

{

while (1)//比对数据,成功返回一个token

{

char strcheck[1000] = { 0 };

int judge = fscanf(pf, "%s", strcheck);

if (!strcmp(strcheck, log.account))

return "access";

if (judge == EOF)

break;

}

fclose(pf);

}

}

return "fail";

}

//菜单

void menu()

{

printf("******************\n");

printf("0.退出程序\n");

printf("1.浏览数据\n");

printf("2.录入数据\n");

printf("3.删除数据\n");

printf("4.修改数据\n");

printf("5.查找数据\n");

printf("6.恢复备份\n");

printf("7.按成绩排序\n");

printf("******************\n");

}

//文件操作

//数据初始化

void initData(FILE* pf, ListNode* head)

{

pf = fopen("学生数据.txt", "r");

if (pf == NULL)

printf("数据读取失败,请重试\n");

else

{

ListNode* pcur = head->next;

Stu student;

while (fscanf(pf, "%s%s%d", student.num, student.name, &student.grade) != EOF)

{

insertNode(head, student);

}

fclose(pf);

}

}

//数据保存

int saveData(FILE* pf, Stu student)

{

pf = fopen("学生数据.txt", "a");

if (pf == NULL)

printf("数据录入失败\n");

else if (!is_repeat(student.num))

printf("该编号已存在,请检查后重新录入!\n");

else

{

fprintf(pf, "%s\t%s\t%d\n", student.num, student.name, student.grade);//将录入的数据保存在文件中

printf("已成功录入\n");

return 1;

fclose(pf);

}

return 0;

}

//恢复备份

void restoreBackup(FILE* pf, char* num)

{

pf = fopen("学生数据.txt", "a");

FILE* pfs = fopen("数据备份.txt", "r");

if (pfs == NULL)

printf("该目录下没有数据备份,无法恢复\n");

else

{

Stu student;

int flag = 1;

while (fscanf(pfs, "%s%s%d", student.num, student.name, &student.grade) != EOF)

{

if (!strcmp(num, student.num))

{

fprintf(pf, "%s\t%s\t%d\n", student.num, student.name, student.grade);

flag = 0;

}

}

if (flag)

printf("要恢复的数据不存在\n");

else printf("已成功恢复备份!\n");

fclose(pf);

fclose(pfs);

}

}

//对数据进行排序

void sortData(ListNode* head)

{

for (ListNode* first = head->next; first != NULL; first = first->next)

{

for (ListNode* second = head->next; second != NULL; second = second->next)

{

if (second->next != NULL)

{

if (second->student.grade < second->next->student.grade)

{

Stu student = second->student;

second->student = second->next->student;

second->next->student = student;

}

}

}

}

}

//获取用户操作

void keyDown(ListNode* head, FILE* pf)

{

int input = 0;

printf("请用户选择操作方式\n");

scanf("%d", &input);

Stu student;

switch (input)

{

case 0:

printf("程序正在退出\n");

system("pause");

exit(0);

break;

case 1:

if (head->next == NULL)

printf("暂时没有数据,无法浏览\n");

else printList(head);

break;

case 2:

printf("请用户输入学生信息:\n");

scanf("%s %s %d", student.num, student.name, &student.grade);

if (saveData(pf, student))

insertNode(head, student);

break;

case 3:

printf("请用户输入要删除的学生编号:");

scanf("%s", student.num);

deleteNode(head, student.num, pf);

break;

case 4:

printf("请用户输入要修改的学生的编号:");

char str[1000];

scanf("%s", str);

printf("请用户输入新的学生信息:\n");

scanf("%s %s %d", student.num, student.name, &student.grade);

modifyNode(head, str, student);

break;

case 5:

printf("请用户输入要查找的学生编号:");

scanf("%s", student.num);

seekNode(head, student.num);

break;

case 6:

printf("请输入要恢复的学生编号\n");

char back[1000] = { 0 };

scanf("%s", back);

if (!is_repeat(back))

printf("编号重复,请检查后重新输入\n");

else

{

restoreBackup(pf, back);

initData(pf, head);

if (!remove("数据备份.txt"))

printf("备份已删除\n");

}

break;

case 7:

sortData(head);

printList(head);

break;

default:

printf("非法操作,请重新输入!!!\n");

break;

}

}

int main()

{

FILE* pf = NULL;

while (1)

{

Login log = logInterface();

char* check= loginCheck(log);

if (!strcmp(check, "access"))//通过token判断是否存在这么一个用户

{

printf("登陆成功\n");

break;

}

else printf("登录失败!请重试\n");

system("pause");

system("cls");

}

system("pause");

system("cls");

ListNode* pHead = createHead();

initData(pf, pHead);

while (1)

{

menu();

keyDown(pHead, pf);

system("pause");

system("cls");

}

return 0;

}

相关推荐
木向2 分钟前
leetcode第十二题:整数转罗马数字
c++·算法·leetcode·职场和发展
繁星璀璨G6 分钟前
C++11标准模板(STL)- 常用数学函数 - 计算e的给定幂 (ex)(std::exp, std::expf, std::expl)
开发语言·c++·算法·stl·计算e的给定幂
X² 编程说13 分钟前
14.面试算法-字符串常见算法题(三)
java·数据结构·后端·算法·面试
程序猿练习生14 分钟前
C++速通LeetCode中等第20题-随机链表的复制(三步简单图解)
c++·leetcode·链表
S01d13r23 分钟前
LeetCode 每周算法 6(图论、回溯)
算法·leetcode·图论
程序员波特40 分钟前
初识算法
数据结构·算法·leetcode
wheeldown43 分钟前
【数据结构&&C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!
c语言·开发语言·数据结构
繁依Fanyi1 小时前
828华为云征文|华为Flexus云服务器打造《我的世界》游戏服务器
java·服务器·开发语言·python·算法·华为·华为云
那一抹阳光多灿烂1 小时前
代码随想录训练营 Day62打卡 图论part11 Floyd 算法 A * 算法
数据结构·python·算法·图论
Stanf up1 小时前
C语言内存函数
c++·算法