C语言图书馆管理系统(管理员版)

news2024/11/27 13:28:38

案例:图书馆管理系统(管理员版)

背景:

随着信息技术的发展和普及,传统的图书馆管理方式已经无法满足现代图书馆高效、便捷、智能化的管理需求。传统的手工登记、纸质档案管理不仅耗时耗力,而且容易出现错误,导致图书资源的浪费和读者体验的下降。因此,开发一套高效的图书馆管理系统成为了提升图书馆服务质量和管理水平的迫切需求。

 题目要求:

开发一个图书馆管理系统实现以下功能

增加图书

1.输入:管理员输入图书的详细信息。

2.处理:系统验证信息的有效性,并将图书信息存储到数据库中。

3.输出:提示管理员图书添加成功,并在图书列表中显示新增的图书。

查找图书

1.输入:管理员输入查找对应图书的编码和书名即可查找。

2.处理:系统根据条件在数据库中检索匹配的图书。

3.输出:返回查找结果,显示符合条件的图书列表。

删除图书

1.输入:管理员选择要删除的图书编码或者书名。

2.处理:系统确认删除操作,并从数据库中移除该图书的信息。

3.输出:提示删除成功,并更新图书列表。

显示图书

1.输入:无。

2.处理:系统从数据库中读取所有图书信息。

3.输出:显示所有图书的列表。

归还图书

1.输入:管理员选择要借出的图书编码或者书名。

2.处理:系统记录归还信息,更新图书的库存状态。

3.输出:提示归还成功,并更新归还记录。

借阅图书

1.输入:管理员选择要借出的图书编码或者书名。

2.处理:系统记录借阅信息,更新图书的库存状态。

3.输出:提示借阅成功,并更新借阅记录。

退出系统

1.输入:管理员选择退出系统的选项。

2.处理:系统保存当前状态,并关闭所有运行中的进程。

3.输出:显示退出系统的确认信息。

5. 安全性

对于未能查询到的图书创建异常处理机制来提高系统安全性与稳定性

开始

  |

  |---程序启动,初始化

  |       library[] 和 bookCount = 0

  |

  |---主菜单

  |

  |---用户选择:

  |       (1) 添加图书

  |       (2) 显示所有图书

  |       (3) 查找图书

  |       (4) 借阅图书

  |       (5) 归还图书

  |       (6) 删除图书

  |       (7) 退出程序

  |

  |---添加图书 (addBook):

  |       提示用户输入图书信息

  |       创建新书籍对象

  |       library[bookCount] = 新书籍对象

  |       bookCount++

  |       回到主菜单

  |

  |---显示所有图书 (displayAllBooks):

  |       遍历 library[] 并打印图书信息

  |       回到主菜单

  |

  |---查找图书 (findBook):

  |       询问用户选择按 ID 还是书名

  |       根据选择搜索 library[]

  |       显示搜索结果

  |       回到主菜单

  |

  |---借阅图书 (borrowBook):

  |       询问用户选择按 ID 还是书名

  |       根据选择执行借阅操作

  |       回到主菜单

  |

  |---归还图书 (returnBook):

  |       询问用户选择按 ID 还是书名

  |       根据选择执行归还操作

  |       回到主菜单

  |

  |---删除图书 (deleteBook):

  |       询问用户选择按 ID 还是书名

  |       根据选择执行删除操作

  |       回到主菜单

  |

  |---退出程序

  |

结束

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define FILENAME "D:\\Filedemo\\library.txt"
#define MAX_BOOKS 100
#define NAME_LENGTH 50
#define AUTHOR_LENGTH 50

typedef struct {
    int id;
    char title[NAME_LENGTH];
    char author[AUTHOR_LENGTH];
    float price;
    char category[NAME_LENGTH];
    bool borrowed;
} Book;

Book library[MAX_BOOKS];
int bookCount = 0;

// 声明图书馆数组和图书计数变量
Book library[MAX_BOOKS];

// 保存图书信息到文件的函数
void saveBooksToFile() {
    FILE *file = fopen(FILENAME, "wb"); // 打开文件以二进制写入模式
    if (file == NULL) { // 检查文件是否成功打开
        printf("Error opening file for writing.\n");
        return; // 如果打开失败,打印错误信息并返回
    }
    fwrite(library, sizeof(Book), bookCount, file); // 将图书数据写入文件
    fclose(file); // 关闭文件
}

// 从文件加载图书信息的函数
void loadBooksFromFile() {
    FILE *file = fopen(FILENAME, "rb"); // 打开文件以二进制读取模式
    if (file == NULL) { // 检查文件是否成功打开
        printf("No existing library data found.\n");
        return; // 如果没有找到数据,打印信息并返回
    }
    bookCount = fread(library, sizeof(Book), MAX_BOOKS, file); // 从文件读取图书数据
    fclose(file); // 关闭文件
}

// 添加新图书的函数
void addBook() {
    if (bookCount >= MAX_BOOKS) { // 检查是否达到最大图书数量
        printf("抱歉,无法增加图书.\n");
        return; // 如果达到上限,打印信息并返回
    }
    Book newBook; // 创建一个新的图书结构体
    // 获取用户输入的图书信息
    printf("请输入图书书名: ");
    scanf("%s", newBook.title);
    printf("请输入图书作者: ");
    scanf("%s", newBook.author);
    printf("请输入图书价格: ");
    scanf("%f", &newBook.price);
    printf("请输入图书类型: ");
    scanf("%s", newBook.category);
    newBook.borrowed = false; // 默认图书未被借出
    newBook.id = bookCount + 1; // 设置图书ID
    library[bookCount++] = newBook; // 将新图书添加到图书馆数组中
    saveBooksToFile(); // 保存图书信息到文件
    printf("增加图书成功.\n"); // 打印成功信息
}

// 显示所有图书
void displayAllBooks() {
    for (int i = 0; i < bookCount; i++) { // 遍历图书馆中的所有图书
        // 打印每本图书的详细信息,包括ID、书名、作者、价格、类型和借阅状态
        printf("ID: %d, 书名: %s, 作者: %s, 价格: %.2f, 类型: %s, 是否被借: %s\n",
               library[i].id, library[i].title, library[i].author, library[i].price, library[i].category,
               library[i].borrowed ? "是" : "否"); // 使用三元运算符判断图书是否被借出
    }
}

// 查找图书
void findBook() {
    int choice; // 用于存储用户选择的查找方式

    // 提示用户选择查找方式,并读取用户的选择
    printf("请选择查找方式:\n1. 按ID查找\n2. 按书名查找\n");
    scanf("%d", &choice);

    if (choice == 1) { // 如果用户选择按ID查找
        int id; // 用于存储用户输入的图书ID

        // 提示用户输入要查找的图书ID,并读取用户输入的图书ID
        printf("请输入要查找的图书ID: ");
        scanf("%d", &id);

        // 遍历图书馆中的所有图书,查找匹配的图书ID
        for (int i = 0; i < bookCount; i++) {
            if (library[i].id == id) { // 如果找到匹配的图书ID
                // 打印找到的图书的详细信息,包括ID、书名、作者、价格、类型和借阅状态
                printf("找到了图书:\nID: %d, 书名: %s, 作者: %s, 价格: %.2f, 类型: %s, 是否被借: %s\n",
                       library[i].id, library[i].title, library[i].author, library[i].price, library[i].category,
                       library[i].borrowed ? "是" : "否");
                return; // 查找完成,函数返回
            }
        }
        // 如果没有找到匹配的图书ID,打印提示信息
        printf("未找到ID为 %d 的图书。\n", id);
    } else if (choice == 2) { // 如果用户选择按书名查找
        char title[NAME_LENGTH]; // 用于存储用户输入的图书书名

        // 提示用户输入要查找的图书书名,并读取用户输入的图书书名
        printf("请输入要查找的图书书名: ");
        scanf("%s", title);

        // 遍历图书馆中的所有图书,查找匹配的图书书名
        for (int i = 0; i < bookCount; i++) {
            if (strcmp(library[i].title, title) == 0) { // 如果找到匹配的图书书名
                // 打印找到的图书的详细信息,包括ID、书名、作者、价格、类型和借阅状态
                printf("找到了图书:\nID: %d, 书名: %s, 作者: %s, 价格: %.2f, 类型: %s, 是否被借: %s\n",
                       library[i].id, library[i].title, library[i].author, library[i].price, library[i].category,
                       library[i].borrowed ? "是" : "否");
                return; // 查找完成,函数返回
            }
        }
        // 如果没有找到匹配的图书书名,打印提示信息
        printf("未找到书名为 '%s' 的图书。\n", title);
    } else { // 如果用户选择了无效的选项
        // 打印提示信息,告知用户选择无效
        printf("无效的选择,请重新输入。\n");
    }
}

// 借阅图书
void borrowBook() {
    int choice; // 用于存储用户选择的借阅方式

    // 提示用户选择借阅方式,并读取用户的选择
    printf("请选择借阅方式:\n1. 按ID借阅\n2. 按书名借阅\n");
    scanf("%d", &choice);

    if (choice == 1) { // 如果用户选择按ID借阅
        int id; // 用于存储用户输入的图书ID

        // 提示用户输入要借阅的图书ID,并读取用户输入的图书ID
        printf("请输入要借阅的图书ID: ");
        scanf("%d", &id);

        // 遍历图书馆中的所有图书,查找匹配的图书ID
        for (int i = 0; i < bookCount; i++) {
            if (library[i].id == id && !library[i].borrowed) { // 如果找到未被借出的匹配图书ID
                library[i].borrowed = true; // 标记图书为已借出状态
                saveBooksToFile(); // 保存图书信息到文件,以便数据持久化
                printf("借阅图书成功。\n"); // 打印借阅成功的消息
                return; // 借阅完成,函数返回
            }
        }
        // 如果没有找到匹配的图书ID,或者图书已被借出,打印提示信息
        printf("未找到ID为 %d 的图书,或者该图书已被借出,借阅失败。\n", id);
    } else if (choice == 2) { // 如果用户选择按书名借阅
        char title[NAME_LENGTH]; // 用于存储用户输入的图书书名

        // 提示用户输入要借阅的图书书名,并读取用户输入的图书书名
        printf("请输入要借阅的图书书名: ");
        scanf("%s", title);

        // 遍历图书馆中的所有图书,查找匹配的图书书名
        for (int i = 0; i < bookCount; i++) {
            if (strcmp(library[i].title, title) == 0 && !library[i].borrowed) { // 如果找到未被借出的匹配图书书名
                library[i].borrowed = true; // 标记图书为已借出状态
                saveBooksToFile(); // 保存图书信息到文件,以便数据持久化
                printf("借阅图书成功。\n"); // 打印借阅成功的消息
                return; // 借阅完成,函数返回
            }
        }
        // 如果没有找到匹配的图书书名,或者图书已被借出,打印提示信息
        printf("未找到书名为 '%s' 的图书,或者该图书已被借出,借阅失败。\n", title);
    } else { // 如果用户选择了无效的选项
        // 打印提示信息,告知用户选择无效
        printf("无效的选择,请重新输入。\n");
    }
}
// 归还图书的函数
void returnBook() {
    int choice; // 用于存储用户选择的归还方式

    // 提示用户选择归还方式,并读取用户的选择
    printf("请选择归还方式:\n1. 按ID归还\n2. 按书名归还\n");
    scanf("%d", &choice);

    if (choice == 1) { // 如果用户选择按ID归还
        int id; // 用于存储用户输入的图书ID

        // 提示用户输入要归还的图书ID,并读取用户输入的图书ID
        printf("请输入要归还的图书ID: ");
        scanf("%d", &id);

        // 遍历图书馆中的所有图书,查找匹配的图书ID
        for (int i = 0; i < bookCount; i++) {
            if (library[i].id == id && library[i].borrowed) { // 如果找到已借出的匹配图书ID
                library[i].borrowed = false; // 标记图书为未借出状态
                saveBooksToFile(); // 保存图书信息到文件,以便数据持久化
                printf("归还图书成功。\n"); // 打印归还成功的消息
                return; // 归还完成,函数返回
            }
        }
        // 如果没有找到匹配的图书ID,或者图书未被借出,打印提示信息
        printf("未找到ID为 %d 的图书,或者该图书未被借出,归还失败。\n", id);
    } else if (choice == 2) { // 如果用户选择按书名归还
        char title[NAME_LENGTH]; // 用于存储用户输入的图书书名

        // 提示用户输入要归还的图书书名,并读取用户输入的图书书名
        printf("请输入要归还的图书书名: ");
        scanf("%s", title);

        // 遍历图书馆中的所有图书,查找匹配的图书书名
        for (int i = 0; i < bookCount; i++) {
            if (strcmp(library[i].title, title) == 0 && library[i].borrowed) { // 如果找到已借出的匹配图书书名
                library[i].borrowed = false; // 标记图书为未借出状态
                saveBooksToFile(); // 保存图书信息到文件,以便数据持久化
                printf("归还图书成功。\n"); // 打印归还成功的消息
                return; // 归还完成,函数返回
            }
        }
        // 如果没有找到匹配的图书书名,或者图书未被借出,打印提示信息
        printf("未找到书名为 '%s' 的图书,或者该图书未被借出,归还失败。\n", title);
    } else { // 如果用户选择了无效的选项
        // 打印提示信息,告知用户选择无效
        printf("无效的选择,请重新输入。\n");
    }
}
//删除图书
void deleteBook() {
    int choice;
    printf("请选择删除方式:\n1. 按ID删除\n2. 按书名删除\n");
    scanf("%d", &choice);

    if (choice == 1) {
        int id;
        printf("请输入要删除的图书ID: ");
        scanf("%d", &id);
        for (int i = 0; i < bookCount; i++) {
            if (library[i].id == id) {
                // 将找到的图书之后的所有图书向前移动一位
                for (int j = i; j < bookCount - 1; j++) {
                    library[j] = library[j + 1];
                }
                // 更新图书数量
                bookCount--;
                // 保存更改到文件
                saveBooksToFile();
                printf("图书删除成功。\n");
                return;
            }
        }
        printf("未找到ID为 %d 的图书,删除失败。\n", id);
    } else if (choice == 2) {
        char title[NAME_LENGTH];
        printf("请输入要删除的图书书名: ");
        scanf("%s", title);
        for (int i = 0; i < bookCount; i++) {
            if (strcmp(library[i].title, title) == 0) {
                // 将找到的图书之后的所有图书向前移动一位
                for (int j = i; j < bookCount - 1; j++) {
                    library[j] = library[j + 1];
                }
                // 更新图书数量
                bookCount--;
                // 保存更改到文件
                saveBooksToFile();
                printf("图书删除成功。\n");
                return;
            }
        }
        printf("未找到书名为 '%s' 的图书,删除失败。\n", title);
    } else {
        printf("无效的选择,请重新输入。\n");
    }
}
int main() {
    loadBooksFromFile();
    int choice;
    while (1) {
        printf("*************************图书馆管理系统*********************\n");
        printf("1. 增加图书\n");
        printf("2. 展示所有图书\n");
        printf("3. 查找图书\n");
        printf("4. 借阅图书\n");
        printf("5. 归还图书\n");
        printf("6. 删除图书\n");
        printf("7. 退出程序\n");
        printf("请选择操作: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1:
                addBook();
                break;
            case 2:
                displayAllBooks();
                break;
            case 3:
                findBook();
                break;
            case 4:
                borrowBook();
                break;
            case 5:
                returnBook();
                break;
            case 6:
                deleteBook();
                break;
            case 7:
                exit(0);
            default:
                printf("无效的选择,请重新输入。\n");
        }
    }
    return 0;
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1897332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RT-Thread Studio与CubeMX联合编程之rtthread启动

看到了好多文章&#xff0c;在rtthread studio中启用mx&#xff0c;后总是复制mx相关msp函数到rt的board.c文件下&#xff0c;实际使用过程中发现并不需要&#xff0c;这里我们看下rt启动流程&#xff0c;看下到底需要不。 1.打开startup_stm32h743xx.S文件&#xff0c;看下芯片…

区块链技术如何改变供应链管理?

引言 供应链管理在现代商业中扮演着至关重要的角色&#xff0c;确保产品和服务从原材料到最终消费者的顺利流转。然而&#xff0c;当前的供应链管理面临诸多挑战&#xff0c;如信息不透明、数据篡改和效率低下等问题&#xff0c;这些问题严重制约了供应链的整体效能和可信度&am…

用kimi和claude自动生成时间轴图表

做时间轴图表并不难&#xff0c;但是很麻烦&#xff0c;先要大量收集相关事件&#xff0c;然后在一些图表软件中反复调整操作。现在借助AI工具&#xff0c;可以自动生成了。 首先&#xff0c;在kimi中输入提示词来获取某个企业的大事记&#xff1a; 联网检索&#xff0c;元语…

【专业指南】移动硬盘坏道下的数据恢复之道

移动硬盘坏道揭秘&#xff1a;数据安全的隐形挑战 在数据日益成为核心资产的今天&#xff0c;移动硬盘作为便携存储的代名词&#xff0c;承载着无数用户的重要信息。然而&#xff0c;随着使用时间的增长和不当操作的影响&#xff0c;移动硬盘可能会遭遇“坏道”这一棘手问题。…

14-30 剑和诗人4 – 具有长上下文窗口的微调 LLM 的数据设计

LLM 中的长上下文窗口的挑战 微调大型语言模型 (LLM) 面临的最大挑战之一在于处理较长的上下文窗口。LLM 经过大量文本数据训练&#xff0c;能够理解和生成类似人类的语言。然而&#xff0c;在推理过程中&#xff0c;这些模型的上下文窗口有限&#xff0c;通常约为 2,048 个标…

基于MCU平台的HMI开发的性能优化与实战(下)

继上篇《基于MCU平台的HMI开发的性能优化与实战&#xff08;上&#xff09;》深入探讨了提升MCU平台HMI开发效率和应用性能的策略后&#xff0c;本文将专注于NXP i.MX RT1170 MCU平台的仪表盘开发实践。我们将重点介绍Qt for MCUs的优化技巧&#xff0c;展示如何通过实际案例应…

三、分布式软总线的架构设计

软总线的主要架构如下&#xff1a; 软总线主体功能分为发现、组网、连接和传输四个基本模块&#xff0c;实现&#xff1a; 即插即用&#xff1a;快速便捷发现周边设备。 自由流转&#xff1a;各设备间自组网&#xff0c;任意建立业务连接&#xff0c;实现自由通信。 高效传…

Ubuntu 22.04远程自动登录桌面环境

如果需要远程自动登录桌面环境&#xff0c;首先需要将Ubuntu的自动登录打开&#xff0c;在【settings】-【user】下面 然后要设置【Sharing】进行桌面共享&#xff0c;Ubuntu有自带的桌面共享功能&#xff0c;不需要另外去安装xrdp或者vnc之类的工具了 点开【Remote Desktop】…

Zerotier+Parsec五分钟实现外网远程访问校园或公司内网

0 需求 校园网或公司内网是不能直接通过远程控制桌面软件访问的&#xff0c;想要实现&#xff0c;就必须通过三方的服务来实现穿透内网。但是这样的缺点就是存在延迟。 1 安装软件 &#xff08;1&#xff09;Zerotier 是内网穿透软件&#xff0c;在两台设备上都要安装&#…

LabVIEW图像分段线性映射

介绍了如何使用LabVIEW对图像进行分段线性映射处理&#xff0c;通过对特定灰度值区间进行不同的线性映射调整&#xff0c;以优化图像的显示效果。案例中详细展示了如何配置和使用LabVIEW中的图像处理工具&#xff0c;包括设置分段区间、计算映射参数和应用映射函数等步骤。 实…

我独立开发生涯的第一个商业化产品 - 微寻

2024 年 04 月 27 日晚八点&#xff0c;微寻 终于正式上线了。时隔一周&#xff0c;我在五一假期的最后一天写下此文&#xff0c;以纪念这款我独立开发生涯的第一个商业化产品。 1. 何为微寻 微寻 为个人网站提供微信码登录 能力。 没错&#xff0c;微寻 是一个小型 SaaS&am…

【数据结构】07.循环队列

一、循环队列的定义 定义&#xff1a;队列主要有顺序队列&#xff0c;循环队列&#xff0c;双端队列&#xff0c;优先队列。而当中循环队列是一种线性数据结构。它也被称为“环形缓冲器”。它只允许在一端进行插入操作&#xff0c;即队尾&#xff08;rear&#xff09;&#xf…

【elasticsearch】IK分词器添加自定义词库,然后更新现有的索引

进入elasticsearch中的plugins位置&#xff0c;找到ik分词器插件&#xff0c;进入ik插件的config文件夹&#xff0c;当中有一个IKAnalyzer.cfg.xml配置文件。使用vim编辑器修改配置文件&#xff1a; vim IKAnalyzer.cfg.xml 配置文件如下&#xff08;添加了自定义字典的位置&…

springboot交流论坛网站-计算机毕业设计源码00304

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了交流论坛网站的开发全过程。通过分析交流论坛网站管理的不足&#xff0c;创建了一个计算机管理交流论坛网站的方案。文章介绍了交流论坛网站的系统分析部分&…

名企面试必问30题(十九)——最近行业内你觉得做的最好的案例是哪一个,为什么?

1.思路 考察你对于行业了解&#xff0c;对于新动态是否保持时时关注&#xff0c;以及判断好和不好的能力。 首先&#xff0c;明确指出您认为行业内做得最好的案例。简要介绍该案例所属的公司和产品。阐述该案例在测试方面的突出特点和优势&#xff0c;例如采用了创新的测试方法…

海量设备集中运维,向日葵远程控制赋能农牧产品加工产业链

产业规模越大&#xff0c;单位成本就越低&#xff0c;这是一个广泛存在的商业规律。 在诸多行业中&#xff0c;农牧业的这种“规模效应”尤为明显&#xff0c;这使得在农牧行业内逐渐发展出许多横跨产业链上下游的大型企业集团&#xff0c;业务甚至覆盖相关产业设备的设计与生…

[产品]理解产品

课程安排 认识互联网行业 1.行业对比 2.互联网公司 广义理解: 互联网行业的公司大都以计算机网络技术为基础, 利用网络平台帮助企业提供服务, 并以此获取收入 3.行业细分 典型产品 认识产品经理 1.职责差异 不同类型的公司, 产品经理岗位所负责的工作都是略有差异的 1,外包…

555 定时器芯片工作原理

在本教程中&#xff0c;您将学习如何使用 555 定时器做一些有趣的事情。许多人用它做的第一件事就是制造闪烁的灯光。但这只是用该芯片可以做很多事情的简单示例之一。您还可以控制电机、创建闹钟、创建乐器等等。 让我们先来概览一下这些引脚。 555 定时器引脚排列 引脚 1 接地…

maven项目启动的时候,自动启动netty

1.写一个监听器,重开一个线程初始化,netty,一定要重开一个线程去启动,要不会阻塞的 public class StartupListener implements ServletContextListener {Overridepublic void contextInitialized(ServletContextEvent sce) {// 在Web应用启动时启动WebSocket服务器new Thread(…

从零开始学量化~Ptrade使用教程(三)——行情界面主要功能

技术分析 除复权 提供向前复权、向后复权&#xff0c;系统默认不复权。此外&#xff0c;全面支持月、周、日线复权&#xff0c;支持向前和向后复权、不同时段分段复权等功能。系统能够根据盘中即时行情&#xff0c;个股K线图可以根据该股除权日的送股、配股及红利情况圆滑地画出…