第一周实验:二次开发

  1. 来源
    来自大一舍友C++大作业。该项目模拟了一个图书管理系统,涉及到用户对于书籍的查看、借阅与归还,管理员对于书籍相关信息的增删改查。
  2. 运行环境+运行结果的截图
    运行环境:Windows 11 + Visual Studio 2022











main.cpp
#include<Windows.h>
#include "Account.h"
#include "libaray.h"
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
void cls()
{
	system("cls");
}
int main()
{
	AccontList list;
	AllLibaray lib;
	auto reject = [&list, &lib]()
		{
			string acc, pass, name;
			system("cls");
			cout << "\t注册" << endl;
			cout << "账户:";
			cin >> acc;
			cout << "密码:";
			cin >> pass;
			cout << "用户名:";
			cin >> name;
			while (!list.reje(acc, pass, name))
			{
				system("cls");
				cout << "\t注册账号,重复请重试\n账户:";
				cin >> acc;
				cout << "密码:";
				cin >> pass;
				cout << "用户名:";
				cin >> name;
			}
			cls();
			cout << "  注册成功" << endl;
			system("pause");
		};
	auto log = [&list, &lib]()
		{
			cls();
			int i; string acc, pass;
			cout << "请选择以何种身份登录" << endl;
			cout << "1.管理员   2.用户   " << endl;
			cin >> i;
			cls();
			cout << "账户:";
			cin >> acc;
			cout << "密码:";
			cin >> pass;
			if (i == 1)
			{
				if (!list.loginManager(acc, pass))
				{
					do
					{
						cls();
						cout << "账号密码错误,请重新输入\n";
						cout << "账户:";
						cin >> acc;
						cout << "密码:";
						cin >> pass;
					} while (!list.loginManager(acc, pass));

				}
				cls();
				cout << "登陆成功,欢迎管理员使用" << endl;
				return -1;
			}
			else
			{
				int i;
				if ((i = list.loginUser(acc, pass)) != -1)
				{
					cls();
					cout << "登陆成功,欢迎用户" << list[i].getName()
						<< "使用" << endl;
					return i;
				}
				else
				{
					do
					{
						cls();
						cout << "账号密码错误,请重新输入\n";
						cout << "账户:";
						cin >> acc;
						cout << "密码:";
						cin >> pass;
					} while ((i = list.loginUser(acc, pass)) == -1);
					cls();
					cout << "登陆成功,欢迎用户" << list[i].getName()
						<< endl;
					return i;
				}
			}
		};
	auto manage = [&list, &lib]()
		{
			int j = 0;
			lib.choice();
			system("pause");
			while (true)
			{
				cls();
				cout << "请根据提示输入数字以进行操作" << endl;
				cout << "1.重新选择书籍库	2.修改现有书籍数量        3.增添新的书籍" << endl;
				cout << "4.删除书籍	        5.显示本书籍库中所有书籍  6.查找书籍" << endl;
				cout << "7.退出登录" << endl;
				cin >> j;
				cls();
				switch (j)
				{
				case 1:lib.choice();
					break;
				case 2:lib.add();
					break;
				case 3:lib.addnew();
					break;
				case 4:lib.erase();
					break;
				case 5:lib.showAll();
					break;
				case 6:cout << "请选择查找书籍的方式:\n1.根据书籍id精确搜索		2.模糊搜索" << endl;
					cin >> j;
					if (j == 2)lib.search();
					else lib.searchBook();
					break;
				case 7:goto endManage;
					break;
				}
				system("pause");
			}
		endManage:
			cls();
		};
	auto use = [&list, &lib](User& user)
		{
			if (user.getFine() != 0)
			{
				cout << "您有" << user.getFine() << "本书籍逾期,请尽快还书" << endl;
				system("pause");
				cls();
			}
			int j = 0;
			lib.choice();
			system("pause");
			while (true)
			{
				cls();
				cout << "请根据提示输入数字以进行操作" << endl;
				cout << "1.重新选择书籍库          2.借阅书籍     3.借书管理" << endl;
				cout << "4.显示本书籍库中所有书籍  5.查找书籍     6.退出登录" << endl;
				cin >> j;
				cls();
				switch (j)
				{
				case 1:lib.choice();
					break;
				case 2:user.push_back(lib.lend());
					break;
				case 3:cout << "请根据提示输入数字以进行操作\n1.查看借阅信息	 2.还书" << endl;
					cin >> j;
					cls();
					if (j == 1)
					{
						user.showBorrow();
					}
					else if (j == 2)
					{
						bool p = true;
						Borrow& borrow = user.returnBook(p);
						if (p)
						{
							lib.returnBook(borrow);
							cout << "还书成功" << endl;
						}
					}
					break;
				case 4:lib.showAll();
					break;
				case 5:cout << "请选择查找书籍的方式:\n1.根据书籍id精确搜索		2.模糊搜索" << endl;
					cin >> j;
					if (j == 2)lib.search();
					else lib.searchBook();
					break;
					break;
				case 6:goto endUse;
					break;
				}
				system("pause");
			}

		endUse:
			cls();
		};

	int i = 0; bool islog = false;
	while (true)
	{
		cls();
		cout << "   欢迎使用图书馆管理系统   " << endl;
		cout << "请根据提示输入数字以进行操作" << endl;
		cout << "   1.登录  2.注册  3.退出   " << endl;
		cin >> i;
		switch (i)
		{
		case 3:goto end;
			break;
		case 2:reject();
			break;
		case 1:i = log(); islog = true;
			break;
		}
		if (islog)
		{
			if (i == -1)
			{
				manage();
				islog = false;
			}
			else
			{
				use(list[i]);
				islog = false;
			}
		}
	}
end:
	cls();
	cout << "感谢您的使用!再见" << endl;
}
Borrow.h
#pragma once
#include<string>
#include<chrono>
#include <fstream>
#include<iostream>
#include<iomanip>
class Borrow
{
	std::string ID;
	std::string name;
	bool isreturn = false;
	std::chrono::system_clock::time_point begin, end;
	std::chrono::system_clock::time_point should;
public:
	Borrow() = default;
	Borrow(std::string ID, std::string name, int day = 60);
	void returnbook();
	void show();
	bool isReturn();
	bool overtime();
	std::string getID();
	void is(bool is);
	void change(std::chrono::system_clock::time_point a, std::chrono::system_clock::time_point b, std::chrono::system_clock::time_point c);
	std::tuple<std::chrono::system_clock::time_point, std::chrono::system_clock::time_point, std::chrono::system_clock::time_point>
		write();
	bool noemp() const;
	friend std::ofstream& operator<<(std::ofstream& out, const Borrow& aim);
};


Borrow.cpp
#include "Borrow.h"
Borrow::Borrow(std::string ID, std::string name, int day)
	:ID(ID), name(name), begin(std::chrono::system_clock::now() + std::chrono::hours(8)-std::chrono::days(60)), should(begin + std::chrono::days(day))
{
	
}
void Borrow::returnbook()
{
	end = std::chrono::system_clock::now() + std::chrono::hours(8);
	isreturn = true;
}
void Borrow::show()
{
	std::cout << "书籍编号:" << std::left << std::setw(10) << ID << "  书名:"
		<< std::left << std::setw(10) << name << "借阅时间:" << begin << std::endl;
	if (isreturn)
	{
		std::cout << "书籍状态:已归还" << "\t                    还书时间:" << end << std::endl;
	}
	else
	{
		std::cout << "书籍状态:未归还" << "\t                    应还时间:" << should << std::endl;
	}

}
bool Borrow::isReturn()
{
	return isreturn;
}
bool Borrow::overtime()
{
	return std::chrono::system_clock::now() > should;
}
std::string Borrow::getID()
{
	return ID;
}
void Borrow::is(bool is)
{
	isreturn = is;
}
void Borrow::change(std::chrono::system_clock::time_point a, std::chrono::system_clock::time_point b, std::chrono::system_clock::time_point c)
{
	begin = a; end = b; should = c;
}
std::tuple<std::chrono::system_clock::time_point, std::chrono::system_clock::time_point, std::chrono::system_clock::time_point> Borrow::write()
{
	return std::tuple<std::chrono::system_clock::time_point, std::chrono::system_clock::time_point,
		std::chrono::system_clock::time_point>(begin, end, should);
}
bool Borrow::noemp() const
{
	return !ID.empty();
}
std::ofstream& operator<<(std::ofstream& out, const Borrow& aim)
{
	out << aim.ID << ' ' << aim.name << ' ' << aim.isreturn;
	return out;
}

Account.h
#pragma once
#include <Windows.h>
#include "Borrow.h"
#include <string>
#include <fstream>
using namespace std;
class Account
{
protected:
	string account, password, name;
public:
	Account(string account, string password, string name);
	~Account();
	bool log(const string& account, const string& password);
	string getName();
};
class User :public Account
{
private:
	size_t fine;
	vector<Borrow> list;
public:
	User(string account, string password, string name);
	~User();
	string& getAccount();
	size_t getFine();
	void push_back(const Borrow& b);
	void showBorrow();
	Borrow& returnBook(bool& p);
	friend ofstream& operator<<(ofstream& out, const User& aim);
};
class AccontList
{
	Account manager;
	vector<User> user;
public:
	AccontList();
	~AccontList();
	int loginUser(const string& account, const string& password);
	bool loginManager(const string& account, const string& password);
	Account& manage();
	User& operator[](int i);
	bool reje(const string& account, const string& password, const string& name);
};

Account.cpp
#include "Account.h"


Account::Account(string account, string password, string name)
	:account(account),password(password),name(name)
{
}

Account::~Account()
{
}

bool Account::log(const string& account, const string& password)
{
	return this->account == account && this->password == password;
}

string Account::getName()
{
	return name;
}


User::User(string account, string password, string name)
	:Account(account, password, name),fine(0)
{
	ifstream in(account + ".txt");
	ifstream inb(account + ".dat", std::ios::in | std::ios::binary);
	if (in.good())
	{
		string ID, BookName; bool is;
		while (!in.eof())
		{
			in >> ID >> BookName >> is;
			Borrow boo(ID, BookName);
			boo.is(is);
			std::chrono::system_clock::time_point a, b, c;
			inb.read(reinterpret_cast<char*>(&a), sizeof(std::chrono::system_clock::time_point));
			inb.read(reinterpret_cast<char*>(&b), sizeof(std::chrono::system_clock::time_point));
			inb.read(reinterpret_cast<char*>(&c), sizeof(std::chrono::system_clock::time_point));
			boo.change(a, b, c);
			list.push_back(boo);
		}

	}
	if (!list.empty())
	{
		for (auto& fff : list)
		{
			if (!fff.isReturn()&&fff.overtime())
			{
				fine += 1;
			}
		}
	}
}

User::~User()
{
	if (!list.empty())
	{
		ofstream out(account + ".txt");
		ofstream outb(account + ".dat", std::ios::out | std::ios::binary);
		for (int i = 0; i < list.size(); i++)
		{
			out << list[i];
			if (i < list.size() - 1)
			{
				out << '\n';
			}
			auto tup = list[i].write();
			std::chrono::system_clock::time_point a = std::get<0>(tup), b = std::get<1>(tup), c = std::get<2>(tup);
			outb.write(reinterpret_cast<char*>(&a), sizeof(std::chrono::system_clock::time_point));
			outb.write(reinterpret_cast<char*>(&b), sizeof(std::chrono::system_clock::time_point));
			outb.write(reinterpret_cast<char*>(&c), sizeof(std::chrono::system_clock::time_point));
		}
	}
}


string& User::getAccount()
{
	return account;
}

size_t User::getFine()
{
	return fine;
}

void User::showBorrow()
{
	if (list.empty())
	{
		cout << "尚无借书记录" << endl;
	}
	for (auto& borrow : list)
	{
		borrow.show();
	}
}

Borrow& User::returnBook(bool& p)
{
	int j;
	for (int i = 0; i < list.size(); ++i)
	{
		cout <<"编号:" << i << '.';
		list[i].show();
	}
	cout << "请输入要归还的书籍所对应的借书记录编号" << endl;
	cin >> j;
	system("cls");
	if (j >= list.size() || j < 0)
	{
		cout << "没有此借书记录" << endl;
		Borrow a;
		p = false;
		return a;
	}
	else if (list[j].isReturn())
	{
		cout << "书籍已经被归还" << endl;
		Borrow a;
		p = false;
		return a;
	}
	return list[j];
	
}


void User::push_back(const Borrow& b)
{
	if(b.noemp())
		list.push_back(b);
}


AccontList::AccontList()
	:manager("mashiro","0721","管理员")
{
	ifstream in("user.txt");
	while (!in.eof())
	{
		string a, b, c;
		in >> a >> b >> c ;
		user.emplace_back(a, b, c);
	}
}

AccontList::~AccontList()
{
	ofstream out("user.txt");
	for (int i = 0; i < user.size(); i++)
	{
		out << user[i];
		if (i < user.size() - 1)
		{
			out << '\n';
		}
	}
}



bool AccontList::loginManager(const string& account, const string& password)
{
	return manager.log(account, password);
}


int AccontList::loginUser(const string& account, const string& password)
{
	for (int i = 0; i < user.size(); i++)
	{
		if (user[i].log(account, password))
		{
			return i;
		}
	}
	return -1;
}

User& AccontList::operator[](int i)
{
	return user[i];
}
bool AccontList::reje(const string& account, const string& password, const string& name)
{
	for (auto& a : user)
	{
		if (a.getAccount() == account)
		{
			return false;
		}
	}
	user.emplace_back(account, password, name);
	return true;
}
Account& AccontList::manage()
{
	return manager;
}
ofstream& operator<<(ofstream& out, const User& aim)
{
	out << aim.account << ' ' << aim.password << ' ' << aim.name ;
	return out;
}

Books.h
#pragma once
#include <iostream>
#include <string>
#include<iomanip>
#include<vector>
#include<algorithm>
#include<fstream>
using namespace std;
class Books {
protected:
	string id;
	string name;
	double price;
	string author;
	string publishing;
	int inventory;
	float totalmark = 0;
	size_t totalman = 0;
public:
	
	Books(string a, string b, double c, string d, string e, int f);
	~Books();
	Books();
	string get_id();
	string get_name();
	double get_price();
	string get_author();
	string get_publishing();
	int get_inventory();
	float get_aver_mark()const;
	float get_totalmark();
	int get_totalman();
	virtual void ShowMe();
	friend ofstream& operator<<(ofstream& out, const Books& a);
	friend ifstream& operator>>(ifstream& in, Books& a);
	bool Search(const string& a);
	friend Books& operator+(Books& ,int b);
	friend Books& operator-(Books& , int b);
	Books& operator++();
	const Books operator++(int);
	Books& operator--();
	const Books operator--(int);
	void evaluate();
	void dis_evalution();
};
class ScienceBook :public Books {
public:
	ScienceBook(string id, string name, double price, string author, string publishing, int inventory);
	ScienceBook() = default;
};
class SocialBook :public Books {
public:
	SocialBook(string id, string name, double price, string author, string publishing, int inventory);
	SocialBook() = default;
};
class ForeignBook :public Books {
protected:
	string Language;
public:
	virtual void ShowMe();
	ForeignBook(string id, string name, double price, string author, string publishing, int inventory, string language);
	friend ofstream& operator<<(ofstream& out, const ForeignBook& a);
	friend ifstream& operator>>(ifstream& in, ForeignBook& a);
	void evaluate();
	void dis_evalution();
	ForeignBook() = default;
};
Books.cpp
#include"Books.h"
Books::Books(string a, string b, double c, string d, string e, int f)
	:id(a), name(b), price(c), author(d), publishing(e), inventory(f) {}
Books::~Books(){}
Books::Books(){}
ScienceBook::ScienceBook(string id, string name, double price, string author, string publishing, int inventory)
	:Books(id, name, price, author, publishing, inventory) {}
SocialBook::SocialBook(string id, string name, double price, string author, string publishing, int inventory)
	:Books(id, name, price, author, publishing, inventory) {}
ForeignBook::ForeignBook(string id, string name, double price, string author, string publishing, int inventory, string language)
	:Books(id, name, price, author, publishing, inventory), Language(language) {}
void ForeignBook::evaluate()
{
	string evalution;
	float a;
	ofstream eva(name + ".txt", ios::ate | ios::app);
	cout << "请输入你对该书的评分" << endl;
	while (true)
	{
		cin >> a;
		if (a >= 0 && a <= 10.0)
		{
			eva << a << "  ";
			totalman++;
			totalmark = totalmark + a;
			break;
		}
		else
			cout << "评分应为0-10请重新输入" << endl;
	}
	cout << "请输入你对这本书的评价" << endl;
	cin >> evalution;
	eva << evalution << endl;
}
void ForeignBook::dis_evalution()
{
	ifstream fin(name + ".txt", ios::in);
	vector<string>a;
	vector<float>b;
	string evalu;
	float score;
	while (fin >> score && fin >> evalu)
	{
		b.emplace_back(score);
		a.emplace_back(evalu);
	}
	for (int i = 0; i < a.size(); i++)
	{
		cout << "评分:" << b[i] << "  ";
		cout << "评价:" << a[i] << endl;
	}
}
ofstream& operator<<(ofstream& out, const Books& a)
{
	out << a.id << " " << a.name << " " << a.price << " " << a.author << " " << a.publishing
		<< " " << a.inventory << " "<<a.totalmark<<" "<<a.totalman;
	return out;
}
ifstream& operator >>(ifstream& in, Books& a)
{
	in >> a.id >> a.name >> a.price >> a.author >> a.publishing >> a.inventory>>a.totalmark>>a.totalman;
	return in;
}
ofstream& operator<<(ofstream& out, const ForeignBook& a)
{
	out << a.id << " " << a.name << " " << a.price << " " << a.author << " " << a.publishing <<
		" " << a.inventory << " " << a.Language <<" "<<a.totalmark<<" "<<a.totalman;
	return out;
}
ifstream& operator >>(ifstream& in, ForeignBook& a)
{
	in >> a.id >> a.name >> a.price >> a.author >> a.publishing >> a.inventory>>a.Language >> a.totalmark >> a.totalman;
	return in;
}
Books& operator+(Books& a,int b)
{
	a.inventory = a.inventory + b;
	return a;
}
 Books& operator-(Books& a, int b)
{
	 a.inventory = a.inventory - b;
	 return a;
}
string Books::get_id(){ return id; }
string Books::get_name(){ return name; }
double Books::get_price(){ return price; }
string Books::get_author() { return author; }
string Books::get_publishing() { return publishing; }
int Books::get_inventory() { return inventory; }
float Books::get_totalmark() { return totalmark; }
int Books::get_totalman() { return totalman; }
float Books::get_aver_mark()const { return totalmark / totalman; }
void Books::ShowMe(){
	cout << "编号:" << std::left << setw(10) << id << " " << "书名:" << std::left << setw(10) << name << " " << "价格:" <<
		std::left << setw(8) << setprecision(4) << price << " " << "作者:" << std::left << setw(10) << author << " " << "出版社:" <<
		std::left << setw(10) << publishing << " " << "库存:" << std::left << setw(5) << inventory
		<< " ";
	if (totalman == 0)
	{
		cout << "暂无评分" << endl;
	}
	else
	{
		cout<< "评分:" << setprecision(2) << get_aver_mark() << endl;
	}
}
void ForeignBook::ShowMe() {
	cout << "编号:" << std::left << setw(10) << id << " " << "书名:" << std::left << setw(10) << name << " " << "价格:" <<
		std::left << setw(8) << setprecision(4) << price << " " << "作者:" << std::left << setw(10) << author << " " << "出版社:" <<
		std::left << setw(10) << publishing<< " " << std::left << setw(5) << "语言:" << Language << " " << "库存:" << std::left << setw(5) << inventory;
		if (totalman == 0)
		{
			cout << "暂无评分" << endl;
		}
		else
		{
			cout <<"评分:"<< setprecision(2) << get_aver_mark() << endl;
		}
}
bool Books::Search(const string& a)
{
	return id.find(a) != -1 || name.find(a) != -1 || author.find(a) != -1 || publishing.find(a) != -1;
}
Books& Books::operator++()
{
	this->inventory++;
	return *this;
}
const Books Books::operator++(int)
{
	Books a;
	this->inventory++;
	return a;
}

Books& Books::operator--()
{
	this->inventory--;
	return *this;
}

const Books Books::operator--(int)
{
	Books a;
	this->inventory--;
	return a;
}

void Books::evaluate()
{
	string evalution;
	float a;
	ofstream eva(name + ".txt", ios::ate | ios::app);
	cout << "请输入你对该书的评分" << endl;
	while (true)
	{
		cin >> a;
		if (a >= 0 && a <= 10.0)
		{
			totalman++;
			totalmark=totalmark + a;
			break;
		}
		else
			cout << "评分应为0-10请重新输入" << endl;
	}
	char YON;
	cout << "是否要为这本书写一段评价(Y/N)" << endl;
	cin >> YON;
	if(YON=='Y')
	{
		cout << "请输入你对这本书的评价" << endl;
		cin >> evalution;
		eva << evalution << endl;
	}
}
void Books::dis_evalution()
{
	ifstream fin(name + ".txt", ios::in);
	if (fin.good())
	{
		vector<string>a;
		string evalu;
		while (fin >> evalu)
		{
			a.push_back(evalu);
		}
		if (!a.empty())
		{
			for (int i = 0; i < a.size(); i++)
			{
				cout << "评价:" << a[i] << endl;
			}
		}
	}
}
libarary.h
#pragma once
#include<Windows.h>
#include"Books.h"
#include"Borrow.h"
#include<vector>

template<typename T,int S>
class Libaray
{
private:
    std::vector<T> list;
public:
    Libaray()
    {
        string a;
        if (S == 1)
        {
            a = "1";
        }
        else if(S==2)
        {
            a="2";
        }
        else if (S == 3)
        {
            a="3";
        }
        std::ifstream file(a + "book.txt");
        while (!file.eof())
        {
            T book;
            file >> book;
            list.push_back(book);
        }
    }//从文件中读取Books的信息并放入list
    ~Libaray()
    {
        string a;
        if (S == 1)
        {
            a="1";
        }
        else if (S == 2)
        {
            a="2";
        }
        else if (S == 3)
        {
            a="3";
        }
        std::ofstream file(a+"book.txt");
        for (int i = 0; i < list.size(); i++)
        {
            file << list[i];
            if (i < list.size() - 1)
            {
                file << "\n";
            }
        }
    }//将list中的book的信息传入文件
    T& operator[](int i)
    {
        return list[i];
    }
    Borrow lend()
    {
        string id;
        int day;
        cout << "请输入您想寻找的书籍ID:";
        cin >> id;
        for (auto it = list.begin(); it != list.end(); ++it)
        {
            if (it->get_id() == id && it->get_inventory() > 0)
            {
                cout << "请输入您想借阅的天数:";
                cin >> day;
                --*it;
                cout << "该书籍已被成功借阅" << endl;
                return Borrow(id, it->get_name(), day);
            }
        }
        cout << "您寻找的书籍未满足可借阅条件" << endl;
        return Borrow();
    }
    void add()
    {
        string id;
        int addnum;
        cout << "请输入您想要增添库存的书籍ID:";
        cin >> id;
        cout << endl;
        for (auto it = list.begin(); it != list.end(); ++it)
        {
            if (it->get_id() == id)
            {
                cout << "请输入您想要增添的数量:";
                cin >> addnum;
                cout << endl;
                *it + addnum;
                cout << "成功添加到库存当中";
                return;
            }
        }
        std::cout << "没有在书库中找到对应的书籍" << std::endl;
    }
    void addnew(string id,string name,double price,string author,string publishing,int inventory)
    {
        for (auto it = list.begin(); it != list.end(); it++)
        {
            if (it->get_id() == id)
            {
                std::cout << "该书籍ID与书库中已有的书籍的ID重合" << std::endl;
                return;
            }
            if (it->get_name() == name)
            {
                cout << "该书籍的书名与书库中已有的书籍书名重合" << endl;
                return;
            }
        }
        list.push_back(T(id, name,price,author, publishing,inventory));
        cout << "该书籍已被成功添入书库" << endl;
    }
    void addnew(string id, string name, double price, string author, string publishing, int inventory,string language)
    {
        for (auto it = list.begin(); it != list.end(); it++)
        {
            if (it->get_id() == id)
            {
                std::cout << "该书籍ID与书库中已有的书籍的ID重合" << std::endl;
                return;
            }
            if (it->get_name() == name)
            {
                cout << "该书籍的书名与书库中已有的书籍书名重合" << endl;
                return;
            }
        }
        list.push_back(T(id, name, price, author, publishing, inventory,language));
        cout << "该书籍已被成功添入书库" << endl;
    }
    void searchBook()
    {
        string id; char i;
        cout << "请输入您想要搜索的书籍ID:";
        cin >> id;
        cout << endl;
        system("cls");
        for (T& book : list) {
            if (book.get_id() == id) {
                book.ShowMe();
                cout << "\n是否要进一步查看书籍信息(T/F)" << endl;
                cin >> i;
                if (i == 'T')
                {
                    system("cls");
                    cout << "1.查看书籍评价   2.评价书籍" << endl;
                    cin >> i;
                    if (i == '1')
                    {
                        book.dis_evalution();
                    }
                    else if (i == '2')
                    {
                        book.evaluate();
                    }
                }
                return;
            }
        }
        std::cout << "未找到ID为" << id << "的书籍。" << std::endl;
    }
    void search()
    {
        bool find = false;
        string aim;
        cout << "请输入您想要搜索的书籍拥有的信息:";
        cin >> aim;
        cout << endl;
        system("cls");
        for (T& book : list)
        {
            if (book.Search(aim))
            {
                book.ShowMe();
                find = true;
            }
        }
        if (!find)
        {
            cout << "提供信息:" << aim << endl << "没有找到符合条件的书籍" << endl;
        }
    }
    void erase()
    {
        string id;
        cout << "请输入您想要删除的书籍ID:";
        cin >> id;
        cout << endl;
        for (auto it = list.begin(); it != list.end(); ++it)
        {
            if (it->get_name() == id) {
                system("cls");
                std::cout << "已删除书籍: " << it->get_name() << std::endl;
                list.erase(it);
                return;
            }
        }
        system("cls");
        std::cout << "未找到ID为" << id << "的书籍。" << std::endl;
    }
    void showAll()
    {
        for (auto& book : list)
        {
            book.ShowMe();
        }
    }
    void returnBook(Borrow& borrow)
    {
        for (T& book : list) {
            if (book.get_id() == borrow.getID()) {
                ++book;
                borrow.returnbook();
                return;
            }
        }
    }
};

class AllLibaray {
private:
    Libaray<ScienceBook, 1>a;
    Libaray<SocialBook, 2>b;
    Libaray<ForeignBook, 3>c;
    int i;
public:
    void choice();
    void addnew();
    Borrow lend();
    void add();
    void searchBook();
    void search();
    void erase();
    void showAll();
    void returnBook(Borrow& borrow);
};
libarary.cpp
#include "libaray.h"
void AllLibaray::choice()
{
    cout << "以下是图书馆书籍库的书籍类型:\n";
    cout << "1.科学类书籍库\t2.社会类书籍库\t3.外语类书籍库\n";
    cout << "请输入您想要进入的书籍库:";
    cin >> i;
    system("cls");
    if (i == 1)
    {
        cout << "您将进入科学类书籍库\n";
    }
    else if (i == 2)
    {
        cout << "您将进入社会类书籍库\n";
    }
    else if (i == 3)
    {
        cout << "您将进入外语类书籍库\n";
    }
    
}
void AllLibaray::addnew()
{
    string id, name, author, publishing, language;
    int inventory;
    float price;
    if (i == 1)
    {
        cout << "请输入您想要添加的书籍信息:\n";
        cout << "书籍ID:";
        cin >> id;
        cout << endl << "书籍名字:";
        cin >> name;
        cout << endl << "书籍价格:";
        cin >> price;
        cout << endl << "书记作者:";
        cin >> author;
        cout << endl << "书籍出版社:";
        cin >> publishing;
        cout << endl << "添入书库的库存数量:";
        cin >> inventory;
        a.addnew(id, name, price, author, publishing, inventory);
    }
    else if (i == 2)
    {
        cout << "请输入您想要添加的书籍信息:\n";
        cout << "书籍ID:";
        cin >> id;
        cout << endl << "书籍名字:";
        cin >> name;
        cout << endl << "书籍价格:";
        cin >> price;
        cout << endl << "书记作者:";
        cin >> author;
        cout << endl << "书籍出版社:";
        cin >> publishing;
        cout << endl << "添入书库的库存数量:";
        cin >> inventory;
        b.addnew(id, name, price, author, publishing, inventory);
    }
    else if (i == 3)
    {
        cout << "请输入您想要添加的书籍信息:\n";
        cout << "书籍ID:";
        cin >> id;
        cout << endl << "书籍名字:";
        cin >> name;
        cout << endl << "书籍价格:";
        cin >> price;
        cout << endl << "书记作者:";
        cin >> author;
        cout << endl << "书籍出版社:";
        cin >> publishing;
        cout << endl << "添入书库的库存数量:";
        cin >> inventory;
        cout << endl << "该外刊的语言种类:";
        cin >> language;
        c.addnew(id, name, price, author, publishing, inventory, language);
    }
}
Borrow AllLibaray::lend()
{
    switch (i)
    {
    case 1:a.showAll(); return a.lend();
        break;
    case 2:b.showAll(); return b.lend();
        break;
    case 3:c.showAll(); return c.lend();
        break;
    }
}
void AllLibaray::add()
{
    switch (i)
    {
    case 1:a.showAll(); a.add();
        break;
    case 2:b.showAll(); b.add();
        break;
    case 3:c.showAll(); c.add();
        break;
    }
}
void AllLibaray::searchBook()
{
    switch (i)
    {
    case 1: a.searchBook();
        break;
    case 2: b.searchBook();
        break;
    case 3: c.searchBook();
        break;
    }
}
void AllLibaray::search()
{
    switch (i)
    {
    case 1: a.search();
        break;
    case 2: b.search();
        break;
    case 3: c.search();
        break;
    }
}
void AllLibaray::erase()
{
    switch (i)
    {
    case 1:a.showAll(); a.erase();
        break;
    case 2:b.showAll(); b.erase();
        break;
    case 3:c.showAll(); c.erase();
        break;
    }
}
void AllLibaray::showAll()
{
    switch (i)
    {
    case 1: a.showAll();
        break;
    case 2: b.showAll();
        break;
    case 3: c.showAll();
        break;
    }
}

void AllLibaray::returnBook(Borrow& borrow)
{
    a.returnBook(borrow);
    b.returnBook(borrow);
    c.returnBook(borrow);
}

3. 主要问题列表
  • 代码中使用了goto语句,破坏了整体的结构性,重新优化结构以避免使用goto语句

  • 进入登录或注册操作后,不成功登录或注册无法回到选择登录还是注册界面,如果用户误操作,就必须重新启动程序

  • 用户在借书后,显示借书时间与实际时间不符

  • 用户在精准查询时,可以输入,对于该书籍的评价,但在模糊搜寻后,若想要评价某一书籍,必须重新进入查询的精准查询功能,步骤繁琐

  • 删除数据功能有误

  • 删除书籍后,曾有对于书籍评价的文件还会存在,不会一并被删除

  • 还书时,若书籍被删除,会出bug

  • 输出的文字存在部分语法错误

  1. 新代码附上
代码中使用了goto语句,破坏了整体的结构性,重新优化结构以避免使用goto语句
	auto manage = [&list, &lib]()
		{
			int j = 0;
			lib.choice();
			system("pause");
			while (true)
			{
				system("cls");
				cout << "请根据提示输入数字以进行操作" << endl;
				cout << "1.重新选择书籍库	2.修改现有书籍数量        3.增添新的书籍" << endl;
				cout << "4.删除书籍	        5.显示本书籍库中所有书籍  6.查找书籍" << endl;
				cout << "7.退出登录" << endl;
				cin >> j;
				system("cls");
				switch (j)
				{
				case 1:lib.choice();
					break;
				case 2:lib.add();
					break;
				case 3:lib.addnew();
					break;
				case 4:lib.erase();
					break;
				case 5:lib.showAll();
					break;
				case 6:cout << "请选择查找书籍的方式:\n1.根据书籍id精确搜索		2.模糊搜索" << endl;
					cin >> j;
					if (j == 2)lib.search();
					else lib.searchBook();
					break;
				}
				if (j == 7)
				{
					break;
				}
				system("pause");
			}
			system("cls");
		};
	auto use = [&list, &lib](User& user)
		{
			if (user.getFine() != 0)
			{
				cout << "您有" << user.getFine() << "本书籍逾期,请尽快还书" << endl;
				system("pause");
				system("cls");
			}
			int j = 0;
			lib.choice();
			system("pause");
			while (true)
			{
				system("cls");
				cout << "请根据提示输入数字以进行操作" << endl;
				cout << "1.重新选择书籍库          2.借阅书籍     3.借书管理" << endl;
				cout << "4.显示本书籍库中所有书籍  5.查找书籍     6.退出登录" << endl;
				cin >> j;
				system("cls");
				switch (j)
				{
				case 1:lib.choice();
					break;
				case 2:user.push_back(lib.lend());
					break;
				case 3:cout << "请根据提示输入数字以进行操作\n1.查看借阅信息	 2.还书" << endl;
					cin >> j;
					system("cls");
					if (j == 1)
					{
						user.showBorrow();
					}
					else if (j == 2)
					{
						
						if (user.hasBorrow())
						{
							bool p = true;
							Borrow& borrow = user.returnBook(p);
							if (p)
							{
								lib.returnBook(borrow);
								cout << "还书成功" << endl;
							}
						}
						else
						{
							cout << "尚无借书记录" << endl;
							system("pause");
						}
						
					}
					break;
				case 4:lib.showAll();
					break;
				case 5:cout << "请选择查找书籍的方式:\n1.根据书籍id精确搜索		2.模糊搜索" << endl;
					cin >> j;
					if (j == 2)lib.search();
					else lib.searchBook();
					break;
				}
				if (j == 6)
				{
					break;
				}
				system("pause");
			}
			system("cls");
		};
	while (true)
	{
		system("cls");
		cout << "   欢迎使用图书馆管理系统   " << endl;
		cout << "请根据提示输入数字以进行操作" << endl;
		cout << "   1.登录  2.注册  3.退出   " << endl;
		cin >> i;
		if (i == 1)
		{
			i = log();
			if (i == -1)
			{
				manage();
			}
			else if (i == -2)
			{

			}
			else
			{
				use(list[i]);
			}
		}
		else if (i == 2)
		{
			reject();
		}
		else
		{
			break;
		}
	}
        
进入登录或注册操作后,不成功登录或注册无法回到选择登录还是注册界面,如果用户误操作,就必须重新启动程序
	auto reject = [&list, &lib]()
		{
			string acc, pass, name;
			system("cls");
			cout << "\t注册(若想返回初始界面请于“账户:”输入return)" << endl;
			cout << "账户:";
			cin >> acc;
			if (acc == "return")
			{
				return;
			}
			cout << "密码:";
			cin >> pass;
			cout << "用户名:";
			cin >> name;
			while (!list.reje(acc, pass, name))
			{
				system("cls");
				cout << "\t注册账号重复,请重试(若想返回初始界面请于“账户:”输入return)\n账户:";
				cin >> acc;
				if (acc == "return")
				{
					return;
				}
				cout << "密码:";
				cin >> pass;
				cout << "用户名:";
				cin >> name;
			}
			system("cls");
			cout << "  注册成功" << endl;
			system("pause");
		};
	auto log = [&list, &lib]()
		{
			system("cls");
			int i; string acc, pass;
			cout << "请选择以何种身份登录" << endl;
			cout << "1.管理员   2.用户   " << endl;
			cin >> i;
			system("cls");
			cout << "(若想返回初始界面请于“账户:”输入return)\n账户:";
			cin >> acc;
			if (acc == "return")
			{
				return -2;
			}
			cout << "密码:";
			cin >> pass;
			if (i == 1)
			{
				if (!list.loginManager(acc, pass))
				{
					do
					{
						system("cls");
						cout << "账号密码错误,请重新输入(若想返回初始界面请于“账户:”输入return)\n";
						cout << "账户:";
						cin >> acc;
						if (acc == "return")
						{
							return -2;
						}
						cout << "密码:";
						cin >> pass;
					} while (!list.loginManager(acc, pass));

				}
				system("cls");
				cout << "登陆成功,欢迎管理员使用" << endl;
				return -1;
			}
			else
			{
				int i;
				if ((i = list.loginUser(acc, pass)) != -1)
				{
					system("cls");
					cout << "登陆成功,欢迎用户" << list[i].getName()
						<< "使用" << endl;
					return i;
				}
				else
				{
					do
					{
						system("cls");
						cout << "账号密码错误,请重新输入(若想返回初始界面请于“账户:”输入return)\n";
						cout << "账户:";
						cin >> acc;
						if (acc == "return")
						{
							return -2;
						}
						cout << "密码:";
						cin >> pass;
					} while ((i = list.loginUser(acc, pass)) == -1);
					system("cls");
					cout << "登陆成功,欢迎用户" << list[i].getName()
						<< endl;
					return i;
				}
			}
		};
用户在借书后所记录的借书时间与当前时间不符
Borrow::Borrow(std::string ID, std::string name, int day)
	:ID(ID), name(name), begin(std::chrono::system_clock::now() + std::chrono::hours(8)), should(begin + std::chrono::days(day))
{
	
}
用户在精准查询时,可以输入,对于该书籍的评价,但在模糊搜寻后,若想要评价某一书籍,必须重新进入查询的精准查询功能,步骤繁琐
   void search()
   {
       bool find = false;
       string aim;
       cout << "请输入您想要搜索的书籍拥有的信息:";
       cin >> aim;
       cout << endl;
       system("cls");
       for (T& book : list)
       {
           if (book.Search(aim))
           {
               book.ShowMe();
               find = true;
           }
       }
       if (!find)
       {
           cout << "提供信息:" << aim << endl << "没有找到符合条件的书籍" << endl;
       }
       else
       {
           char userDicision;
           cout << "\n是否要进一步查看书籍信息(T/F)" << endl;
           cin >> userDicision;
           if (userDicision == 'T')
           {
               while (true)
               {
                   system("cls");
                   cout << "请输入您想要进一步查看的书籍ID:" << endl;
                   string id;
                   cin >> id;
                   for (T& book : list)
                   {
                       if (book.get_id() == id)
                       {
                           cout << "1.查看书籍评价   2.评价书籍" << endl;
                           cin >> userDicision;
                           if (userDicision == '1')
                           {
                               book.dis_evalution();
                           }
                           else if (userDicision == '2')
                           {
                               book.evaluate();
                           }
                           return;
                       }
                   }
                   cout << "未找到ID为" << id << "的书籍。是否要从新输入(T/F)" << endl;
                   cin >> userDicision;
                   if (userDicision == 'F')
                   {
                       return;
                   }
               }
           }
       }
   }
删除数据功能有误
void erase()
{
    string id;
    cout << "请输入您想要删除的书籍ID:";
    cin >> id;
    cout << endl;
    for (auto it = list.begin(); it != list.end(); ++it)
    {
        if (it->get_id() == id) {
            system("cls");
            std::cout << "已删除书籍: " << it->get_name() << std::endl;
            std::filesystem::path deleteFileName = it->get_name() + ".txt";
            if (std::filesystem::exists(deleteFileName))
            {
                std::filesystem::remove(deleteFileName);
            }
            list.erase(it);
            return;
        }
    }
    system("cls");
    std::cout << "未找到ID为" << id << "的书籍。" << std::endl;
}
删除书籍后,曾有对于书籍评价的文件还会存在,不会一并被删除
std::filesystem::path deleteFileName = it->get_name() + ".txt";
if (std::filesystem::exists(deleteFileName))
{
    std::filesystem::remove(deleteFileName);
}
还书时,若书籍被删除,会出bug
    void returnBook(Borrow& borrow)
    {
        for (T& book : list) {
            if (book.get_id() == borrow.getID()) {
                ++book;
                break;
            }
        }
        borrow.returnbook();
        return;
    }
输出的文字存在部分语法错误
cout << "\t注册账号重复,请重试(若想返回初始界面请于“账户:”输入return)\n账户:";
5. 重构的软件的测试截图

  1. 总结
    本次逆向二次开发,难点在于理解其他人写的代码。Borrow类里超级长的返回值和复杂的STL库函数调用理解起来非常困难。此外,在阅读代码时,没有注释很难理解这段代码的作用是什么。例如,Borrow类构造函数中第二个成员变量赋值中给std::chrono::system_clock::now()加上了两个值,非常难以理解原因,在翻阅了STL库标准文档后才发现std::chrono::system_clock::now()是零时区的时间,换算成中国时间要加八个小时( + std::chrono::hours(8)),而第二个值却是被错误的加上的,会导致程序出bug。
    意识到了在开发过程中,注释和开发文档的重要性。
posted @ 2025-02-28 01:08  仓田真白-破镜之蝶  阅读(39)  评论(0)    收藏  举报