C语言图书管理系统如何实现核心功能?

99ANYc3cd6
预计阅读时长 46 分钟
位置: 首页 C语言 正文

C语言图书管理系统设计与实现

需求分析

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

c语言程序设计的图书管理系统
(图片来源网络,侵删)
  1. 图书信息的录入:能够将新图书的信息(如ID、书名、作者、出版社、库存数量)添加到系统中。
  2. 图书信息的查询:能够根据不同的条件(如书名、作者、ID)查找图书。
  3. 图书信息的修改:能够修改已有图书的信息(如更新库存、修改作者等)。
  4. 图书信息的删除:能够从系统中删除某本图书。
  5. 图书信息的显示:能够以列表形式显示所有图书的信息。
  6. 数据持久化:系统能够将图书数据保存到文件中,并在程序启动时从文件中加载,确保数据不丢失。

系统设计

数据结构设计

为了存储图书信息,我们使用结构体,为了管理所有图书,我们使用结构体数组

// 定义图书结构体
typedef struct {
    int id;             // 图书ID (唯一标识)
    char title[100];    // 书名
    char author[50];    // 作者
    char publisher[50]; // 出版社
    int stock;          // 库存数量
} Book;
// 定义图书管理系统结构体
// 使用一个结构体来封装所有数据和功能,使程序更模块化
typedef struct {
    Book books[MAX_BOOKS]; // 存储所有图书的数组
    int count;             // 当前系统中图书的数量
} LibrarySystem;
  • MAX_BOOKS 是一个宏,定义了系统能容纳的最大图书数量,#define MAX_BOOKS 1000
  • LibrarySystem 结构体封装了数据和图书总数,方便函数间传递。

功能模块设计

我们将系统功能分解为独立的函数,每个函数负责一个特定的任务。

函数名 功能描述
initSystem(LibrarySystem *sys) 初始化系统,清空图书列表,计数器归零。
saveToFile(LibrarySystem *sys) 将系统中的所有图书数据保存到文件(如 library.dat)。
loadFromFile(LibrarySystem *sys) 从文件中加载图书数据到系统。
addBook(LibrarySystem *sys) 添加一本新书。
findBook(LibrarySystem *sys) 查找并显示图书。
modifyBook(LibrarySystem *sys) 修改图书信息。
deleteBook(LibrarySystem *sys) 删除图书。
displayAllBooks(LibrarySystem *sys) 显示所有图书信息。
showMenu() 显示用户操作菜单。
main() 程序入口,负责调用其他函数,控制程序流程。

核心代码实现

下面是完整的C语言代码实现,代码包含了详细的注释,以帮助你理解每一部分的作用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BOOKS 1000  // 最大图书数量
#define FILENAME "library.dat" // 数据文件名
// 定义图书结构体
typedef struct {
    int id;
    char title[100];
    char author[50];
    char publisher[50];
    int stock;
} Book;
// 定义图书管理系统结构体
typedef struct {
    Book books[MAX_BOOKS];
    int count;
} LibrarySystem;
// 函数声明
void initSystem(LibrarySystem *sys);
void saveToFile(LibrarySystem *sys);
void loadFromFile(LibrarySystem *sys);
void addBook(LibrarySystem *sys);
void findBook(LibrarySystem *sys);
void modifyBook(LibrarySystem *sys);
void deleteBook(LibrarySystem *sys);
void displayAllBooks(LibrarySystem *sys);
void showMenu();
int main() {
    LibrarySystem sys;
    initSystem(&sys);
    // 程序启动时尝试从文件加载数据
    loadFromFile(&sys);
    int choice;
    do {
        showMenu();
        printf("请输入您的选择: ");
        scanf("%d", &choice);
        getchar(); // 消耗掉输入缓冲区中的换行符,避免影响后续的gets或fgets
        switch (choice) {
            case 1:
                addBook(&sys);
                break;
            case 2:
                findBook(&sys);
                break;
            case 3:
                modifyBook(&sys);
                break;
            case 4:
                deleteBook(&sys);
                break;
            case 5:
                displayAllBooks(&sys);
                break;
            case 0:
                printf("感谢使用,系统将自动保存数据并退出,\n");
                saveToFile(&sys);
                break;
            default:
                printf("无效的选择,请重新输入!\n");
                break;
        }
    } while (choice != 0);
    return 0;
}
// 初始化系统
void initSystem(LibrarySystem *sys) {
    sys->count = 0;
    printf("图书管理系统已初始化,\n");
}
// 显示菜单
void showMenu() {
    printf("\n========== 图书管理系统 ==========\n");
    printf("    1. 添加图书\n");
    printf("    2. 查询图书\n");
    printf("    3. 修改图书\n");
    printf("    4. 删除图书\n");
    printf("    5. 显示所有图书\n");
    printf("    0. 退出系统\n");
    printf("=================================\n");
}
// 添加图书
void addBook(LibrarySystem *sys) {
    if (sys->count >= MAX_BOOKS) {
        printf("错误:系统已满,无法添加更多图书!\n");
        return;
    }
    Book newBook;
    printf("请输入图书ID: ");
    scanf("%d", &newBook.id);
    getchar(); // 消耗换行符
    printf("请输入书名: ");
    fgets(newBook.title, sizeof(newBook.title), stdin);
    newBook.title[strcspn(newBook.title, "\n")] = 0; // 去掉fgets读取的换行符
    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("%d", &newBook.stock);
    // 检查ID是否已存在
    for (int i = 0; i < sys->count; i++) {
        if (sys->books[i].id == newBook.id) {
            printf("错误:ID为 %d 的图书已存在!\n", newBook.id);
            return;
        }
    }
    sys->books[sys->count] = newBook;
    sys->count++;
    printf("图书添加成功!\n");
}
// 查询图书
void findBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("系统中没有图书!\n");
        return;
    }
    int choice;
    printf("请选择查询方式:\n");
    printf("1. 按ID查询\n");
    printf("2. 按书名查询\n");
    printf("请输入选择: ");
    scanf("%d", &choice);
    if (choice == 1) {
        int id;
        printf("请输入要查询的图书ID: ");
        scanf("%d", &id);
        int found = 0;
        for (int i = 0; i < sys->count; i++) {
            if (sys->books[i].id == id) {
                printf("\n--- 找到图书 ---\n");
                printf("ID: %d\n", sys->books[i].id);
                printf("书名: %s\n", sys->books[i].title);
                printf("作者: %s\n", sys->books[i].author);
                printf("出版社: %s\n", sys->books[i].publisher);
                printf("库存: %d\n", sys->books[i].stock);
                found = 1;
                break;
            }
        }
        if (!found) {
            printf("未找到ID为 %d 的图书,\n", id);
        }
    } else if (choice == 2) {
        char title[100];
        printf("请输入要查询的书名: ");
        getchar(); // 消耗换行符
        fgets(title, sizeof(title), stdin);
        title[strcspn(title, "\n")] = 0;
        int found = 0;
        for (int i = 0; i < sys->count; i++) {
            if (strstr(sys->books[i].title, title) != NULL) { // 使用strstr进行模糊查询
                printf("\n--- 找到图书 ---\n");
                printf("ID: %d\n", sys->books[i].id);
                printf("书名: %s\n", sys->books[i].title);
                printf("作者: %s\n", sys->books[i].author);
                printf("出版社: %s\n", sys->books[i].publisher);
                printf("库存: %d\n", sys->books[i].stock);
                printf("-----------------\n");
                found = 1;
            }
        }
        if (!found) {
            printf("未找到包含 \"%s\" 的图书,\n", title);
        }
    } else {
        printf("无效的选择!\n");
    }
}
// 修改图书
void modifyBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("系统中没有图书!\n");
        return;
    }
    int id;
    printf("请输入要修改的图书ID: ");
    scanf("%d", &id);
    for (int i = 0; i < sys->count; i++) {
        if (sys->books[i].id == id) {
            printf("找到图书,请输入新的信息 (直接回车则保持不变):\n");
            printf("书名 (%s): ", sys->books[i].title);
            getchar();
            char newTitle[100];
            fgets(newTitle, sizeof(newTitle), stdin);
            if (strlen(newTitle) > 1) { // 如果用户输入了内容
                newTitle[strcspn(newTitle, "\n")] = 0;
                strcpy(sys->books[i].title, newTitle);
            }
            printf("作者 (%s): ", sys->books[i].author);
            char newAuthor[50];
            fgets(newAuthor, sizeof(newAuthor), stdin);
            if (strlen(newAuthor) > 1) {
                newAuthor[strcspn(newAuthor, "\n")] = 0;
                strcpy(sys->books[i].author, newAuthor);
            }
            printf("出版社 (%s): ", sys->books[i].publisher);
            char newPublisher[50];
            fgets(newPublisher, sizeof(newPublisher), stdin);
            if (strlen(newPublisher) > 1) {
                newPublisher[strcspn(newPublisher, "\n")] = 0;
                strcpy(sys->books[i].publisher, newPublisher);
            }
            printf("库存数量 (%d): ", sys->books[i].stock);
            char newStockStr[10];
            fgets(newStockStr, sizeof(newStockStr), stdin);
            if (strlen(newStockStr) > 1) {
                int newStock = atoi(newStockStr);
                sys->books[i].stock = newStock;
            }
            printf("图书信息修改成功!\n");
            return;
        }
    }
    printf("未找到ID为 %d 的图书,\n", id);
}
// 删除图书
void deleteBook(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("系统中没有图书!\n");
        return;
    }
    int id;
    printf("请输入要删除的图书ID: ");
    scanf("%d", &id);
    int foundIndex = -1;
    for (int i = 0; i < sys->count; i++) {
        if (sys->books[i].id == id) {
            foundIndex = i;
            break;
        }
    }
    if (foundIndex != -1) {
        // 将后面的所有图书向前移动一位,覆盖掉要删除的图书
        for (int i = foundIndex; i < sys->count - 1; i++) {
            sys->books[i] = sys->books[i + 1];
        }
        sys->count--;
        printf("ID为 %d 的图书已删除,\n", id);
    } else {
        printf("未找到ID为 %d 的图书,\n", id);
    }
}
// 显示所有图书
void displayAllBooks(LibrarySystem *sys) {
    if (sys->count == 0) {
        printf("系统中没有图书!\n");
        return;
    }
    printf("\n========== 所有图书列表 (共 %d 本) ==========\n", sys->count);
    printf("-----------------------------------------------------------------\n");
    printf("%-5s %-30s %-20s %-20s %-10s\n", "ID", "书名", "作者", "出版社", "库存");
    printf("-----------------------------------------------------------------\n");
    for (int i = 0; i < sys->count; i++) {
        printf("%-5d %-30s %-20s %-20s %-10d\n",
               sys->books[i].id,
               sys->books[i].title,
               sys->books[i].author,
               sys->books[i].publisher,
               sys->books[i].stock);
    }
    printf("-----------------------------------------------------------------\n");
}
// 保存数据到文件
void saveToFile(LibrarySystem *sys) {
    FILE *fp = fopen(FILENAME, "wb"); // "wb" 表示二进制写入,会覆盖文件
    if (fp == NULL) {
        printf("警告:无法打开文件 %s 进行保存!\n", FILENAME);
        return;
    }
    // 一次性写入整个结构体数组
    fwrite(sys->books, sizeof(Book), sys->count, fp);
    fclose(fp);
    printf("数据已成功保存到 %s\n", FILENAME);
}
// 从文件加载数据
void loadFromFile(LibrarySystem *sys) {
    FILE *fp = fopen(FILENAME, "rb"); // "rb" 表示二进制读取
    if (fp == NULL) {
        printf("提示:数据文件 %s 不存在,将创建新文件,\n", FILENAME);
        return;
    }
    // 一次性读取整个结构体数组
    sys->count = fread(sys->books, sizeof(Book), MAX_BOOKS, fp);
    fclose(fp);
    printf("数据已成功从 %s 加载,共 %d 本图书,\n", FILENAME, sys->count);
}

如何编译和运行

  1. 将以上代码保存为一个文件,library_system.c
  2. 打开终端或命令提示符。
  3. 使用GCC编译器进行编译:
    gcc library_system.c -o library_system
  4. 运行生成的可执行文件:
    • 在Windows上: library_system.exe
    • 在Linux或macOS上: ./library_system

系统扩展建议

如果你想让这个系统更完善,可以考虑以下扩展:

c语言程序设计的图书管理系统
(图片来源网络,侵删)
  1. 更强大的查询功能

    • 增加按作者、出版社查询。
    • 实现组合查询(查找“某位作者”写的“某本书”)。
  2. 借阅和归还功能

    • 添加一个 borrowBook 函数,当用户借书时,减少对应图书的库存。
    • 添加一个 returnBook 函数,当用户还书时,增加对应图书的库存。
    • 可以增加一个 isAvailable 函数来检查图书是否可借。
  3. 用户管理系统

    • 创建一个 User 结构体,包含用户ID、姓名、密码等。
    • 实现用户注册、登录功能,不同权限的用户(如管理员、普通用户)可以操作的功能不同。
  4. 改进数据存储

    c语言程序设计的图书管理系统
    (图片来源网络,侵删)
    • 使用文本文件(如CSV格式)存储数据,方便用Excel等工具查看和编辑。
    • 对于更复杂的系统,可以考虑使用简单的数据库(如SQLite)。
  5. 优化用户界面

    • 使用 system("cls") (Windows) 或 system("clear") (Linux/macOS) 来清屏,使界面更整洁。
    • 添加更多的输入验证,防止非法输入导致程序崩溃。

这个项目是学习C语言结构体、文件操作、函数模块化设计的一个绝佳实践,希望这个详细的实现能对你有所帮助!

-- 展开阅读全文 --
头像
没有dede-admin表
« 上一篇 02-15
C语言程序的基本单位是什么?
下一篇 » 02-15
取消
微信二维码
支付宝二维码

目录[+]