C++ 实现图书馆资料管理系统

news2024/9/24 11:33:48

1、问题描述 :

图书馆中的资料很多,如果能分类对其资料流通进行管理,将会带来很多方 便,因此需要有一个媒体库管理系统。 图书馆共有三大类物品资料:图书、视频光盘、图画。 这三类物品共同具有的属性有:编号、标题、作者、评级(未评级,一般 成人,儿童) 等。其中图书类增加出版社、ISBN号、页数等信息;视频光盘类增加出品者 的名字、出品年份和视频时长等信息;图画类增加出品国籍、作品的长和宽 (以厘米计,整数)等信息。 读者:基本信息,可借阅本数 管理员:负责借阅

2、功能要求 :

(1)添加物品:主要完成图书馆三类物品信息的添加,要求编号唯一。当添 加了重复的编号时,则提示数据添加重复并取消添加:查询物品可按照三种 方式来查询物品,分别为: 按标题查询:输入标题,输出所查询的信息,若不存在该记录,则提示“该 标题+存在!”; 按编号查询:输入编号,输出所查询的信息,若不存在该记录,则提示“该 编号不存在!”; 按类别查询:输入类别,输出所查询的信息,若不存在记录,则提示“该类 别没有物品!”;

(2)显示物品库:输出当前物品库中所有物品信息,每条记录占据一行。

(3)编辑物品:可根据查询结果对相应的记录进行修改,修改时注意编号的 唯一性。

(4)删除物品:主要完成图书馆物品信息的删除。如果当前物品库为空,则 提示“物品库为空!”,并返回操作:否则,输入要删除的编号,根据编号删 除该物品的记录,如果该编号不在物品库中,则提示“该编号不存在”。

(5)借阅,管理员负责将物品借阅给读者,数据保存到文件中 。

(6)统计信息 输出当前物品库中总物品数,以及按物品类别,统计出山前物品中各类别的 物品数并显。

(7)物品存盘:将当前程序中的物品信息存入文件中。

(8)读出物品 从文件中将物品信息读入程序。 开发完代码后需要进行测试,如果报错请修改,知道各项功能都可以正常运行。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <unordered_map>
#include <windows.h>
using namespace std;

enum Rating { UNRATED, ADULT, CHILD };

string ratingToString(Rating rating) {
    switch (rating) {
        case UNRATED: return "未评级";
        case ADULT: return "成人";
        case CHILD: return "儿童";
        default: return "";
    }
}

class Media {
public:
    int id;
    string title;
    string author;
    Rating rating;

    Media(int id, string title, string author, Rating rating)
        : id(id), title(title), author(author), rating(rating) {}

    virtual void display() const {
        cout << "ID: " << id << ", 标题: " << title << ", 作者: " << author << ", 评级: " << ratingToString(rating) << endl;
    }

    virtual ~Media() {}
};

class Book : public Media {
public:
    string publisher;
    string isbn;
    int pages;

    Book(int id, string title, string author, Rating rating, string publisher, string isbn, int pages)
        : Media(id, title, author, rating), publisher(publisher), isbn(isbn), pages(pages) {}

    void display() const override {
        Media::display();
        cout << "出版社: " << publisher << ", ISBN: " << isbn << ", 页数: " << pages << endl;
    }
};

class Video : public Media {
public:
    string producer;
    int year;
    int duration;

    Video(int id, string title, string author, Rating rating, string producer, int year, int duration)
        : Media(id, title, author, rating), producer(producer), year(year), duration(duration) {}

    void display() const override {
        Media::display();
        cout << "出品者: " << producer << ", 年份: " << year << ", 时长: " << duration << " mins" << endl;
    }
};

class Picture : public Media {
public:
    string nationality;
    int length;
    int width;

    Picture(int id, string title, string author, Rating rating, string nationality, int length, int width)
        : Media(id, title, author, rating), nationality(nationality), length(length), width(width) {}

    void display() const override {
        Media::display();
        cout << "国籍: " << nationality << ", 尺寸: " << length << "x" << width << " cm" << endl;
    }
};

class Library {
    unordered_map<int, Media*> mediaCollection;

public:
    ~Library() {
        for (auto& pair : mediaCollection) {
            delete pair.second;
        }
    }

    void addMedia(Media* media) {
        if (mediaCollection.find(media->id) != mediaCollection.end()) {
            cout << "检测到重复的 ID, 未添加资料." << endl;
            delete media;
            return;
        }
        mediaCollection[media->id] = media;
        cout << "资料添加成功." << endl;
    }

    void queryByTitle(const string& title) {
        bool found = false;
        for (const auto& pair : mediaCollection) {
            if (pair.second->title == title) {
                pair.second->display();
                found = true;
            }
        }
        if (!found) cout << " 标题 \"" << title << "\" 不存在!" << endl;
    }

    void queryById(int id) {
        if (mediaCollection.find(id) != mediaCollection.end()) {
            mediaCollection[id]->display();
        } else {
            cout << " ID \"" << id << "\" 不存在!" << endl;
        }
    }

    void queryByType(const string& type) {
        bool found = false;
        for (const auto& pair : mediaCollection) {
            if ((type == "Book" && dynamic_cast<Book*>(pair.second)) ||
                (type == "Video" && dynamic_cast<Video*>(pair.second)) ||
                (type == "Picture" && dynamic_cast<Picture*>(pair.second))) {
                pair.second->display();
                found = true;
            }
        }
        if (!found) cout << "分类没有 \"" << type << "\" 找到!" << endl;
    }

    void displayAll() {
        if (mediaCollection.empty()) {
            cout << "数据库中没有相关资料." << endl;
            return;
        }
        for (const auto& pair : mediaCollection) {
            pair.second->display();
        }
    }

    void editMedia(int id, Media* newMedia) {
        if (mediaCollection.find(id) == mediaCollection.end()) {
            cout << " ID \"" << id << "\" 不存在!" << endl;
            delete newMedia;
            return;
        }
        delete mediaCollection[id];
        mediaCollection[id] = newMedia;
        cout << "资料编辑成功." << endl;
    }

    void deleteMedia(int id) {
        if (mediaCollection.find(id) == mediaCollection.end()) {
            cout << " ID \"" << id << "\" 不存在!" << endl;
            return;
        }
        delete mediaCollection[id];
        mediaCollection.erase(id);
        cout << "资料删除成功." << endl;
    }

    void saveToFile(const string& filename) {
        ofstream file(filename, ios::binary);
        if (!file) {
            cout << "无法打开文件进行写入." << endl;
            return;
        }
        for (const auto& pair : mediaCollection) {
            Media* media = pair.second;
            file.write((char*)&media->id, sizeof(media->id));
            size_t length = media->title.size();
            file.write((char*)&length, sizeof(length));
            file.write(media->title.c_str(), length);
            length = media->author.size();
            file.write((char*)&length, sizeof(length));
            file.write(media->author.c_str(), length);
            file.write((char*)&media->rating, sizeof(media->rating));

            if (Book* book = dynamic_cast<Book*>(media)) {
                char type = 'B';
                file.write(&type, sizeof(type));
                length = book->publisher.size();
                file.write((char*)&length, sizeof(length));
                file.write(book->publisher.c_str(), length);
                length = book->isbn.size();
                file.write((char*)&length, sizeof(length));
                file.write(book->isbn.c_str(), length);
                file.write((char*)&book->pages, sizeof(book->pages));
            } else if (Video* video = dynamic_cast<Video*>(media)) {
                char type = 'V';
                file.write(&type, sizeof(type));
                length = video->producer.size();
                file.write((char*)&length, sizeof(length));
                file.write(video->producer.c_str(), length);
                file.write((char*)&video->year, sizeof(video->year));
                file.write((char*)&video->duration, sizeof(video->duration));
            } else if (Picture* picture = dynamic_cast<Picture*>(media)) {
                char type = 'P';
                file.write(&type, sizeof(type));
                length = picture->nationality.size();
                file.write((char*)&length, sizeof(length));
                file.write(picture->nationality.c_str(), length);
                file.write((char*)&picture->length, sizeof(picture->length));
                file.write((char*)&picture->width, sizeof(picture->width));
            }
        }
        cout << "数据保存到文件." << endl;
    }

    void loadFromFile(const string& filename) {
        ifstream file(filename, ios::binary);
        if (!file) {
            cout << "无法打开文件进行读取." << endl;
            return;
        }
        while (file.peek() != EOF) {
            int id;
            file.read((char*)&id, sizeof(id));

            size_t length;
            file.read((char*)&length, sizeof(length));
            string title(length, ' ');
            file.read(&title[0], length);

            file.read((char*)&length, sizeof(length));
            string author(length, ' ');
            file.read(&author[0], length);

            Rating rating;
            file.read((char*)&rating, sizeof(rating));

            char type;
            file.read(&type, sizeof(type));

            if (type == 'B') {
                file.read((char*)&length, sizeof(length));
                string publisher(length, ' ');
                file.read(&publisher[0], length);

                file.read((char*)&length, sizeof(length));
                string isbn(length, ' ');
                file.read(&isbn[0], length);

                int pages;
                file.read((char*)&pages, sizeof(pages));

                mediaCollection[id] = new Book(id, title, author, rating, publisher, isbn, pages);
            } else if (type == 'V') {
                file.read((char*)&length, sizeof(length));
                string producer(length, ' ');
                file.read(&producer[0], length);

                int year, duration;
                file.read((char*)&year, sizeof(year));
                file.read((char*)&duration, sizeof(duration));

                mediaCollection[id] = new Video(id, title, author, rating, producer, year, duration);
            } else if (type == 'P') {
                file.read((char*)&length, sizeof(length));
                string nationality(length, ' ');
                file.read(&nationality[0], length);

                int length, width;
                file.read((char*)&length, sizeof(length));
                file.read((char*)&width, sizeof(width));

                mediaCollection[id] = new Picture(id, title, author, rating, nationality, length, width);
            }
        }
        cout << "从文件加载的数据." << endl;
    }

    void countItems() {
        cout << "Total items: " << mediaCollection.size() << endl;
        int books = 0, videos = 0, pictures = 0;
        for (const auto& pair : mediaCollection) {
            if (dynamic_cast<Book*>(pair.second)) books++;
            else if (dynamic_cast<Video*>(pair.second)) videos++;
            else if (dynamic_cast<Picture*>(pair.second)) pictures++;
        }
        cout << "Books: " << books << ", Videos: " << videos << ", Pictures: " << pictures << endl;
    }
};

int main() {
    SetConsoleOutputCP(65001);
    Library library;
    while (true) {
        cout << "欢迎使用图书馆资料管理系统: \n1. 添加资料\n2. 按标题查询资料\n3. 按ID查询资料\n4. 按类别查询资料\n5. 显示所有资料\n6. 编辑资料\n7. 删除资料\n8. 资料存盘\n9. 读取资料\n10. 统计资料\n11. 退出\n";
        int choice;
        cin >> choice;

        if (choice == 1) {
            cout << "选择类别: 1. 图书 2. 视频 3. 图画\n";
            int type;
            cin >> type;
            int id;
            string title, author;
            int rating;
            cout << "输入ID: ";
            cin >> id;
            cout << "输入标题: ";
            cin.ignore();
            getline(cin, title);
            cout << "输入作者: ";
            getline(cin, author);
            cout << "输入评级 (0 未评级, 1 成人, 2 儿童): ";
            cin >> rating;

            if (type == 1) {
                string publisher, isbn;
                int pages;
                cout << "输入出版社: ";
                cin.ignore();
                getline(cin, publisher);
                cout << "输入ISBN: ";
                getline(cin, isbn);
                cout << "输入页数: ";
                cin >> pages;
                library.addMedia(new Book(id, title, author, static_cast<Rating>(rating), publisher, isbn, pages));
            } else if (type == 2) {
                string producer;
                int year, duration;
                cout << "输入出品者: ";
                cin.ignore();
                getline(cin, producer);
                cout << "输入出品年份: ";
                cin >> year;
                cout << "输入时长(分钟): ";
                cin >> duration;
                library.addMedia(new Video(id, title, author, static_cast<Rating>(rating), producer, year, duration));
            } else if (type == 3) {
                string nationality;
                int length, width;
                cout << "输入出品国籍: ";
                cin.ignore();
                getline(cin, nationality);
                cout << "输入长度(厘米): ";
                cin >> length;
                cout << "输入宽度(厘米): ";
                cin >> width;
                library.addMedia(new Picture(id, title, author, static_cast<Rating>(rating), nationality, length, width));
            }
        } else if (choice == 2) {
            string title;
            cout << "输入标题: ";
            cin.ignore();
            getline(cin, title);
            library.queryByTitle(title);
        } else if (choice == 3) {
            int id;
            cout << "输入ID: ";
            cin >> id;
            library.queryById(id);
        } else if (choice == 4) {
            string type;
            cout << "输入类别 (图书, 视频, 图画): ";
            cin.ignore();
            getline(cin, type);
            library.queryByType(type);
        } else if (choice == 5) {
            library.displayAll();
        } else if (choice == 6) {
            int id;
            cout << "输入要编辑资料的ID: ";
            cin >> id;
            cout << "选择新分类: 1. 图书 2. 视频 3. 图画\n";
            int type;
            cin >> type;
            string title, author;
            int rating;
            cout << "输入新标题: ";
            cin.ignore();
            getline(cin, title);
            cout << "输入新作者: ";
            getline(cin, author);
            cout << "输入新评级 (0 未评级, 1 成人, 2 儿童): ";
            cin >> rating;

            if (type == 1) {
                string publisher, isbn;
                int pages;
                cout << "输入新的出版社: ";
                cin.ignore();
                getline(cin, publisher);
                cout << "输入新的ISBN: ";
                getline(cin, isbn);
                cout << "输入新的页数: ";
                cin >> pages;
                library.editMedia(id, new Book(id, title, author, static_cast<Rating>(rating), publisher, isbn, pages));
            } else if (type == 2) {
                string producer;
                int year, duration;
                cout << "输入新的作者: ";
                cin.ignore();
                getline(cin, producer);
                cout << "输入新的年份: ";
                cin >> year;
                cout << "输入新的持续时间(分钟): ";
                cin >> duration;
                library.editMedia(id, new Video(id, title, author, static_cast<Rating>(rating), producer, year, duration));
            } else if (type == 3) {
                string nationality;
                int length, width;
                cout << "输入新国籍: ";
                cin.ignore();
                getline(cin, nationality);
                cout << "输入新长度(厘米): ";
                cin >> length;
                cout << "输入新宽度(厘米): ";
                cin >> width;
                library.editMedia(id, new Picture(id, title, author, static_cast<Rating>(rating), nationality, length, width));
            }
        } else if (choice == 7) {
            int id;
            cout << "输入要删除的资料ID: ";
            cin >> id;
            library.deleteMedia(id);
        } else if (choice == 8) {
            string filename;
            cout << "输入文件名: ";
            cin.ignore();
            getline(cin, filename);
            library.saveToFile(filename);
        } else if (choice == 9) {
            string filename;
            cout << "输入文件名: ";
            cin.ignore();
            getline(cin, filename);
            library.loadFromFile(filename);
        } else if (choice == 10) {
            library.countItems();
        } else if (choice == 11) {
            break;
        } else {
            cout << "无效的选择,请再试一次." << endl;
        }
    }

    return 0;
}

3、运行效果:

录入:

统计:

查询:

需要协助课设或论文的加微信:LAF20151116

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

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

相关文章

BFS:多源BFS问题

一、多源BFS简介 超级源点&#xff1a;其实就是把相应的原点一次性都丢到队列中 二、01矩阵 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:const int dx[4]{1,-1,0,0};const int dy[4]{0,0,1,-1};vector<vector<int>> updateMatrix(vector…

2024最新国际版抖音TikTok安装教程,免root免拔卡安卓+iOS,附全套安装工具!

我是阿星&#xff0c;今天给大家带来是2024年最新TikTok国际版抖音的下载和安装教程&#xff0c;而且还是免root免拔卡的那种&#xff0c;安卓和iOS都能用哦&#xff01;由于某些原因&#xff0c;国内用户并不能使用TikTok。今天阿星就教一下大家怎么安装TikTok。 TikTok在全球…

自动驾驶AVM环视算法--540度全景的算法实现和exe测试demo

参考&#xff1a;金书世界 540度全景影像是什么 540度全景影像是在360度全景影像基础上的升级功能&#xff0c;它增加了更多的摄像头来收集周围的图像数据。通常&#xff0c;这些摄像头分布在车辆的更多位置&#xff0c;例如车顶、车底等&#xff0c;以便更全面地捕捉车辆周围…

【C++题解】1156 - 排除异形基因

问题&#xff1a;1156 - 排除异形基因 类型&#xff1a;数组基础 题目描述&#xff1a; 神舟号飞船在完成宇宙探险任务回到地球后&#xff0c;宇航员张三感觉身体不太舒服&#xff0c;去了医院检查&#xff0c;医生诊断结果&#xff1a;张三体内基因已被改变&#xff0c;原有…

微信小程序---npm 支持

一、构建 npm 目前小程序已经支持使用 npm 安装第三方包&#xff0c;但是这些 npm 包在小程序中不能够直接使用&#xff0c;必须得使用小程序开发者工具进行构建后才可以使用。 为什么得使用小程序开发者工具需要构建呢❓ 因为 node_modules 目录下的包&#xff0c;不会参与…

【建议收藏】一万字图文并茂,终于有人把GPT的玩法整理全了

1. 学生常用 1.1 辅导作业、写作业 打数学建模和写期末作业~ Openai GPT-4o 模型从 2024 年 5 月发布以来&#xff0c;作为各项性能评测综合第一的 GPT。 对于法律类&#xff0c;语言类的作业&#xff0c;随意秒杀了&#xff01;&#xff01; 所以我决定让他做一道高等数学…

【开源项目的机遇与挑战】探索、贡献与应对

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 目录 引言 一&#xff1a;开源项目的发展趋势 &#x1f343;开源项目的蓬勃发展现状 &#x1f343;开…

GitHub访问慢的问题彻底解决(一)

1、访问巨慢&#xff0c;图片打不开 按照下面这个项目来解决 https://github.com/521xueweihan/GitHub520 【前提】能够访问github 本项目无需安装任何程序&#xff0c;通过修改本地 hosts 文件&#xff0c;试图解决&#xff1a; GitHub 访问速度慢的问题GitHub 项目中的图…

【STM32标准库】读写内部FLASH

1.内部FLASH的构成 STM32F407的内部FLASH包含主存储器、系统存储器、OTP区域以及选项字节区域。 一般我们说STM32内部FLASH的时候&#xff0c;都是指这个主存储器区域&#xff0c;它是存储用户应用程序的空间。STM32F407ZGT6型号芯片&#xff0c; 它的主存储区域大小为1MB。其…

JavaSE 面向对象程序设计进阶 IO 综合练习 利用糊涂包生成假数据 随机点名器 登录案例

目录 生成假数据 利用糊涂包生成假数据 随机点名器 综合练习 生成假数据 制造假数据 制造假数据也是开发中的一个能力 在各个网上爬取数据 这是其中一个方法 爬取网站中的内容 import cn.hutool.core.io.FileUtil;import java.io.IOException; import java.io.InputSt…

银行函证业务的数字化转型:合合信息智能文档处理平台如何实现集中化处理与全流程合规?

“银行函证”是注册会计师在获取被审计单位授权后&#xff0c;直接向银行业金融机构发出询证函&#xff0c;银行业金融机构针对所收到的询证函&#xff0c;查询、核对相关信息并直接提供书面回函的过程。 财政部、银保监会联合发布《关于加快推进银行函证规范化、集约化、数字…

教程系列2 | 趋动云『社区项目』一步实现与 AI 对话

上周&#xff0c;我们沉浸于文生图【教程系列1 | 趋动云『社区项目』极速部署 SD WebUI】的奇幻世界&#xff0c;领略了文字转化为视觉的无限乐趣。本周我们继续与 AI 进行对话&#xff0c;探索智能交互的无限魅力&#xff01; Llama3-8B-Chinese-Chat Llama3-8B-Chinese-Cha…

system V共享内存【Linux】

文章目录 原理shmgetftokshmat(share memory attach)shmdt&#xff0c;去关联&#xff08;share memory delete attach&#xff09;shmctl ,删除共享内存共享内存与管道 原理 共享内存本质让不同进程看到同一份资源。 申请共享内存&#xff1a; 1、操作系统在物理内存当中申请…

PGCCC|【PostgreSQL】PCA认证考试大纲#postgresql认证

PostgreSQL Certified Associate|PCA&#xff08;初级&#xff09; 学员将学会安装、创建和维护PostgreSQL数据库。学完后&#xff0c;学员可以从事PostgreSQL数据库的数据操作和管理等工作。 获证途径 参加PostgreSQL培训再考试 考试为上机考试。 PostgreSQL PCA培训考试课…

【嵌入式Linux】<知识点> GDB调试(更新中)

文章目录 前言 一、GDB调试预备工作 二、GDB的启动与退出 三、GDB中查看源代码 四、GDB断点操作 五、GDB调试指令 前言 在专栏【嵌入式Linux】应用开发篇_Linux打工仔的博客中&#xff0c;我们已经写了大量的源程序。但是在调试这些程序时我们都是通过printf大法和肉眼除…

网络(一)——初始网络

文章目录 计算机网络的背景网络发展认识 "协议" 网络协议初识协议分层网络分层 网络传输基本流程数据包封装和分用网络中的地址管理认识IP地址认识MAC地址 计算机网络的背景 网络发展 独立模式:计算机之间相互独立 在最早的时候&#xff0c;计算机之间是相互独立的&…

【启明智显分享】乐鑫HMI方案4.3寸触摸串口屏应用于称重测力控制仪表

称重测力控制仪表是将称重传感器信号&#xff08;或再通过重量变送器&#xff09;转换为重量数字显示&#xff0c;并可对重量数据进行传输、储存、统计、打印的电子设备&#xff0c;常用于工农业生产中的自动化配料&#xff0c;称重&#xff0c;以提高生产效率。随着工业化的发…

Oracle11g_RAC for vmware workstation 安装教程(on suse11)

一、前言 本文介绍在vmware workstation环境下&#xff0c;基于suse11sp1操作系统安装Oracle11g RACASM 数据库&#xff08;两节点&#xff09;。 1.1 RAC中的基本概念 安装ORACLE RACASM前&#xff0c;您可能需要事先简要的了解RAC&#xff0c;CRS&#xff0c;ASM的概念。 1.1…

【Linux】01.Linux 的常见指令

1. ls 指令 语法&#xff1a;ls [选项] [目录名或文件名] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息 常用选项&#xff1a; -a&#xff1a;列出当前目录下的所有文件&#xff0c;包含隐藏文件…

java 实验一:Java集成开发环境的搭建

一、实验目的 1、掌握Java集成开发环境的搭建方式&#xff0c;重点掌握JDK/Eclipse的安装&#xff0c;同时熟悉开发环境的使用&#xff1b; 2、重点掌握JDK/Eclipse的安装&#xff0c;同时熟悉开发环境的使用&#xff1b; 3、会使用输出语句在命令行输出信息&#xff1b; 4…