c语言图书管理系统程序设计

99ANYc3cd6
预计阅读时长 45 分钟
位置: 首页 C语言 正文
  1. 系统功能分析
  2. 数据结构设计
  3. 模块化设计
  4. 完整源代码
  5. 代码编译与运行
  6. 系统扩展与优化建议

系统功能分析

一个基础的图书管理系统应具备以下核心功能:

c语言图书管理系统程序设计
(图片来源网络,侵删)
  • 添加图书: 将新图书的信息(如ISBN、书名、作者、库存数量)录入系统。
  • 删除图书: 根据ISBN号从系统中移除一本图书。
  • 查找图书: 提供多种查找方式,例如按ISBN、按书名、按作者查找。
  • 显示所有图书: 以列表形式展示系统中所有图书的信息。
  • 借阅图书: 减少指定图书的库存数量。
  • 归还图书: 增加指定图书的库存数量。
  • 保存数据: 将图书信息保存到文件中,以便程序关闭后数据不丢失。
  • 加载数据: 从文件中加载之前保存的图书信息。

数据结构设计

为了存储图书信息,我们需要一个自定义的结构体 Book

// 图书结构体
typedef struct {
    char isbn[20];      // ISBN号,作为唯一标识
    char title[100];    // 书名
    char author[50];    // 作者
    int  quantity;      // 库存数量
} Book;

为了管理所有图书,我们将使用一个动态数组,动态数组的好处是可以在运行时根据需要调整大小,以容纳任意数量的图书。

// 图书管理系统结构体
typedef struct {
    Book *books;        // 指向图书动态数组的指针
    int  count;         // 当前图书的数量
    int  capacity;      // 当前动态数组的总容量
} LibrarySystem;

模块化设计

为了使代码结构清晰、易于维护,我们将把不同的功能封装成独立的函数。

函数模块 功能描述
初始化与销毁 initSystem(): 初始化系统,分配内存。 freeSystem(): 释放系统内存,防止内存泄漏。
文件操作 saveToFile(): 将所有图书数据保存到文件。 loadFromFile(): 从文件加载图书数据。
核心功能 addBook(), deleteBook(), findBook(), displayAllBooks(), borrowBook(), returnBook()
菜单与交互 showMenu(): 显示主菜单。 main(): 程序入口,控制程序流程。

完整源代码

下面是完整的C语言源代码,您可以直接将其复制到 .c 文件(library.c)中编译运行。

c语言图书管理系统程序设计
(图片来源网络,侵删)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// --- 常量定义 ---
#define FILENAME "library.dat"
#define INITIAL_CAPACITY 10
#define ISBN_LEN 20
#define TITLE_LEN 100
#define AUTHOR_LEN 50
// --- 图书结构体 ---
typedef struct {
    char isbn[ISBN_LEN];
    char title[TITLE_LEN];
    char author[AUTHOR_LEN];
    int  quantity;
} Book;
// --- 图书管理系统结构体 ---
typedef struct {
    Book *books;        // 指向图书动态数组的指针
    int  count;         // 当前图书的数量
    int  capacity;      // 当前动态数组的总容量
} LibrarySystem;
// --- 函数声明 ---
void initSystem(LibrarySystem *sys);
void freeSystem(LibrarySystem *sys);
void showMenu();
void addBook(LibrarySystem *sys);
void deleteBook(LibrarySystem *sys);
void findBook(const LibrarySystem *sys);
void displayAllBooks(const LibrarySystem *sys);
void borrowBook(LibrarySystem *sys);
void returnBook(LibrarySystem *sys);
void saveToFile(const LibrarySystem *sys);
void loadFromFile(LibrarySystem *sys);
void resizeLibrary(LibrarySystem *sys);
// --- 主函数 ---
int main() {
    LibrarySystem sys;
    initSystem(&sys);
    // 尝试从文件加载数据
    loadFromFile(&sys);
    int choice;
    do {
        showMenu();
        printf("请输入您的选择: ");
        scanf("%d", &choice);
        getchar(); // 清除输入缓冲区中的换行符
        switch (choice) {
            case 1: addBook(&sys); break;
            case 2: deleteBook(&sys); break;
            case 3: findBook(&sys); break;
            case 4: displayAllBooks(&sys); break;
            case 5: borrowBook(&sys); break;
            case 6: returnBook(&sys); break;
            case 7: saveToFile(&sys); printf("数据已保存!\n"); break;
            case 0: printf("感谢使用,再见!\n"); break;
            default: printf("无效的选择,请重新输入!\n");
        }
    } while (choice != 0);
    // 退出前保存数据
    saveToFile(&sys);
    // 释放内存
    freeSystem(&sys);
    return 0;
}
// --- 函数实现 ---
/**
 * @brief 初始化图书管理系统
 * @param sys 指向图书管理系统的指针
 */
void initSystem(LibrarySystem *sys) {
    sys->capacity = INITIAL_CAPACITY;
    sys->count = 0;
    // 为图书数组分配初始内存
    sys->books = (Book *)malloc(sys->capacity * sizeof(Book));
    if (sys->books == NULL) {
        printf("内存分配失败!\n");
        exit(1);
    }
}
/**
 * @brief 释放图书管理系统占用的内存
 * @param sys 指向图书管理系统的指针
 */
void freeSystem(LibrarySystem *sys) {
    free(sys->books);
    sys->books = NULL;
    sys->count = 0;
    sys->capacity = 0;
}
/**
 * @brief 显示系统菜单
 */
void showMenu() {
    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("=================================\n");
}
/**
 * @brief 添加图书
 * @param sys 指向图书管理系统的指针
 */
void addBook(LibrarySystem *sys) {
    // 检查是否需要扩容
    if (sys->count >= sys->capacity) {
        resizeLibrary(sys);
    }
    Book *newBook = &sys->books[sys->count];
    printf("请输入图书ISBN: ");
    scanf("%s", newBook->isbn);
    getchar();
    printf("请输入书名: ");
    fgets(newBook->title, TITLE_LEN, stdin);
    newBook->title[strcspn(newBook->title, "\n")] = 0; // 去除fgets读取的换行符
    printf("请输入作者: ");
    fgets(newBook->author, AUTHOR_LEN, stdin);
    newBook->author[strcspn(newBook->author, "\n")] = 0;
    printf("请输入库存数量: ");
    scanf("%d", &newBook->quantity);
    getchar();
    sys->count++;
    printf("图书添加成功!\n");
}
/**
 * @brief 删除图书
 * @param sys 指向图书管理系统的指针
 */
void deleteBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("图书馆中没有图书!\n");
        return;
    }
    char isbn[ISBN_LEN];
    printf("请输入要删除的图书ISBN: ");
    scanf("%s", isbn);
    getchar();
    for (int i = 0; i < sys->count; i++) {
        if (strcmp(sys->books[i].isbn, isbn) == 0) {
            // 将最后一个元素移到被删除元素的位置
            sys->books[i] = sys->books[sys->count - 1];
            sys->count--;
            printf("图书删除成功!\n");
            return;
        }
    }
    printf("未找到ISBN为 %s 的图书!\n", isbn);
}
/**
 * @brief 查找图书
 * @param sys 指向图书管理系统的指针
 */
void findBook(const LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("图书馆中没有图书!\n");
        return;
    }
    int choice;
    printf("选择查找方式:\n");
    printf("  1. 按ISBN查找\n");
    printf("  2. 按书名查找\n");
    printf("  3. 按作者查找\n");
    printf("请输入您的选择: ");
    scanf("%d", &choice);
    getchar();
    char keyword[100];
    printf("请输入关键词: ");
    fgets(keyword, 100, stdin);
    keyword[strcspn(keyword, "\n")] = 0;
    int found = 0;
    printf("\n--- 查找结果 ---\n");
    for (int i = 0; i < sys->count; i++) {
        int match = 0;
        switch (choice) {
            case 1: match = (strcmp(sys->books[i].isbn, keyword) == 0); break;
            case 2: match = (strstr(sys->books[i].title, keyword) != NULL); break;
            case 3: match = (strstr(sys->books[i].author, keyword) != NULL); break;
            default: printf("无效的查找选项!\n"); return;
        }
        if (match) {
            printf("ISBN: %s\n", sys->books[i].isbn);
            printf("书名: %s\n", sys->books[i].title);
            printf("作者: %s\n", sys->books[i].author);
            printf("库存: %d\n", sys->books[i].quantity);
            printf("-----------------\n");
            found = 1;
        }
    }
    if (!found) {
        printf("未找到匹配的图书,\n");
    }
}
/**
 * @brief 显示所有图书
 * @param sys 指向图书管理系统的指针
 */
void displayAllBooks(const LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("图书馆中没有图书!\n");
        return;
    }
    printf("\n--- 所有图书列表 (共 %d 本) ---\n", sys->count);
    printf("%-15s %-30s %-20s %s\n", "ISBN", "书名", "作者", "库存");
    printf("----------------------------------------------------------------\n");
    for (int i = 0; i < sys->count; i++) {
        printf("%-15s %-30s %-20s %d\n", 
               sys->books[i].isbn, 
               sys->books[i].title, 
               sys->books[i].author, 
               sys->books[i].quantity);
    }
    printf("----------------------------------------------------------------\n");
}
/**
 * @brief 借阅图书
 * @param sys 指向图书管理系统的指针
 */
void borrowBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("图书馆中没有图书!\n");
        return;
    }
    char isbn[ISBN_LEN];
    printf("请输入要借阅的图书ISBN: ");
    scanf("%s", isbn);
    getchar();
    for (int i = 0; i < sys->count; i++) {
        if (strcmp(sys->books[i].isbn, isbn) == 0) {
            if (sys->books[i].quantity > 0) {
                sys->books[i].quantity--;
                printf("借阅成功! 当前库存: %d\n", sys->books[i].quantity);
            } else {
                printf("借阅失败! 该图书已无库存,\n");
            }
            return;
        }
    }
    printf("未找到ISBN为 %s 的图书!\n", isbn);
}
/**
 * @brief 归还图书
 * @param sys 指向图书管理系统的指针
 */
void returnBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("图书馆中没有图书!\n");
        return;
    }
    char isbn[ISBN_LEN];
    printf("请输入要归还的图书ISBN: ");
    scanf("%s", isbn);
    getchar();
    for (int i = 0; i < sys->count; i++) {
        if (strcmp(sys->books[i].isbn, isbn) == 0) {
            sys->books[i].quantity++;
            printf("归还成功! 当前库存: %d\n", sys->books[i].quantity);
            return;
        }
    }
    printf("未找到ISBN为 %s 的图书!\n", isbn);
}
/**
 * @brief 将数据保存到文件
 * @param sys 指向图书管理系统的指针
 */
void saveToFile(const LibrarySystem *sys) {
    FILE *fp = fopen(FILENAME, "wb"); // "wb" 表示以二进制写入模式
    if (fp == NULL) {
        printf("无法打开文件 %s 进行写入!\n", FILENAME);
        return;
    }
    // 先写入图书的数量
    fwrite(&sys->count, sizeof(int), 1, fp);
    // 再写入所有图书数据
    fwrite(sys->books, sizeof(Book), sys->count, fp);
    fclose(fp);
}
/**
 * @brief 从文件加载数据
 * @param sys 指向图书管理系统的指针
 */
void loadFromFile(LibrarySystem *sys) {
    FILE *fp = fopen(FILENAME, "rb"); // "rb" 表示以二进制读取模式
    if (fp == NULL) {
        // 文件不存在是正常情况(第一次运行)
        return;
    }
    int count;
    // 读取图书数量
    fread(&count, sizeof(int), 1, fp);
    // 根据数量调整系统容量
    if (count > sys->capacity) {
        sys->capacity = count;
        resizeLibrary(sys);
    }
    // 读取所有图书数据
    fread(sys->books, sizeof(Book), count, fp);
    sys->count = count;
    fclose(fp);
    printf("成功从文件加载 %d 本图书,\n", count);
}
/**
 * @brief 调整图书馆容量(扩容)
 * @param sys 指向图书管理系统的指针
 */
void resizeLibrary(LibrarySystem *sys) {
    int new_capacity = sys->capacity * 2;
    Book *new_books = (Book *)realloc(sys->books, new_capacity * sizeof(Book));
    if (new_books == NULL) {
        printf("内存重新分配失败!\n");
        exit(1);
    }
    sys->books = new_books;
    sys->capacity = new_capacity;
    printf("图书馆已扩容至 %d,\n", new_capacity);
}

代码编译与运行

  1. 保存代码: 将上述代码保存为 library.c 文件。
  2. 打开终端/命令行:
    • 在 Windows 上,可以使用 CMD 或 PowerShell。
    • 在 macOS 或 Linux 上,可以使用 Terminal。
  3. 编译代码: 使用 GCC 编译器进行编译。
    gcc library.c -o library
    • gcc: GCC 编译器的命令。
    • library.c: 你的源文件名。
    • -o library: 指定输出的可执行文件名为 library(在 Windows 上会是 library.exe)。
  4. 运行程序:
    • Windows:
      library.exe
    • macOS / Linux:
      ./library

程序运行后,会生成一个名为 library.dat 的文件,用于持久化存储数据。


系统扩展与优化建议

这个基础版本已经可以很好地工作,但如果你想进一步学习和提升,可以考虑以下扩展:

  1. 用户管理:

    • 创建一个 User 结构体,包含用户ID、姓名、借阅的图书列表等。
    • 实现用户注册、登录、查看借阅历史等功能。
    • 借阅时需要关联到特定用户,并限制每个用户的最大借阅数量。
  2. 更强大的数据持久化:

    c语言图书管理系统程序设计
    (图片来源网络,侵删)
    • 使用CSV/文本文件: 将数据保存为人类可读的文本格式(如CSV),方便用Excel等工具查看和编辑,这比二进制文件更灵活,但解析稍慢。
    • 使用数据库: 对于更复杂的系统,可以考虑使用SQLite这样的嵌入式数据库,它提供了SQL查询、索引、事务等强大功能,能极大地提升数据管理的效率和可靠性。
  3. 改进用户界面:

    • 使用 ncurses (Linux/macOS) 或 conio.h (Windows, 非标准) 等库来创建更美观的基于终端的图形界面(TUI),如彩色文本、窗口、按钮等。
  4. 代码健壮性:

    • 输入验证: 对所有用户输入进行更严格的验证,确保库存数量是正整数,ISBN格式正确等。
    • 错误处理: 增加更完善的错误处理机制,当文件读写失败或内存分配失败时,提供更友好的错误信息并尝试恢复。
  5. 功能增强:

    • 图书分类:Book 结构体增加一个 category (分类) 字段,如“文学”、“科学”、“计算机”等,并支持按分类查找和统计。
    • 排序功能: 支持按书名、作者、入库时间等对图书列表进行排序。
    • 统计报表: 实现功能,如“最受欢迎的图书”、“库存不足的图书”等统计报表。

这个项目是学习C语言指针、结构体、文件操作、动态内存管理的绝佳实践,希望这个详细的设计和代码对你有帮助!

-- 展开阅读全文 --
头像
织梦更新后主页为何不更新?
« 上一篇 03-18
dede专题默认模板如何使用?
下一篇 » 03-18

相关文章

取消
微信二维码
支付宝二维码

目录[+]