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

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.mzph.cn/news/870781.shtml

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

相关文章

「51媒体」制定《媒体邀约名单》,几点建议

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 当制定媒体邀约名单时&#xff0c;以下是一些建议&#x…

海事无人机解决方案

海事巡察 海事巡察现状 巡查效率低下&#xff0c;存在视野盲区&#xff0c;耗时长&#xff0c;人力成本高。 海事的职能 统一管理水上交通安全和防治船舶污染。 管理通航秩序、通航环境。负责水域的划定和监督管理&#xff0c;维护水 上交通秩序&#xff1b;核定船舶靠泊安…

日志自动分析-操作系统-GscanLogonTracerf8x

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

Vue 中的 scoped 和 /deep/ 深度选择器

Vue在组件里写 css 给 <style> 标签加上 scoped &#xff0c;比如&#xff1a; <style lang"less" scoped> &#xff0c;这样的 css 就是局部的&#xff0c;不会影响其他组件。 假设引入了一个子组件&#xff0c;并希望在组件中修改子组件的样式&#x…

阿里云Linux中安装MySQL,并使用navicat连接以及报错解决

首先查询是否安装MySQL // linux 使用yum安装或者rpm安装。(就是一个安装工具类似于applStore&#xff0c;brew不必在意) // 区别&#xff1a;yum会自动安装你要安装的东西的其他依赖&#xff0c;rpm不会但会提示你需要安装的东西&#xff0c;比较麻烦&#xff0c;所以采用yum安…

Camera Raw:首选项 - 常规

Camera Raw 首选项中的常规 General选项卡可以为 Camera Raw 配置一些基础和常用的设置&#xff0c;这些设置可能影响界面的外观、工作流程的便利性和使用体验。 外观 Appearance 颜色主题 Color Theme 可以选择不同的界面颜色主题。 包括&#xff1a;默认值 Default、最亮 Lig…

023-GeoGebra中级篇-几何对象之圆锥曲线

圆锥曲线是解析几何中的重要部分&#xff0c;它们包括椭圆、双曲线、抛物线和圆。通过使用预先定义的变量&#xff08;如数值、点和向量&#xff09;&#xff0c;我们可以动态地构建这些曲线的方程&#xff0c;并观察它们如何随变量的变化而变化。本文将介绍如何通过定义变量来…

如何基于大模型开发应用接口

一、前言 针对自然语言处理方向&#xff0c;以前要开发一个情感分析、命名实体识别之列的应用是非常麻烦的&#xff0c;我们需要完成收集数据、清理数据、构建模型、训练模型、调优模型等一系列操作&#xff0c;每一步都非常耗时。如今大语言模型&#xff08;LLM&#xff09;的…

Hive的分区表分桶表

1.分区表&#xff1a; 是Hive中的一种表类型&#xff0c;通过将表中的数据划分为多个子集&#xff08;分区&#xff09;&#xff0c;每个分区对应表中的某个特定的列值&#xff0c;可以提高查询性能和管理数据的效率。分区表的每个分区存储在单独的目录中&#xff0c;分区的定义…

[Flask笔记]一个完整的Flask程序

前面讲过Flask是一个轻量级Web开发框架&#xff0c;为什么说是轻量级的呢&#xff0c;因为它用短短几行代码就能运行起来&#xff0c;我们一起来看看最简单的flask框架。 安装Flask 在看Flask框架之前我们需要先安装flask模块&#xff0c;学过python的肯定都知道&#xff0c;…

SQL构造一个触发器audit_log

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 构造一个触发…

TPM开启确认

TPM 2.0在系统中开启的确认 方法一 &#xff1a;鼠标右击开始菜单-运行&#xff08;或按下键盘的WinR键&#xff09;&#xff0c;输入tpm.msc&#xff0c;然后 回车 弹出窗口 方法二&#xff1a;通过“设置>权限和安全>Windows安全中心>设备安全性” 点击Devices s…

PE73_D_E6_BLE

产品参数 产品型号 PE73_D_E6_BLE 尺寸(mm) 176.2*137.15*80mm 显示技术 电子墨水屏双面显示 显示区域(mm) 163.2(H) * 97.92(V) 分辨率(像素) 800*480 外观颜色 银色 显示颜色 黑/白/红/黄/蓝/绿 视觉角度 180 工作温度 15-35℃ 产品重量 268g 电池容…

计网ip层重要面经总结

文章目录 127.0.0.1, localhost, 0.0.0.0有什么不同?ipv6还需要NAT吗&#xff1f;DNS查询服务器的基本流程浏览器输入一个URL到显示器显示的过程PING是怎么工作的&#xff1f;ipv4和ipv6究竟有哪些区别&#xff1f;什么是跨域&#xff0c;什么情况下会发生跨域问题&#xff1f…

..质数..

先弄清楚我们在上小学时 学的概念。 1、什么是质因数&#xff1f; -质因数是指能够整除给定正整数的质数。每个正整数都可以被表示为几个质数的乘积&#xff0c;这些质数就是该数的质因数。质因数分解是将一个正整数分解成若干个质数相乘的过程。例如&#xff0c;数字 12…

C:数据结构---算法

1.1排序算法 稳定排序 不稳定排序 ①冒泡排序&#xff08;稳定&#xff09; 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换他们两个。对每一对相邻元素作同样的工作&#xff0c;从开始第一对到结尾的最后一对 ②选择排序 在未排序序列中找到最小&#xff08;大…

Nature Communications|柔性高密度、高灵敏应变传感器阵列(柔性应变传感/界面调控/电子皮肤/柔性电子)

复旦大学武利民( Limin Wu)和李卓( Zhuo Li)团队,在《Nature Communications》上发布了一篇题为“High-density, highly sensitive sensor array of spiky carbon nanospheres for strain field mapping”的论文。论文内容如下: 一、 摘要 在工程应用中,准确地映射应变…

星环科技推出语料开发工具TCS,重塑语料管理与应用新纪元

5月30-31日&#xff0c;2024向星力未来数据技术峰会期间&#xff0c;星环科技推出一款创新的语料开发工具——星环语料开发工具TCS&#xff08;Transwarp Corpus Studio&#xff09;&#xff0c;旨在通过全面的语料生命周期管理&#xff0c;极大提升语料开发效率&#xff0c;助…

批量提取PDF中表格内容

1 背景 从PDF文件获取表格中的数据&#xff0c;也是日常办公容易涉及到的一项工作。比如我们想获取某公司年报里面的表格数据&#xff0c;PDF动辄上百页的数据。 2 传统方法 一个一个从PDF表格中复制&#xff0c;然后粘贴到Excel表格中&#xff0c;效率太低了。 3 办公自动…

云计算【第一阶段(29)】远程访问及控制

一、ssh远程管理 1.1、ssh (secureshell)协议 是一种安全通道协议对通信数据进行了加密处理&#xff0c;用于远程管理功能SSH 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令&#xff0c;建立在应用层和传输层基础上的安全协议。SSH客…