一、问题描述
图书馆中的资料很多,如果能分类对其资料流通进行管理,将会带来很多方便,因此需要有一个媒体库管理系统。
图书馆共有三大类物品资料:图书、视频光盘、图画。
这三类物品共同具有的属性有:编号、标题、作者、评级(未评级,一般,成人,儿童)
等。其中图书类增加出版社、ISBN号、页数等信息;视频光盘类增加出品者的名字、出品 年份和视频时长等信息;图画类增加出品国籍、作品的长和宽(以厘米计,整数)等信息。
读者:基本信息,可借阅本数
管理员:负责借阅
二、功能要求
输出当前物品库中总物品数,以及按物品类别,统计出山前物品中各类别的物品数并显
- 添加物品:主要完成图书馆三类物品信息的添加,要求编号唯一。当添加了重复 的编号时,则提示数据添加重复并取消添加;查询物品可按照三种方式来查询物品,分别为:
-
按标题查询:输入标题,输出所查询的信息,若不存在该记录,则提示“该标题+存在!”;
按编号查询:输入编号,输出所查询的信息,若不存在该记录,则提示“该编号不存在!”;
按类别查询:输入类别,输出所查询的信息,若不存在记录,则提示“该类别没有物品!”;
- 显示物品库:输出当前物品库中所有物品信息,每条记录占据一行。
- 编辑物品:可根据查询结果对相应的记录进行修改,修改时注意编号的唯一性。
- 删除物品:主要完成图书馆物品信息的删除。如果当前物品库为空,则提示“物 品库为空!”,并返回操作;否则,输入要删除的编号,根据编号删除该物品的记录,如果该 编号不在物品库中,则提示“该编号不存在”。
- 借阅,管理员负责将物品借阅给读者,数据保存到文件中
- 统计信息
- 物品存盘:将当前程序中的物品信息存入文件中。
- 读出物品:从文件中将物品信息读入程序。
三、系统的初步设计
1.构造出基类Base,然后通过基类公有继承派生出Book、Painting、Video三个派生类
2.分析项目的作用和面向对象:我认为新媒体管理系统可以面向的对象有:普通用户和管理员用户,由此我设计出Reader类和Manager类,用于不同用户的登录和使用。
3.综合管理:我设计出Library来实现用户的各种权限和需求。
四、新媒体系统的具体实现
1.Base、Book、Painting、Video:
头文件和cpp文件:(cpp中的函数实现除了我特别说明的一般理解起来都没什么难度)
实际的类设计中,我将Base设计为抽象类,由此派生出其他三类,避免重复写共同属性代码。
Base的属性有id,name,title,author,level,type,status(这个属性是答辩的时候,老师让我现场填上去的)
Base:
#ifndef BASE_H
#define BASE_H
#include <string>
class Base {
protected:
int id;
std::string name;
std::string title;
std::string author;
std::string level;
std::string type;
bool status;
public:
Base(int id, const std::string& title, const std::string& author, const std::string& level);
virtual ~Base();
int getid() const;
std::string getname();
void setid(int a);
std::string gettitle() const;
std::string getauthor() const;
std::string gettype() const;
std::string getlevel() const;
bool getstatus();
void changestatus();
void changename(std::string a);
virtual void display() const = 0;
virtual void change(int new_id) = 0;
};
#endif
#include "Base.h"
Base::Base(int id, const std::string& title, const std::string& author, const std::string& level)
: id(id), title(title), author(author), level(level){}
Base::~Base() {}
int Base::getid() const {
return id;
}
void Base::setid(int a) {
id = a;
}
bool Base::getstatus() {
return status;
}
void Base::changestatus() {
status = false;
}
std::string Base::gettitle() const {
return title;
}
std::string Base::getauthor() const {
return author;
}
std::string Base::gettype() const {
return type;
}
std::string Base::getname() {
return name;
}
void Base::changename(std::string a) {
name = a;
}
std::string Base::getlevel() const {
return level;
}
Painting中除了共同属性还有nationality、width、height
Painting:
#ifndef PAINTING_H
#define PAINTING_H
#include "Base.h"
#include <string>
class Painting : public Base {
private:
std::string nationality;
int width;
int height;
public:
Painting();
explicit Painting(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& nationality,
int width, int height);
std::string getnationality() const;
int getwidth() const;
int getheight() const;
void display() const override;
void change(int new_id) override;
};
#endif
#include "Painting.h"
#include <iostream>
Painting::Painting() : Base(0, "", "", ""), nationality("unknown"), width(0), height(0) {
}
Painting::Painting(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& nationality,
int width, int height)
: Base(id, title, author, level), nationality(nationality), width(width), height(height) {
type = "painting"; this->status = true; this->name = "root";
}
std::string Painting::getnationality() const {
return nationality;
}
int Painting::getwidth() const {
return width;
}
int Painting::getheight() const {
return height;
}
void Painting::display() const {
std::cout << "Type: " << type << ", ID: " << id << ", Title: " << title << ", Author: " << author
<< ", Level: " << level << ", Nationality: " << nationality
<< ", Width: " << width << "cm, Height: " << height << "cm"<<" "<<name<< std::endl;
}
void Painting::change(int new_id) {
std::cout << "请输入重新修改后的信息:" << std::endl;
std::string new_title, new_author, new_level, new_nationality;
int new_width, new_height;
std::cin >>new_title >> new_author >> new_level >> new_nationality >> new_width >> new_height;
id = new_id;
title = new_title;
author = new_author;
level = new_level;
nationality = new_nationality;
width = new_width;
height = new_height;
}
Video中还包括 producer、producedYear、time
Video:
#ifndef VIDEO_H
#define VIDEO_H
#include "Base.h"
#include <string>
class Video : public Base {
private:
std::string producer;
int producedYear;
int time;
public:
Video();
explicit Video(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& producer,
int producedYear, int time);
std::string getproducer() const;
int getproducedYear() const;
int gettime() const;
void display() const override;
void change(int new_id) override;
};
#endif
#include "Video.h"
#include <iostream>
Video::Video() : Base(0, "", "", ""), producer("unknown"), producedYear(0), time(0) {
this->type = "video"; // 设置默认类型为"video"
}
Video::Video(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& producer,
int producedYear, int time)
: Base(id, title, author, level), producer(producer),
producedYear(producedYear), time(time) {
this->type = "video"; this->status = true; this->name = "root";
}
std::string Video::getproducer() const {
return producer;
}
int Video::getproducedYear() const {
return producedYear;
}
int Video::gettime() const {
return time;
}
void Video::display() const {
std::cout << "Type: " << type << ", ID: " << id << ", Title: " << title << ", Author: " << author
<< ", Level: " << level << ", Producer: " << producer
<< ", Produced Year: " << producedYear << ", Time: " << time<<" "<<name<< std::endl;
}
void Video::change(int new_id) {
std::cout << "请输入重新修改后的信息:" << std::endl;
std::string new_title, new_author, new_level, new_producer;
int new_producedYear, new_time;
std::cin>> new_title >> new_author >> new_level >> new_producer >>
new_producedYear >> new_time;
id = new_id;
title = new_title;
author = new_author;
level = new_level;
producer = new_producer;
producedYear = new_producedYear;
time = new_time;
}
Book类中还包括publisher、ISBN、page
Book:
#ifndef BOOK_H
#define BOOK_H
#include "Base.h"
#include <string>
class Book : public Base {
private:
std::string publisher;
std::string ISBN;
int page;
public:
Book();
explicit Book(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& publisher,
const std::string& ISBN, int page);
std::string getpublisher() const;
std::string getISBN() const;
int getpage() const;
void display() const override;
void change(int new_id) override;
};
#endif
#include<iostream>
#include"Base.h"
#include"Book.h"
#include <iostream>
Book::Book() : Base(0, "", "", "") {}
Book::Book(int id, const std::string& title, const std::string& author,
const std::string& level, const std::string& publisher,
const std::string& ISBN, int page)
: Base(id, title, author, level), publisher(publisher), ISBN(ISBN), page(page) {
this->type = "book"; this->status = true; this->name = "root";
}
std::string Book::getpublisher() const {
return publisher;
}
std::string Book::getISBN() const {
return ISBN;
}
int Book::getpage() const {
return page;
}
void Book::display() const {
std::cout << "Type: " << this->type << ", ID: " << this->id
<< ", Title: " << this->title << ", Author: " << this->author
<< ", Level: " << this->level << ", Publisher: " << publisher
<< ", ISBN: " << ISBN << ", Page: " << page<<" "<<name << std::endl;
}
void Book::change(int new_id) {
std::cout << "请输入重新修改后的信息:" << std::endl;
std::string new_title, new_author, new_level, new_publisher,new_ISBN;
int new_page;
std::cin>> new_title >> new_author >> new_level >> new_publisher >>
new_ISBN >> new_page;
id = new_id;
title = new_title;
author = new_author;
level = new_level;
publisher = new_publisher;
ISBN = new_ISBN;
page = new_page;
}
2.Reader和Manager
头文件和cpp文件实现:
Reader和Manager在登陆时都需要填写密码,(密码和账户都被我保存在txt文件中,需要一一核对,正确后才会进入下一步),由于我本人是信息安全专业的学生,于是我采用了简单异或的加密方法,将txt文本中保存的密码都是加密后的密文而非明文,主要是防止txt文本泄露导致用户账号不安全(我写的加密方法很容易被破解,但是我加这一步是为了突出的我专业特色)
其次,Reader和Manager在登陆后的权限不同(很容易理解,管理员权限大于用户权限,我设计的管理员只有一个账号,不能注册)
Reader类中包括name、passwd、number(可借阅的数量,这也是答辩的时候现场加上去的)
Reader:
#ifndef READER_H
#define READER_H
#include <string>
using namespace std;
class Reader {
private:
string name;
string passwd;
int number = 5;
public:
Reader();
Reader(string a, string b);
bool check(string inputname, string inputpasswd);
int getnumber();
string getname();
string getpasswd();
void lendnumber();
};
#endif
#include "Reader.h"
#include "exchange.h"
Reader::Reader() {}
Reader::Reader(string a, string b) {
name = a;
passwd = b;//保存的密码为密文,登陆时需要解密
}
bool Reader::check(string inputname, string inputpasswd) {
return (inputname == name && inputpasswd == passwd);
}
int Reader::getnumber() {
return number;
}
void Reader::lendnumber() {
number = number - 1;
}
string Reader::getname() {
return name;
}
string Reader::getpasswd() {
return passwd;//获取的密码为密文
}
Manager类中包括name和passwd
Manager:
#ifndef MANAGER_H
#define MANAGER_H
#include <string>
class Manager {
private:
std::string name;
std::string passwd;
public:
Manager();
Manager(const std::string& a, const std::string& b);
bool check(const std::string& inputname, const std::string& inputpasswd) const;
std::string getname() const;
std::string getpasswd() const;
};
#endif
3.异或加密
头文件和cpp文件:
此处我才用异或加密的方式,我用“A”作为密钥,和我的明文密码逐比特异或,然后保存到我的txt文件中。当然加密方法还有很多种,但我作为初学者采用了基础的一种。
#ifndef EXCHANGE_H
#define EXCHANGE_H
#include <string>
std::string exchange(std::string plaintext);
#endif // EXCHANGE_H
#include "exchange.h"
std::string exchange(std::string plaintext) {
std::string key = "A";
std::string ciphertext = "";
int keyLength = key.length();
int index = 0;
// 遍历输入的每个字符
for (char& c : plaintext) {
c ^= key[index % keyLength]; // 对字符和密钥进行异或操作
ciphertext += c; // 将加密后的字符添加到加密文本中
index++;
}
return ciphertext; // 返回加密后的字符串
}
4.Library(本文中最重要的类)
头文件和cpp文件的实现:
本处我为了方便书写代码,我使用了STL容器中的vector向量,我定义了五个向量容器。主要是因为向量容器添加、删除、查找、显示信息都比较容易,部分功能有直接现成的函数,省去了编写的麻烦。
Library:
#include<vector>
#include<iostream>
#include<fstream>
#include<string>
#include <sstream>
#include "Manager.h"
#include "Reader.h"
#include"Base.h"
#include"Painting.h"
#include"Book.h"
#include"Video.h"
using namespace std;
class Library {
private:
vector<Book> books;
vector<Painting> paintings;
vector<Video> videos;
vector<Reader> readers;
vector<Manager> managers;
public:
void havestatus(int id);
bool checkstatus(int id);
void loadlend();
void mlend();
void readmanagers();//读取managers.txt的内容,并且实例化Manager对象
bool mlogin();//manager身份登录
void savereader();
//保存reader身份的信息到readreaders.txt
void readreaders();//读取readreader.txt的信息,然后实例化reader对象
bool rlogin();//reader身份登录
bool registerreader();//注册reader身份用户,检测是否重名addthing
bool searchid(int id);
void addthing();//添加功能,同时检测是否有id重名
bool searchbytitle(string title);
bool searchbyid(int id);
void searchthing();
bool searchbytype(string type);
void displayall();//分类别展示所有物品信息
void read();//非类别读取物品信息,并且实例化(管理员权限)
void loading();
void edit();//编辑物品信息
void deletethings();//删除物品信息
void show();//展示分类的数量和总数量
void rlend();//借出物品功能的实现
void save();
};
在cpp文件的实现中,我感觉部分代码的复用率比较低,但是我看它运行没报错,我就没怎么修改简化了。然后需要注意的一个重点是,我读取和保存文件都是在F盘,而且有特定的名称和路径,如需借鉴,记得修改。
#include<iostream>
#include<vector>
#include<fstream>
#include<string>
#include <sstream>
#include "Manager.h"
#include "Reader.h"
#include"Base.h"
#include"Painting.h"
#include"Book.h"
#include"Video.h"
#include"Library.h"
#include "exchange.h"
using namespace std;
bool Library::checkstatus(int id) {
for (auto& book : books) {
if (book.getid() == id) return book.getstatus();
}
for (auto& painting : paintings) {
if (painting.getid() == id) return painting.getstatus();
}
for (auto& video : videos) {
if (video.getid() == id) return video.getstatus();
}
}
void Library::havestatus(int id) {
for (auto& book : books) {
if (book.getid() == id) book.changestatus();
}
for (auto& painting : paintings) {
if (painting.getid() == id) painting.changestatus();
}
for (auto& video : videos) {
if (video.getid() == id) video.changestatus();
}
}
void Library:: mlend(){
int id;
bool flag = false;
bool flag1 = false;
cout << "请输入借出物品的id" << endl;
cin >> id;
flag = searchid(id);
flag1 = checkstatus(id);
if (!flag) { cout << "输入编号不存在!" << endl; return; }
if (!flag1) { cout << "该物品已经借出!" << endl; return; }
if (flag&&flag1) {
havestatus(id);
ofstream outfile("F:\\lend.txt", ios::app);
if (!outfile)
{ cerr << "open lend.txt error!" << endl;exit(0);}
bool f = false; string name; cout << "请输入用户名称" << endl; cin >> name;
for (int i = 0; i < readers.size(); i++) {
if (name == readers[i].getname()) {
if (readers[i].getnumber() > 0) {
flag = true;
readers[i].lendnumber();
cout << "成功借出!" << endl;}}}
if (!flag) { cout << "未找到用户,借阅失败" << endl; }
else { outfile << name << " " << id << endl; }
outfile.close();
}}
void Library:: readmanagers() {
ifstream infile("F:\\managers.txt", ios::in);
if (!infile) {
cerr << "Error opening managers.txt" << endl;
exit(0);
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
string name, passwd;//输入明文
passwd = exchange(passwd);//加密成密文
if (!(iss >> name >> passwd)) {//用密文进行比对
cerr << "Error reading data from readmanagers.txt" << endl;
continue;
}
Manager a(name, passwd);//实例化时写入的是密文
managers.push_back(a);
}
}//读取managers.txt的内容,并且实例化Manager对象
bool Library:: mlogin() {
string name, passwd;//输入明文
passwd = exchange(passwd);//加密成密文
cout << "请输入管理员名称和密码" << endl;
cin >> name >> passwd;
for (int i = 0; i < managers.size(); i++) {
if (managers[i].check(name, passwd)) {//比对密文
cout << "登录成功!" << " " << "欢迎管理员" << name << "!" << endl;
return true;
}
}
cout << "登录失败" << endl;
return false;
}//manager身份登录
void Library::readreaders() {
ifstream infile("F:\\readreaders.txt", ios::in);
if (!infile) {
cerr << "Error opening readreaders.txt" << endl;
exit(1);
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
string name, passwd;
if (!(iss >> name >> passwd)) {
cerr << "Error reading data from readreaders.txt" << endl;
continue;
}
Reader a(name,passwd);
readers.push_back(a);
}
infile.close();
}//读取readreader.txt的信息,然后实例化reader对象
bool Library::rlogin() {
string name, passwd;
cout << "请输入用户名称和密码" << endl;
cin >> name >> passwd;
passwd = exchange(passwd);
for (int i = 0; i < readers.size(); i++) {
if (readers[i].check(name, passwd)) {
cout << "登录成功!" << " " << "欢迎用户" << name << "!" << endl;
return true;
}
}
cout << "登录失败" << endl;
return false;
}//reader身份登录
void Library::searchthing() {
int a;
cout << "请输入要查询的方式:1.标题,2.编号,3.类别(请输入输入数字)" << endl;
cin >> a;
if (a == 1) {
bool flag;
string title;
cout << "请输入标题:" << endl;
cin >> title;
flag=searchbytitle(title);
if (!flag) cout << "该标题不存在!" << endl;
}
else if (a == 2) {
bool flag;
int id;
cout << "请输入编号" << endl;
cin >> id;
flag=searchbyid(id);
if (!flag) cout << "该编号不存在!" << endl;
}
else if (a == 3) {
bool flag;
string type;
cout << "请输入类别" << endl;
cin >> type;
flag=searchbytype(type);
if (!flag) cout << "该类别没有物品!" << endl;
}
else { cout << "无效选择,请重试" << endl; return; }
}
bool Library::registerreader() {
string name, passwd;
cout << "请输入用户名称和密码" << endl;
cin >> name >> passwd;
passwd = exchange(passwd);
// 检查是否存在重复的用户名
for (auto& reader : readers) {
if (reader.getname() == name) {
cout << "用户名已经存在,请重新选择" << endl;
return false;
}
}
// 如果没有找到重复用户名,则注册新用户
Reader new_reader(name,passwd);
cout << "注册成功" << endl;
readers.push_back(new_reader);
ofstream outfile("F:\\readreaders.txt", ios::trunc);
if (!outfile) { cerr << "open readreaders.txt error!" << endl; exit(0); }
for (int i = 0; i < readers.size(); i++) {
outfile << readers[i].getname() << " " << readers[i].getpasswd() << endl;}
outfile.close();
return true;
}//注册reader身份用户,检测是否重名addthing
bool Library::searchid(int id) {//查看是否有重复的id
for (auto& book : books) {
if (book.getid() == id) return true;
}
for (auto& painting : paintings) {
if (painting.getid() == id) return true;
}
for (auto& video : videos) {
if (video.getid() == id) return true;
}
return false;
}
void Library::addthing() {
int num;
cout << "请输入添加物品的数量: ";
cin >> num;
for (int i = 0; i < num; i++) {
string type;
cout << "请输入物品的类型(book, video, painting): ";
cin >> type;
cout << "进行第" << i + 1 << "件物品的添加" << endl;
if (type == "book") {
int id;
string title, author, level, publisher, ISBN ,name;
int page;
cout << "请输入id, title, author, level, publisher, ISBN, page, name: ";
cin >> id >> title >> author >> level >> publisher >> ISBN >> page>>name;
if (!searchbyid(id)) {
Book newBook(id, title, author, level, publisher, ISBN, page);
newBook.changename(name);
books.push_back(newBook);
cout << "添加成功!" << endl;
}
else { cout << "id重复,添加失败!" << endl; continue; }
}
if (type == "video") {
int id;
string title, author, level, producer, ISBN;
int page, producedYear, time;
cout << "请输入id, title, author, level,producer, producedYear, time : " << endl;
cin >> id >> title >> author >> level >> producer >> producedYear >> time;
if (!searchbyid(id)) {
Video newvideo(id, title, author, level, producer, producedYear, time);
videos.push_back(newvideo);
cout << "添加成功!" << endl;
}
else { cout << "id重复,添加失败!"; continue; }
}
if (type == "painting") {
int id;
string title, author, level, nationality;
int width, height;
cout << "Enter id, title, author, level, nationality, width, height : " << endl;
cin >> id >> title >> author >> level >> nationality >> width >> height;
if (!searchbyid(id)) {
Painting newpainting(id, title, author, level, nationality, width, height);
paintings.push_back(newpainting);
}
else { cout << "id重复,添加失败!" << endl; continue; }
}
}
}//添加功能,同时检测是否有id重名
bool Library::searchbytitle(string title) {
for (auto& book : books) {
if (book.gettitle() == title) {
book.display();
return true;
}
}
for (auto& painting : paintings) {
if (painting.gettitle() == title) {
painting.display();
return true;
}
}
for (auto& video : videos) {
if (video.gettitle() == title) {
video.display();
return true;
}
}
return false;
}
bool Library::searchbyid(int id) {
bool flag = false;
for (auto& book : books) {
if (book.getid() == id) {
book.display();
flag=true;
}
}
for (auto& painting : paintings) {
if (painting.getid() == id) {
painting.display();
flag=true;
}
}
for (auto& video : videos) {
if (video.getid() == id) {
video.display();
flag=true;
}
}
return flag;
}
bool Library::searchbytype(string type) {
bool flag=false;
if (type == "book") {
if (books.size() != 0) {
for (int i = 0; i < books.size(); i++) {
books[i].display();
flag = true;
}
}
}
if (type == "painting") {
if (paintings.size() != 0) {
for (int i = 0; i < paintings.size(); i++) {
paintings[i].display();
flag = true;
}
}
}
if (type == "video") {
if (videos.size() != 0) {
for (int i = 0; i < videos.size(); i++) {
videos[i].display();
flag = true;
}
}
}
return flag;
}
void Library::displayall() {
for (int i = 0; i < books.size(); i++) books[i].display();
for (int i = 0; i < videos.size(); i++) videos[i].display();
for (int i = 0; i < paintings.size(); i++) paintings[i].display();
}//分类别展示所有物品信息
void Library::read() {
string type;
cout << "请输入要读取物品的类型:(book,video,painting)" << endl;
cin >> type;
if (type == "book") {
ifstream infile("F:\\readbooks.txt", ios::in);
if (!infile) {
cerr << "无法打开readbooks.txt" << endl;
exit(0);
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
int id;
string title, author, level, publisher,ISBN,name;
int page;
iss >> id >> title >> author >> level >> publisher >> ISBN >> page>>name;
if (!searchbyid(id)) {
Book a(id, title, author, level, publisher, ISBN, page);
books.push_back(a);
}
else { cout << "id重复,添加失败" << endl; continue; }
}
}
//id,title,author,level,producer,producedYear,time
else if (type == "video") {
ifstream infile("F:\\readvideos.txt", ios::in);
if (!infile) {
cerr << "无法打开readvideos.txt" << endl;
exit(0);
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
int id;
string title, author, level, producer,name;
int producedYear, time;
iss >> id >> title >> author >> level >> producer >> producedYear >> time>>name;
if (!searchbyid(id)) {
Video a(id, title, author, level, producer, producedYear, time);
videos.push_back(a);
}
else { cout << "id重复,添加失败" << endl; continue; }
}
}
else if (type == "painting") {
ifstream infile("F:\\readpaintings.txt", ios::in);
if (!infile) {
cerr << "无法打开readpaintings.txt" << endl;
exit(0);
}
string line;
//id,title,author,level,nationality,width,height
while (getline(infile, line)) {
istringstream iss(line);
int id;
string title, author, level, nationality,name;
int width, height;
iss >> id >> title >> author >> level >> nationality >> width >> height>>name;
if (!searchbyid(id)) {
Painting a(id, title, author, level, nationality, width, height);
paintings.push_back(a);
}
else { cout << "id重复,添加失败!" << endl; continue; }
}
}
else { cout << "无效选择,请重新操作" << endl; return; }
}//非类别读取物品信息,并且实例化(管理员权限)
void Library::loading() {
ifstream infile("F:\\books.txt", ios::in);
if (!infile) {
cerr << "无法打开books.txt" << endl;
exit(0);
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
int id;
string title, author, level, publisher, ISBN,name;
int page;
iss >> id >> title >> author >> level >> publisher >> ISBN >> page>>name;
if (!searchbyid(id)) {
Book a(id, title, author, level, publisher, ISBN, page);
books.push_back(a);
}
else {
cerr << "book id重复,添加失败" << endl;
continue;
}
}
infile.close();
ifstream infile1("F:\\videos.txt", ios::in);
if (!infile1) {
cerr << "无法打开videos.txt" << endl;
exit(0);
}
string line1;
while (getline(infile1, line1)) {
istringstream iss(line1);
int id;
string title, author, level, producer,name;
int producedYear, time;
iss >> id >> title >> author >> level >> producer >> producedYear >> time>>name;
if (!searchbyid(id)) {
Video a(id, title, author, level, producer, producedYear, time);
videos.push_back(a);
}
else {
cerr << "video id重复,添加失败" << endl;
continue;
}
}
infile1.close();
ifstream infile2("F:\\paintings.txt", ios::in);
if (!infile2) {
cerr << "无法打开paintings.txt" << endl;
exit(0);
}
string line2;
while (getline(infile2, line2)) {
istringstream iss(line2);
int id;
string title, author, level, nationality,name;
int width, height;
iss >> id >> title >> author >> level >> nationality >> width >> height>>name;
if (!searchbyid(id)) {
Painting a(id, title, author, level, nationality, width, height);
paintings.push_back(a);
}
else {
cerr << "painting id重复,添加失败!" << endl;
continue;
}
}
infile2.close();
}
void Library::edit() {
int id;
cout << "请输入要更改物品的id" << endl;
cin >> id;
for (auto& book : books) {
if (book.getid() == id) {
int new_id;
cout << "请输入新的编号:" << endl;
cin >> new_id;
if (new_id = id) { book.change(new_id); cout << "编辑成功" << endl; }
else {
bool flag = searchbyid(new_id);
if (flag) cout << "编号已经存在!" << endl;
else { book.change(new_id); cout << "编辑成功" << endl; }
}
}
}
for (auto& painting : paintings) {
if (painting.getid() == id) {
int new_id;
cout << "请输入新的编号:" << endl;
cin >> new_id;
if (new_id = id) { painting.change(new_id); cout << "编辑成功" << endl; }
else {
bool flag = searchbyid(new_id);
if (flag) cout << "编号已经存在!" << endl;
else { painting.change(new_id); cout << "编辑成功" << endl; }
}
}
}
for (auto& video : videos) {
if (video.getid() == id) {
int new_id;
cout << "请输入新的编号:" << endl;
cin >> new_id;
if (new_id = id) { video.change(new_id); cout << "编辑成功" << endl; }
else {
bool flag = searchbyid(new_id);
if (flag) cout << "编号已经存在!" << endl;
else { video.change(new_id); cout << "编辑成功" << endl; }
}
}
}
}//编辑物品信息
void Library::deletethings() {
int id;
cout << "请输入物品的id" << endl;
cin >> id;
for (auto it = books.begin(); it != books.end();) {
if (it->getid() == id) {
it = books.erase(it);
cout << "删除成功" << endl;
}
else {
++it;
}
}
for (auto it = videos.begin(); it != videos.end();) {
if (it->getid() == id) {
it = videos.erase(it);
cout << "删除成功" << endl;
}
else {
++it;
}
}
for (auto it = paintings.begin(); it != paintings.end();) {
if (it->getid() == id) {
it = paintings.erase(it);
cout << "删除成功" << endl;
}
else {
++it;}}}
void Library::show() {
int num, num1, num2, num3;
num1 = books.size(); num2 = videos.size(); num3 = paintings.size();
num = num1 + num2 + num3;
cout << "图书馆中一共有" << num << "件物品" << endl;
cout << "book的数量为" << num1 << " " << "video的数量为" << num2 << " " << "painting的数量为" << " " << num3 << endl;
}//展示分类的数量和总数量
void Library::save() {
ofstream outfile("F:\\books.txt", ios::trunc);
//id,title,author,level,publisher,ISBN,page
for(int i=0;i<books.size();i++){
outfile << books[i].getid() << " " << books[i].gettitle() << " " << books[i].getauthor() << " " << books[i].getlevel() << " " << books[i].getpublisher()
<< " " << books[i].getISBN() << " " << books[i].getpage() << endl;}
outfile.close();
ofstream outfile1("F:\\videos.txt", ios::trunc);
for (int i = 0; i < videos.size(); i++) {
//id,title,author,level,producer,producedYear,time
outfile1 << videos[i].getid() << " " << videos[i].gettitle() << " " << videos[i].getauthor() << " " << videos[i].getlevel() << " " << books[i].getpublisher()
<< " "<< " " << videos[i].getproducedYear() << " " << videos[i].gettime() << endl;}
outfile1.close();
ofstream outfile2("F:\\paintings.txt", ios::trunc);
for (int i = 0; i < paintings.size(); i++) {
//id,title,author,level,nationality,width,height
outfile2 << paintings[i].getid() << " " << paintings[i].gettitle() << " " << paintings[i].getauthor() << " " << paintings[i].getlevel() << " "
<< " " << paintings[i].getnationality() << " " << paintings[i].getwidth() << " " << paintings[i].getheight() << endl;
}outfile2.close();
}//将实例化的物品保存到各个文件当中
main.cpp
#include<iostream>
#include<vector>
#include<iostream>
#include<fstream>
#include<string>
#include <sstream>
#include "Manager.h"
#include "Reader.h"
#include"Base.h"
#include"Painting.h"
#include"Book.h"
#include"Video.h"
#include"Library.h"
#include"exchange.h"
using namespace std;
int main() {
cout <<" --------------欢迎使用!--------------" << endl;
int opt;
bool flag = false;
Library library; library.loading();
int selection;
cout << " -----------请输入您的选项-------------" << endl;
cout << " ------------1.用户身份----------------" << endl;
cout << " ------------2.管理员身份--------------" << endl;
cin >> opt;
if (opt==1) {
while (true) {
cout << " ------------1.用户登录----------------" << endl;
cout << " ------------2.用户注册----------------" << endl;
cout << " ------------3.退出程序----------------" << endl;
cout << " ----------请输入您的选项--------------" << endl;
cin >> selection;
if (selection == 1) {
library.readreaders();//读取信息并且实例化reader
flag = library.rlogin();//以reader身份登录
break;
}
else if (selection == 2) {
library.readreaders();//读取信息并且实例化reader
flag = library.registerreader();//注册reader用户
break;
}
else if (selection == 3) {
return 0;
}
else{
cout << " 无效选项,请重试!" << endl;
}
}
int option;
while (flag) {
cout << " -----------1.显示物品库-----------------" << endl
<< " -----------2.统计信息显示---------------" << endl
<< " -----------3.查询物品-------------------" << endl
<< " -----------4.添加物品-------------------" << endl
<< " -----------5.退出程序-------------------" << endl;
cout << " ---------请输入您的选项-----------------" << endl;
cin >> option;
switch (option) {
case 1:
library.displayall();
break;
case 2:
library.show();
break;
case 3:
library.searchthing();
break;
case 4:
library.addthing();//加入上传用户的名字
break;
case 5:
return 0;
break;
default:
cout << " 无效选项,请重新选择" << endl;
break;
}
}
}
else if (opt == 2) {
cout << " -----------请输入您的选项-------------" << endl;
cout << " ------------1.管理员登录--------------" << endl
<< " ------------2.退出程序----------------" << endl;
cin >> selection;
switch (selection) {
case 1:
library.readmanagers();//读取managers.txt的内容,并且实例化Manager对象
flag = library.mlogin();//manager身份登录
break;
case 2:
return 0;
break;
default:
cout << "无效选项,请重新选择" << endl;
break;
}
int option;
while (flag) {
cout << " ------------1.添加物品----------------" << endl
<< " ------------2.显示物品库--------------" << endl
<< " ------------3.编辑物品----------------" << endl
<< " ------------4.删除物品----------------" << endl
<< " ------------5.借阅物品----------------" << endl
<< " ------------6.统计信息显示------------" << endl
<< " ------------7.物品存盘----------------" << endl
<< " ------------8.读出物品----------------" << endl
<< " ------------9.查询物品----------------" << endl
<< " ------------10.退出程序---------------" << endl;
cout << " ----------请输入您的选项--------------" << endl;
cin >> option;
switch (option) {
case 1:
library.addthing();
break;
case 2:
library.displayall();
break;
case 3:
library.edit();
break;
case 4:
library.deletethings();
break;
case 5:
library.mlend();
break;
case 6:
library.show();
break;
case 7:
library.save();
break;
case 8:
library.read();
break;
case 9:
library.searchthing();
break;
case 10:
return 0;
break;
default:
cout << " 无效选项,请重新选择" << endl;
break;
}
}
}
else { cout << "无效选择,请退出重试!" << endl; }
return 0;
}
五、创新点和不足
1.创新点:本次课设采用分文件编写,更加清晰明确,方便维护;将系统分为普通用户和管理员用户,明确权限;采用STL容器;采用异或加密,防止密码明文泄露,保护用户账号安全。
2.不足:在界面设计时,退出有些瑕疵,写的是请重试,但是直接结束了程序。修改的话,需要调整一下main.cpp中的流程。