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

简介: 基于链表实现的链式管理系统(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;
}
相关文章
|
26天前
|
存储 安全 数据管理
C语言之考勤模拟系统平台(千行代码)
C语言之考勤模拟系统平台(千行代码)
48 4
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
11天前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
88 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
6天前
|
存储 编译器 C语言
【C语言】C语言的变量和声明系统性讲解
在C语言中,声明和定义是两个关键概念,分别用于告知编译器变量或函数的存在(声明)和实际创建及分配内存(定义)。声明可以多次出现,而定义只能有一次。声明通常位于头文件中,定义则在源文件中。通过合理组织头文件和源文件,可以提高代码的模块化和可维护性。示例包括全局变量、局部变量、函数、结构体、联合体、数组、字符串、枚举和指针的声明与定义。
35 12
|
15天前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
108 6
|
19天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
42 5
|
18天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
37 1
|
18天前
|
人工智能 安全 算法
基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。
本文深入探讨了基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。C语言因其高效、可移植、灵活及成熟度高等特点,在嵌入式系统开发中占据重要地位。文章还介绍了从系统需求分析到部署维护的完整开发流程,以及中断处理、内存管理等关键技术,并展望了嵌入式系统在物联网和人工智能领域的未来发展。
40 1
|
1月前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
32 1
|
1月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?