首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >附完整源码 | C语言实现图书管理系统(数据持久化版本)

附完整源码 | C语言实现图书管理系统(数据持久化版本)

作者头像
C语言中文社区
发布2025-06-30 09:52:44
发布2025-06-30 09:52:44
37800
代码可运行
举报
文章被收录于专栏:C语言中文社区C语言中文社区
运行总次数:0
代码可运行

C语言中文社区

学习路线 | AI编程 | 代码实例 | 实战源码 | 开发工具 | 视频教程 | 面试题 | 电子书 | 专注于C语言编程技术分享

186篇原创内容

公众号

正文

图片
图片

文末附完整源代码

设计文档

1. 系统概述

本图书管理系统使用C语言实现,采用链表数据结构存储图书信息,并提供基本的增删改查功能。系统将数据持久化存储到二进制文件中,确保程序关闭后数据不会丢失。

2. 数据结构设计

Book结构体:

代码语言:javascript
代码运行次数:0
运行
复制
typedef struct Book {
    int id;             // 图书ID
    char title[];    // 书名
    char author[];    // 作者
    char publisher[]; // 出版社
    float price;        // 价格
    struct Book *next;  // 指向下一个节点的指针
} Book;
  • id: 唯一标识每本图书的整数ID
  • title: 存储书名的字符数组
  • author: 存储作者信息的字符数组
  • publisher: 存储出版社信息的字符数组
  • price: 存储图书价格的浮点数
  • next: 指向链表中下一个节点的指针

3. 功能模块设计

3.1 添加图书 (addBook)
  • 从用户输入获取图书信息
  • 创建新的Book节点并分配内存
  • 将新节点添加到链表头部
  • 调用saveToFile()保存数据
3.2 显示所有图书 (displayBooks)
  • 遍历链表并格式化输出每本图书的信息
  • 如果链表为空,显示提示信息
3.3 查询图书 (searchBook)
  • 提供三种查询方式:按ID、按书名、按作者
  • 按书名和作者查询时支持不区分大小写的模糊匹配
  • 显示查询结果或未找到的提示
3.4 删除图书 (deleteBook)
  • 根据ID查找要删除的图书
  • 处理删除头节点和中间节点的特殊情况
  • 释放被删除节点的内存
  • 调用saveToFile()保存数据
3.5 修改图书信息 (modifyBook)
  • 根据ID查找要修改的图书
  • 允许用户选择修改部分或全部信息
  • 空输入表示不修改该项
  • 调用saveToFile()保存数据
3.6 数据持久化
  • saveToFile(): 将链表中的所有图书信息以二进制形式写入文件
  • loadFromFile(): 从二进制文件读取数据并重建链表
  • 程序启动时自动加载数据,退出时自动保存数据

4. 文件操作设计

  • 使用二进制文件格式(books.dat)存储数据
  • 每个Book结构体以二进制形式连续存储
  • 文件操作使用标准C库的fopen/fread/fwrite/fclose函数
  • 程序启动时自动尝试加载文件,文件不存在时不报错

5. 用户界面设计

  • 提供清晰的菜单界面
  • 每个功能操作后有明确的反馈信息
  • 输入错误时有适当的提示和重试机会
  • 查询和显示结果格式化输出,便于阅读

6. 错误处理设计

  • 内存分配失败时给出提示并终止操作
  • 文件操作失败时给出提示
  • 用户输入错误时有基本的验证和提示
  • 链表为空时提供友好的提示信息

7. 扩展性考虑

  • 链表结构便于添加新的图书信息
  • 数据结构设计合理,便于添加新的图书属性
  • 模块化设计使得功能扩展相对容易
  • 文件存储格式固定,便于与其他程序交互

8. 使用说明

  1. 编译并运行程序
  2. 按照菜单提示选择相应功能
  3. 添加图书后数据会自动保存
  4. 程序退出时会自动保存当前数据
  5. 下次启动时会自动加载之前保存的数据

9. 限制与改进方向

  • 当前实现中图书ID需要用户手动输入,可能导致重复
  • 可以添加ID自动生成功能
  • 可以增加排序功能
  • 可以添加更多查询条件组合
  • 可以增加数据备份和恢复功能
  • 可以添加用户权限管理

测试结果

CLion:

图片
图片
代码语言:javascript
代码运行次数:0
运行
复制
D:\CODING\cyyzwsq\BooksMS\cmake-build-debug\BooksMS.exe
未找到数据文件,将创建新文件。

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):1

请输入图书ID:1001

请输入书名:C语言

请输入作者:张三

请输入出版社:ABC

请输入价格:55

图书添加成功!
数据已保存到文件!

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2


ID         书名                           作者                 出版社               价格
------------------------------------------------------------
1001       C语言                          张三                 ABC                  55.00

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):1

请输入图书ID:1002

请输入书名:C++

请输入作者:李四

请输入出版社:BBB

请输入价格:66

图书添加成功!
数据已保存到文件!

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2


ID         书名                           作者                 出版社               价格
------------------------------------------------------------
1002       C++                            李四                 BBB                  66.00
1001       C语言                          张三                 ABC                  55.00

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):3

请选择查询方式:
1. 按ID查询
2. 按书名查询
3. 按作者查询
请输入选择(1-3):1

请输入要查询的图书ID:1002


查询结果:
ID: 1002
书名: C++
作者: 李四
出版社: BBB
价格: 66.00

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):5

请输入要修改的图书ID:1002

当前图书信息:
ID: 1002
书名: C++
作者: 李四
出版社: BBB
价格: 66.00
请输入新的书名(留空则不修改):

请输入新的作者(留空则不修改):

请输入新的出版社(留空则不修改):CCC

请输入新的价格(留空则不修改):77

图书信息修改成功!
数据已保存到文件!

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):2


ID         书名                           作者                 出版社               价格
------------------------------------------------------------
1002       C++                            李四                 CCC                  77.00
1001       C语言                          张三                 ABC                  55.00

图书管理系统
1. 添加图书
2. 显示所有图书
3. 查询图书
4. 删除图书
5. 修改图书信息
6. 保存数据到文件
7. 从文件加载数据
0. 退出
请输入您的选择(0-7):

完整源码

GIT地址:https://gitee.com/cyyzwsq/C-Coding.git

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// 定义图书结构体
typedefstruct Book {
    int id;             // 图书ID
    char title[];    // 书名
    char author[];    // 作者
    char publisher[]; // 出版社
    float price;        // 价格
    struct Book *next;// 指向下一个节点的指针
} Book;
// 全局变量,指向链表头
Book *head = NULL;
// 函数声明
void addBook();
void displayBooks();
void searchBook();
void deleteBook();
void modifyBook();
void saveToFile();
void loadFromFile();
void menu();
void toLowerCase(char *str);
int main() {
    loadFromFile(); // 程序启动时加载数据
    menu();         // 显示主菜单
    return;
}
// 添加图书
void addBook() {
    Book *newBook = (Book *)malloc(sizeof(Book));
    if (newBook == NULL) {
        printf("内存分配失败!\n");
        return;
    }
    printf("请输入图书ID: ");
    scanf("%d", &newBook->id);
    getchar(); // 清除输入缓冲区中的换行符
    printf("请输入书名: ");
    fgets(newBook->title, sizeof(newBook->title), stdin);
    newBook->title[strcspn(newBook->title, "\n")] = '\0'; // 去除换行符
    printf("请输入作者: ");
    fgets(newBook->author, sizeof(newBook->author), stdin);
    newBook->author[strcspn(newBook->author, "\n")] = '\0';
    printf("请输入出版社: ");
    fgets(newBook->publisher, sizeof(newBook->publisher), stdin);
    newBook->publisher[strcspn(newBook->publisher, "\n")] = '\0';
    printf("请输入价格: ");
    scanf("%f", &newBook->price);
    // 将新书添加到链表头部
    newBook->next = head;
    head = newBook;
    printf("图书添加成功!\n");
    saveToFile(); // 添加后立即保存到文件
}
// 显示所有图书
void displayBooks() {
    if (head == NULL) {
        printf("当前没有图书记录!\n");
        return;
    }
    Book *current = head;
    printf("\n%-10s %-30s %-20s %-20s %-10s\n", 
           "ID", "书名", "作者", "出版社", "价格");
    printf("------------------------------------------------------------\n");
    
    while (current != NULL) {
        printf("%-10d %-30s %-20s %-20s %-10.2f\n", 
               current->id, current->title, current->author, 
               current->publisher, current->price);
        current = current->next;
    }
}
// 查询图书
void searchBook() {
    if (head == NULL) {
        printf("当前没有图书记录!\n");
        return;
    }
    int choice;
    printf("请选择查询方式:\n");
    printf("1. 按ID查询\n");
    printf("2. 按书名查询\n");
    printf("3. 按作者查询\n");
    printf("请输入选择(1-3): ");
    scanf("%d", &choice);
    getchar(); // 清除输入缓冲区
    Book *current = head;
    int found = ;
    switch (choice) {
        case: {
            int searchId;
            printf("请输入要查询的图书ID: ");
            scanf("%d", &searchId);
            
            while (current != NULL) {
                if (current->id == searchId) {
                    printf("\n查询结果:\n");
                    printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n", 
                           current->id, current->title, current->author, 
                           current->publisher, current->price);
                    found = ;
                    break;
                }
                current = current->next;
            }
            break;
        }
        case: {
            char searchTitle[];
            printf("请输入要查询的书名: ");
            fgets(searchTitle, sizeof(searchTitle), stdin);
            searchTitle[strcspn(searchTitle, "\n")] = '\0';
            
            // 转换为小写以便不区分大小写比较
            char lowerTitle[];
            strcpy(lowerTitle, searchTitle);
            toLowerCase(lowerTitle);
            
            while (current != NULL) {
                char lowerCurrent[];
                strcpy(lowerCurrent, current->title);
                toLowerCase(lowerCurrent);
                
                if (strstr(lowerCurrent, lowerTitle) != NULL) {
                    printf("\n查询结果:\n");
                    printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n", 
                           current->id, current->title, current->author, 
                           current->publisher, current->price);
                    found = ;
                }
                current = current->next;
            }
            break;
        }
        case: {
            char searchAuthor[];
            printf("请输入要查询的作者: ");
            fgets(searchAuthor, sizeof(searchAuthor), stdin);
            searchAuthor[strcspn(searchAuthor, "\n")] = '\0';
            
            // 转换为小写以便不区分大小写比较
            char lowerAuthor[];
            strcpy(lowerAuthor, searchAuthor);
            toLowerCase(lowerAuthor);
            
            while (current != NULL) {
                char lowerCurrent[];
                strcpy(lowerCurrent, current->author);
                toLowerCase(lowerCurrent);
                
                if (strstr(lowerCurrent, lowerAuthor) != NULL) {
                    printf("\n查询结果:\n");
                    printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n", 
                           current->id, current->title, current->author, 
                           current->publisher, current->price);
                    found = ;
                }
                current = current->next;
            }
            break;
        }
        default:
            printf("无效的选择!\n");
            return;
    }
    if (!found) {
        printf("未找到匹配的图书!\n");
    }
}
// 删除图书
void deleteBook() {
    if (head == NULL) {
        printf("当前没有图书记录!\n");
        return;
    }
    int deleteId;
    printf("请输入要删除的图书ID: ");
    scanf("%d", &deleteId);
    Book *current = head;
    Book *prev = NULL;
    int found = ;
    while (current != NULL) {
        if (current->id == deleteId) {
            found = ;
            if (prev == NULL) {
                // 删除的是头节点
                head = current->next;
            } else {
                prev->next = current->next;
            }
            free(current);
            printf("图书删除成功!\n");
            saveToFile(); // 删除后立即保存到文件
            break;
        }
        prev = current;
        current = current->next;
    }
    if (!found) {
        printf("未找到ID为%d的图书!\n", deleteId);
    }
}
// 修改图书信息
void modifyBook() {
    if (head == NULL) {
        printf("当前没有图书记录!\n");
        return;
    }
    int modifyId;
    printf("请输入要修改的图书ID: ");
    scanf("%d", &modifyId);
    getchar(); // 清除输入缓冲区
    Book *current = head;
    int found = ;
    while (current != NULL) {
        if (current->id == modifyId) {
            found = ;
            printf("当前图书信息:\n");
            printf("ID: %d\n书名: %s\n作者: %s\n出版社: %s\n价格: %.2f\n", 
                   current->id, current->title, current->author, 
                   current->publisher, current->price);
            printf("请输入新的书名(留空则不修改): ");
            char newTitle[];
            fgets(newTitle, sizeof(newTitle), stdin);
            if (newTitle[] != '\n') {
                newTitle[strcspn(newTitle, "\n")] = '\0';
                strcpy(current->title, newTitle);
            }
            printf("请输入新的作者(留空则不修改): ");
            char newAuthor[];
            fgets(newAuthor, sizeof(newAuthor), stdin);
            if (newAuthor[] != '\n') {
                newAuthor[strcspn(newAuthor, "\n")] = '\0';
                strcpy(current->author, newAuthor);
            }
            printf("请输入新的出版社(留空则不修改): ");
            char newPublisher[];
            fgets(newPublisher, sizeof(newPublisher), stdin);
            if (newPublisher[] != '\n') {
                newPublisher[strcspn(newPublisher, "\n")] = '\0';
                strcpy(current->publisher, newPublisher);
            }
            printf("请输入新的价格(留空则不修改): ");
            char priceStr[];
            fgets(priceStr, sizeof(priceStr), stdin);
            if (priceStr[] != '\n') {
                current->price = atof(priceStr);
            }
            printf("图书信息修改成功!\n");
            saveToFile(); // 修改后立即保存到文件
            break;
        }
        current = current->next;
    }
    if (!found) {
        printf("未找到ID为%d的图书!\n", modifyId);
    }
}
// 将链表数据保存到文件
void saveToFile() {
    FILE *file = fopen("books.dat", "wb");
    if (file == NULL) {
        printf("无法打开文件进行保存!\n");
        return;
    }
    Book *current = head;
    while (current != NULL) {
        fwrite(current, sizeof(Book), , file);
        current = current->next;
    }
    fclose(file);
    printf("数据已保存到文件!\n");
}
// 从文件加载数据到链表
void loadFromFile() {
    FILE *file = fopen("books.dat", "rb");
    if (file == NULL) {
        printf("未找到数据文件,将创建新文件。\n");
        return;
    }
    // 清空现有链表
    Book *current = head;
    while (current != NULL) {
        Book *temp = current;
        current = current->next;
        free(temp);
    }
    head = NULL;
    // 从文件读取数据
    Book book;
    while (fread(&book, sizeof(Book), , file) == ) {
        Book *newBook = (Book *)malloc(sizeof(Book));
        if (newBook == NULL) {
            printf("内存分配失败!\n");
            break;
        }
        *newBook = book;
        newBook->next = head;
        head = newBook;
    }
    fclose(file);
    printf("数据已从文件加载!\n");
}
// 将字符串转换为小写
void toLowerCase(char *str) {
    for (int i = ; str[i]; i++) {
        str[i] = tolower(str[i]);
    }
}
// 显示主菜单
void menu() {
    int choice;
    do {
        printf("\n图书管理系统\n");
        printf("1. 添加图书\n");
        printf("2. 显示所有图书\n");
        printf("3. 查询图书\n");
        printf("4. 删除图书\n");
        printf("5. 修改图书信息\n");
        printf("6. 保存数据到文件\n");
        printf("7. 从文件加载数据\n");
        printf("0. 退出\n");
        printf("请输入您的选择(0-7): ");
        scanf("%d", &choice);
        getchar(); // 清除输入缓冲区
        switch (choice) {
            case: addBook(); break;
            case: displayBooks(); break;
            case: searchBook(); break;
            case: deleteBook(); break;
            case: modifyBook(); break;
            case: saveToFile(); break;
            case: loadFromFile(); break;
            case: 
                saveToFile(); // 退出前保存数据
                printf("感谢使用图书管理系统,再见!\n");
                break;
            default:
                printf("无效的选择,请重新输入!\n");
        }
    } while (choice != );
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 C语言中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
    • 设计文档
      • 1. 系统概述
      • 2. 数据结构设计
      • 3. 功能模块设计
      • 4. 文件操作设计
      • 5. 用户界面设计
      • 6. 错误处理设计
      • 7. 扩展性考虑
      • 8. 使用说明
      • 9. 限制与改进方向
    • 测试结果
    • 完整源码
    • GIT地址:https://gitee.com/cyyzwsq/C-Coding.git
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档