C语言编写简易图书管理系统

news2024/11/25 12:29:14

这篇文章介绍了一个基本的图书管理系统的实现,它允许用户添加、插入、删除、修改、显示和查询图书的功能。该系统通过使用二进制文件将图书信息保存到磁盘,并且在程序启动时能够加载已保存的图书信息。

介绍

在计算机科学中,图书管理系统是一种用于管理和维护图书馆或个人藏书的系统。它可以帮助用户记录、跟踪和查找图书信息。图书管理系统通常包括一系列功能,如添加、删除、修改、查询和显示图书等,以提高图书的管理效率。

功能项解释
  1. 添加书籍:用户可以输入书籍的标题、作者和出版年份,然后将图书信息添加到系统中。添加的图书信息将被保存到磁盘文件中。
  2. 插入书籍:用户可以选择一个位置,将书籍插入到指定位置。插入书籍时,系统会将后面的书籍向后移动一个位置。插入书籍后,系统会将修改后的图书信息保存到磁盘文件中。
  3. 删除书籍:用户可以选择要删除的书籍位置,然后系统将删除该位置上的书籍,并将后面的书籍向前移动一个位置。删除后的图书信息将被保存到磁盘文件中。
  4. 修改书籍:用户可以选择要修改的书籍位置,然后输入新的标题、作者和出版年份进行修改。修改后的图书信息将被保存到磁盘文件中。
  5. 显示书籍:系统将显示已添加的所有图书信息。如果没有添加任何图书,系统将显示相应提示信息。
  6. 查询书籍:用户可以根据输入内容逐一匹配图书标题、作者和年份,在符合条件的图书中查询。查询结果将显示所有符合条件的图书信息。
相关知识点解释

在这个图书管理系统中,使用了结构体(struct)来存储每本书的信息。结构体是一种自定义的数据类型,它可以包含不同类型的数据,例如字符串和整数。在这个系统中,Book 结构体包含了书籍的标题(title)、作者(author)和出版年份(year)。

文件操作也是这个系统的关键特性之一。文件是计算机存储数据的一种方式,它可以将数据长久地保存在磁盘上。在这个系统中,通过使用文件操作函数(如 fopen、fwrite 和 fread)将图书信息保存到名为 “library.dat” 的二进制文件中,以及从该文件读取已保存的图书信息并加载到程序中。具体来说,使用二进制模式(“wb” 或 “rb”)打开文件来进行写入和读取操作。

另外,这个系统中使用了循环和条件语句来实现不同的功能。通过使用循环(如 do-while 循环),使程序能够反复执行一系列操作,直到用户选择退出。通过使用条件语句(如 switch-case 语句),根据用户选择的功能选项执行相应的操作。

代码解析
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

由于程序中使用了标准输入输出库(stdio.h)、标准库(stdlib.h)和字符串库(string.h),因此需要包含这些库的头文件。

typedef struct {
    char title[100];
    char author[100];
    int year;
} Book;

定义了一个名为 Book 的结构体类型,包含了三个成员变量:title(标题)、author(作者)和 year(年份)。这个结构体类型用于存储图书的信息。

void addBook(Book *books, int *count) {
    // ...
}

定义了一个名为 addBook 的函数,用于添加书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void insertBook(Book *books, int *count) {
    // ...
}

定义了一个名为 insertBook 的函数,用于插入书籍。这个函数同样接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void deleteBook(Book *books, int *count) {
    // ...
}

定义了一个名为 deleteBook 的函数,用于删除书籍。这个函数同样接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void modifyBook(Book *books, int count) {
    // ...
}

定义了一个名为 modifyBook 的函数,用于修改书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

void displayBooks(Book *books, int count) {
    // ...
}

定义了一个名为 displayBooks 的函数,用于显示书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

void searchBooks(Book *books, int count) {
    // ...
}

定义了一个名为 searchBooks 的函数,用于查询书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

int main() {
    // ...
}

定义了一个 main 函数,它是程序的主函数,程序从这里开始执行。

完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char title[100];
    char author[100];
    int year;
} Book;

void addBook(Book *books, int *count) {
    char title[100];
    char author[100];
    int year;
    
    printf("请输入书籍标题:");
    scanf("%s", title);
    
    printf("请输入书籍作者:");
    scanf("%s", author);
    
    printf("请输入书籍出版年份:");
    scanf("%d", &year);
    
    Book book;
    strcpy(book.title, title);
    strcpy(book.author, author);
    book.year = year;
    
    books[*count] = book;
    (*count)++;
    
    FILE *file = fopen("library.dat", "ab");
    if (file == NULL) {
        printf("无法打开文件\n");
        exit(1);
    }
    
    fwrite(&book, sizeof(Book), 1, file);
    
    fclose(file);
    printf("添加书籍成功!\n");
}

void insertBook(Book *books, int *count) {
    char title[100];
    char author[100];
    int year;
    int position;

    printf("请输入要插入的位置:");
    scanf("%d", &position);

    if (position < 0 || position > (*count)) {
        printf("无效的位置\n");
        return;
    }

    printf("请输入书籍标题:");
    scanf("%s", title);

    printf("请输入书籍作者:");
    scanf("%s", author);

    printf("请输入书籍出版年份:");
    scanf("%d", &year);

    Book book;
    strcpy(book.title, title);
    strcpy(book.author, author);
    book.year = year;

    for (int i = *count; i > position; i--) {
        books[i] = books[i - 1];
    }

    books[position] = book;
    (*count)++;

    FILE *file = fopen("library.dat", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        exit(1);
    }

    for (int i = 0; i < *count; i++) {
        fwrite(&books[i], sizeof(Book), 1, file);
    }

    fclose(file);
    printf("插入书籍成功!\n");
}

void deleteBook(Book *books, int *count) {
    int position;

    printf("请输入要删除的位置:");
    scanf("%d", &position);

    if (position < 0 || position >= (*count)) {
        printf("无效的位置\n");
        return;
    }

    for (int i = position; i < (*count) - 1; i++) {
        books[i] = books[i + 1];
    }

    (*count)--;

    FILE *file = fopen("library.dat", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        exit(1);
    }

    for (int i = 0; i < *count; i++) {
        fwrite(&books[i], sizeof(Book), 1, file);
    }

    fclose(file);
    printf("删除书籍成功!\n");    
}

void modifyBook(Book *books, int count) {
    int position;

    printf("请输入要修改的位置:");
    scanf("%d", &position);

    if (position < 0 || position >= count) {
        printf("无效的位置\n");
        return;
    }

    printf("请输入要修改的书籍标题:");
    scanf("%s", books[position].title);

    printf("请输入要修改的书籍作者:");
    scanf("%s", books[position].author);

    printf("请输入要修改的书籍出版年份:");
    scanf("%d", &books[position].year);

    FILE *file = fopen("library.dat", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        exit(1);
    }

    for (int i = 0; i < count; i++) {
        fwrite(&books[i], sizeof(Book), 1, file);
    }

    fclose(file);
    printf("修改书籍成功!\n");
}

void displayBooks(Book *books, int count) {
    if (count == 0) {
        printf("暂无书籍信息\n");
    } else {
        printf("图书列表:\n");
        for (int i = 0; i < count; i++) {
            printf("书籍标题: %s\n", books[i].title);
            printf("书籍作者: %s\n", books[i].author);
            printf("书籍出版年份: %d\n", books[i].year);
            printf("--------------------\n");
        }
    }
}

void searchBooks(Book *books, int count) {
    char query[100];

    printf("请输入要查询的内容:");
    scanf("%s", query);

    printf("查询结果:\n");
    for (int i = 0; i < count; i++) {
        if (strstr(books[i].title, query) != NULL || strstr(books[i].author, query) != NULL || books[i].year == atoi(query)) {
            printf("书籍标题: %s\n", books[i].title);
            printf("书籍作者: %s\n", books[i].author);
            printf("书籍出版年份: %d\n", books[i].year);
            printf("--------------------\n");
        }
    }
}

int main() {
    Book books[100];
    int count = 0;

    FILE *file = fopen("library.dat", "rb");
    if (file != NULL) {
        while (!feof(file)) {
            Book book;
            fread(&book, sizeof(Book), 1, file);
            if (!feof(file)) {
                books[count] = book;
                count++;
            }
        }
        fclose(file);
    }

    int choice;

    do {
        printf("欢迎使用图书管理系统\n");
        printf("1. 添加书籍\n");
        printf("2. 插入书籍\n");
        printf("3. 删除书籍\n");
        printf("4. 修改书籍\n");
        printf("5. 显示书籍\n");
        printf("6. 查询书籍\n");
        printf("0. 退出\n");
        printf("请输入选项: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                addBook(books, &count);
                break;
            case 2:
                insertBook(books, &count);
                break;
            case 3:
                deleteBook(books, &count);
                break;
            case 4:
                modifyBook(books, count);
                break;
            case 5:
                displayBooks(books, count);
                break;
            case 6:
                searchBooks(books, count);
                break;
            case 0:
                printf("谢谢使用,再见!\n");
                break;
            default:
                printf("无效的选项,请重新输入\n");
        }
        printf("\n");

    } while (choice != 0);

    return 0;
}

运行测试如下:测试运行

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

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

相关文章

buffer overflow detected

背景 在应用上云改造中&#xff0c;业务场景如下&#xff1a; 在使用ecs的场景中&#xff0c;应用的ip都是固定的&#xff1b;在使用k8s之后pod的ip就变的不固定了&#xff0c;k8s提供了statefulset的模式来支持这种场景&#xff0c;以固定域名的方式支持。 问题 在平台pod开…

Locust性能测试框架,从入门到精通

1. Locust简介 Locust是使用Python语言编写实现的开源性能测试工具&#xff0c;简洁、轻量、高效&#xff0c;并发机制基于gevent协程&#xff0c;可以实现单机模拟生成较高的并发压力。 主要特点如下&#xff1a; 使用普通的Python脚本用户测试场景分布式和可扩展&#xff…

论文阅读:ECAPA-TDNN

1. 提出ECAPA-TDNN架构 TDNN本质上是1维卷积&#xff0c;而且常常是1维膨胀卷积&#xff0c;这样的一种结构非常注重context&#xff0c;也就是上下文信息&#xff0c;具体而言&#xff0c;是在frame-level的变换中&#xff0c;更多地利用相邻frame的信息&#xff0c;甚至跳过…

用于医学图像分割的分段任意模型 (SAM)

一、说明 在不断发展的人工智能 (AI) 领域&#xff0c;医学成像是一个正在经历深刻变革的领域。乘着这一变革浪潮&#xff0c;Facebook 的&#xff08;现为 Meta&#xff09;研究小组开发了一种突破性的模型架构&#xff0c;称为 SegmentAnything (SAM)。SAM 的卓越之处在于它能…

队列:如何在线程池等有限资源池中的应用?

文章来源于极客时间前google工程师−王争专栏。 我们知道&#xff0c;CPU 资源是有限的&#xff0c;任务的处理速度与线程个数并不是线性正相关。相反&#xff0c;过多的线程反而会导致CPU频繁切换&#xff0c;处理性能下降。所以&#xff0c;线程池的大小一般都是综合考虑要处…

MTK6877/MT6877天玑900安卓5G核心板_安卓开发板主板定制开发

2021年5月13日&#xff0c;MediaTek 宣布发布旗下的天玑900系列芯片&#xff0c;又名MT6877。天玑900基于6nm先进工艺制造&#xff0c;搭载硬件级4K HDR视频录制引擎&#xff0c;支持1.08亿像素摄像头、5G双全网通和Wi-Fi 6连接、旗舰级存储规格和120Hz的FHD超高清分辨率显示&a…

GD32F10x系列单片机下载方式

GD32F10x系列单片机下载方式 简介烧录接口KEIL在线烧录选择下载器ST-link接线 DAP、JLINK等 烧录软件烧录STlink接线操作 ISP烧录接线 总结 简介 GD32F10x系列的单片机是兆易创新推出对标意法半导体STM32F10x系列的国产单片机。本文将以GD32F103C8T6展开&#xff0c;GD32F103C8…

持续提升信息安全运维保障服务能力,天玑科技助力企业快速实现数字化转型

近年来&#xff0c;以互联网、云计算、大数据、物联网为代表的新一代信息技术快速发展。给人们的生产生活方式带来方便的同时&#xff0c;也给信息系统的安全带来了严峻的挑战。我国信息化和信息安全保障工作的不断深入推进&#xff0c;以应急处理、风险评估、灾难恢复、系统测…

电动车租赁小程序开发方案详解php

电动车租赁小程序开发功能有哪些&#xff1f; 1.地图找车 进入小程序后&#xff0c;在地图上显示门店位置&#xff0c;点击位置可查看门店信息。进入门店后可以看到车辆列表&#xff0c;车辆里详细的介绍的车辆名称、图片、车辆介绍、租赁价格、押金等信息。 2.租赁/购车 电…

【LeetCode:1488. 避免洪水泛滥 | 有序表 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

十五、【历史记录画笔工具组】

文章目录 历史记录画笔工具历史记录艺术画笔工具 历史记录画笔工具 历史记录画笔工具很简单&#xff0c;就是将画笔工具嗯&#xff0c;涂抹过的修改过的地方&#xff0c;然后用历史记录画笔工具重新修改回来&#xff0c;比如我们将三叠美元中的一叠用画笔工具先涂抹掉&#xf…

CSS 边框

CSS 边框属性 CSS边框属性允许你指定一个元素边框的样式和颜色。 在四边都有边框 红色底部边框 圆角边框 左侧边框带宽度&#xff0c;颜色为蓝色 边框样式 边框样式属性指定要显示什么样的边界。 border-style属性用来定义边框的样式 border-style 值: none: 默认无边框…

防爆对讲机在消防救援工作中的重要性

据相关报道2022年国内因易燃易爆造成的事故825起&#xff0c;死亡1人以上的事故有103起&#xff0c;共造成234人死亡;火灾爆炸事故306起&#xff0c;占事故总数的37%&#xff0c;造成93人死亡&#xff0c;占死亡总人数的40%。 消防救援队伍在实施灭火作战、应急救援工作面对复杂…

新版Android Studio搜索不到Lombok以及无法安装Lombok插件的问题

前言 在最近新版本的Android Studio中&#xff0c;使用插件时&#xff0c;在插件市场无法找到Lombox Plugin&#xff0c;具体表现如下图所示&#xff1a; 1、操作步骤&#xff1a; &#xff08;1&#xff09;打开Android Studio->Settings->Plugins&#xff0c;搜索Lom…

Notepad++使用技巧

显示远程连接的文件目录 自动完成&#xff1a;函数自动提示 自动输入&#xff1a;输入一半括号自动补全另一半 自动关联 .pc文件识别为C 列模式 按住Alt不松手&#xff0c;可以直接范围选择&#xff0c;便于编辑选择的区域 关键行筛选 1.进入搜索页面的标记 2.选中标…

【C++】继承 ③ ( 继承的一些重要特性 | 子类拥有父类的所有成员 | 多态性 | 子类可以拥有父类没有的成员 | 代码示例 )

文章目录 一、继承的一些重要特性1、子类拥有父类的所有成员2、子类可以拥有父类没有的成员3、多态性 二、代码示例 一、继承的一些重要特性 1、子类拥有父类的所有成员 子类 继承 父类 , 则 子类 拥有 父类的 所有 成员变量 和 成员函数 ; 这里要注意 : 子类 拥有 父类的 私有…

海外代理高性价比推荐——精选list

做跨境电商的都明白&#xff0c;无论运营店铺还是社媒账号&#xff0c;都需要海外代理&#xff0c;而在市场上海外的代理很多&#xff0c;到底什么才是适合自己呢&#xff1f;下面我进行测评后整理列出了一份稳定&#xff0c;高性价比好用的几款海外代理。 1、IPFoxy全球代理I…

NeurIPS 2023 | MQ-Det: 首个支持多模态查询的开放世界目标检测大模型

目前的开放世界目标检测模型大多遵循文本查询的模式&#xff0c;即利用类别文本描述在目标图像中查询潜在目标。然而&#xff0c;这种方式往往会面临“广而不精”的问题。一图胜千言&#xff0c;为此&#xff0c;作者提出了基于多模态查询的目标检测&#xff08;MQ-Det&#xf…

postman接口测试

HTTP的接口测试工具有很多&#xff0c;可以进行http请求的方式也有很多&#xff0c;但是可以直接拿来就用&#xff0c;而且功能还支持的不错的&#xff0c;我使用过的来讲&#xff0c;还是postman比较上手。 优点&#xff1a; 1、支持用例管理 2、支持get、post、文件上传、响…

解决modprobe加载驱动问题

一、insmod与modprobe 在Linux中&#xff0c;linux设备驱动有两种加载方式insmod和modprobe。 insmod insmod是一个加载模块的命令&#xff0c;但和modprobe不同的是&#xff0c;insmod不会自动加载依赖的模块。如果你需要加载的模块有依赖关系&#xff0c;那么你需要手动一个…