C++ 图书管理系统--单机版 ( 约 1000行 代码 ) 用 C 实现的单机版图书管理系统具备完整借还管理、库存统计、热度排行、数据持久化和命令行交互界面。1. 程序实现的功能清单编号功能说明1添加图书ISBN/书名/作者/类型/库存2修改图书支持改 ISBN级联更新读者记录3入库采购新书库存增加4下架报废/淘汰库存减少5图书列表显示所有图书及借出情况6统计种类/总藏量/可借/已借出7读者注册ID/姓名/最大借阅数8修改读者ID/姓名/借阅上限9借书库存校验、上限校验、重复校验10还书自动记录归还时间11读者列表借阅记录详情12热度排行降序/升序辅助采购下架决策13保存数据手动保存到文件14加载数据从文件恢复15借阅记录查询按 ISBN 查所有借阅历史输入校验类型检查 y/n 确认机制启动自动加载程序启动读取文件0退出询问保存防止数据丢失2. 设计框架分层架构数据关系命令行交互程序运行示例图:交互界面选择 “保存数据” 后--读者信息保存在 readers.txt 文件中图书数据库信息保存在 books.txt 文件中BookHub.cpp 代码#include pch.h #define BOOKFILE books.txt #define READERFILE readers.txt // 借阅记录 struct BorrowRecord { std::string Isbn; // 借阅的图书 ISBN std::string BorrowTime; // 借阅时间 std::string ReturnTime; // 归还时间空字符串表示未归还 // 借阅记录 BorrowRecord(const std::string bookIsbn, const std::string borrowTime) : Isbn(bookIsbn),BorrowTime(borrowTime),ReturnTime() {} // 是否已归还 bool IsReturned() const{ return !ReturnTime.empty(); } }; // 获取当前时间, 转换为字符串 inline std::string GetCurrentTimeStr() { auto now std::time(nullptr); // 获取当前秒数 auto* tm std::localtime(now);// 秒数 → 年月日时分秒 std::ostringstream oss; oss std::put_time(tm,%Y-%m-%d %H:%M:%S); return oss.str(); } class Book { protected: std::string m_BookIsbn; // 图书唯一标识码, 例如 978-7-115-49250-0 std::string m_BookName; // 书名 std::string m_BookAuthor; // 作者 std::string m_BookType; // 类型 u_int32_t m_stock; // 单本书当前可借数量 ( 剩余库存 ) u_int32_t m_total; // 单本书总藏书量包括已借出的 public: Book(const std::string isbn,const std::string name,const std::string author \ ,const std::string type,u_int32_t stock,u_int32_t total 0) : m_BookIsbn(isbn),m_BookName(name),m_BookAuthor(author),\ m_BookType(type), m_stock(stock), m_total(total 0 ? stock : total) {} const std::string GetBookIsbn() const {return m_BookIsbn;} const std::string GetBookName() const {return m_BookName;} const std::string GetBookAuthor() const {return m_BookAuthor;} const std::string GetBookType() const {return m_BookType;} u_int32_t Get_stock() const {return m_stock;} u_int32_t Get_total() const {return m_total;} // 当录入错误信息时修改信息 void ResetBookIsbn(const std::string isbn) { m_BookIsbn isbn; } void ResetBookName(const std::string name) { m_BookName name; } void ResetBookAuthor(const std::string author) { m_BookAuthor author; } void ResetBookType(const std::string type) { m_BookType type; } // 单本书增加库存采购新书 void AddStock(uint32_t count) { m_stock count; m_total count; std::cout 书名: m_BookName 入库: count 本当前库存: m_stock / m_total std::endl; } // 单本书 下架淘汰/报废 bool RemoveStock(uint32_t count) { if(count m_stock) { std::cout 下架失败可下架数量不能超过当前库存 - m_stock std::endl; return false; } m_stock - count; m_total - count; std::cout 书名: m_BookName 下架: count 本当前库存: m_stock / m_total std::endl; return true; } // 单本书可借数量 uint32_t GetAvailable() const { return m_stock; } // 单本书已借出数量 uint32_t GetBorrowedCount() const { return m_total - m_stock; } // 图书信息 void PrintBookInfo() const { std::cout 书名: m_BookName 作者: m_BookAuthor 类型: m_BookType 可借: m_stock 本, 已借: GetBorrowedCount() 本, 总计: m_total 本 std::endl; } // 借书 库存减 bool BorrowOne() { if(m_stock 0){ m_stock--; return true; } return false; } // 还书 库存加 void ReturnOne() { if(m_stock m_total) m_stock; } // 序列化为文件格式 std::string Serialize() const { return m_BookIsbn | m_BookName | m_BookAuthor | m_BookType | std::to_string(m_stock) | std::to_string(m_total); } // 从文件格式反序列化 static Book Deserialize(const std::string line) { std::stringstream ss(line); std::string isbn, name, author, type, stockStr, totalStr; std::getline(ss, isbn, |); std::getline(ss, name, |); std::getline(ss, author, |); std::getline(ss, type, |); std::getline(ss, stockStr, |); std::getline(ss, totalStr, |); Book book(isbn, name, author, type, \ std::stoul(stockStr), std::stoul(totalStr)); return book; } virtual ~Book() default; }; class Reader { private: uint32_t m_Id; // 读者ID std::string m_Name; // 姓名 std::string m_CreateTime; // 读者创建时间 std::vectorBorrowRecord m_BorrowRecords; // 借阅记录列表 int m_MaxLimit; // 最大借阅数量 public: Reader(uint32_t id,const std::string name,int limit) : m_Id(id),m_Name(name),m_CreateTime(GetCurrentTimeStr()),m_MaxLimit(limit) {} uint32_t GetId() const { return m_Id; } const std::string GetName() const { return m_Name; } const std::string GetCreateTime() const { return m_CreateTime; } int GetMaxLimit() const { return m_MaxLimit; } // 修改读者信息 void ResetReaderId(uint32_t id){ m_Id id; } void ResetReaderName(std::string name){ m_Name name; } void ResetReaderMaxLimit(int limit){ m_MaxLimit limit; } void UpdateBorrowRecordISBN(const std::string oldIsbn, const std::string newIsbn) { for(auto record : m_BorrowRecords){ if(record.Isbn oldIsbn) record.Isbn newIsbn; } } // 当前 已经借了几本书 int GetCurrentBorrowCount() const{ int count 0; for(const auto record : m_BorrowRecords){ if(record.ReturnTime.empty()){ count; } } return count; } // 历史 总借阅次数 int GetTotalBorrowCount() const{ return m_BorrowRecords.size(); } // 是否达到 可借阅上限 bool CanBorrow() const { return GetCurrentBorrowCount() m_MaxLimit; } // 检查是否已借过某书且未归还 bool HasBook(const std::string isbn) const { for(const auto record : m_BorrowRecords){ if(record.Isbn isbn record.ReturnTime.empty()){ return true; } } return false; } // 借书 bool BorrowBook(const std::string isbn){ if(!CanBorrow()){ std::cout 借阅失败已达到最大借阅数量 m_MaxLimit std::endl; return false; } if(HasBook(isbn)){ std::cout 借阅失败已借过此书且未归还 std::endl; return false; } m_BorrowRecords.emplace_back(isbn,GetCurrentTimeStr()); std::cout m_Name 成功借阅 ISBN: isbn 时间: m_BorrowRecords.back().BorrowTime std::endl; return true; } // 还书 bool ReturnBook(const std::string isbn){ for(auto record : m_BorrowRecords){ if(record.Isbn isbn record.ReturnTime.empty()){ record.ReturnTime GetCurrentTimeStr(); std::cout m_Name 成功归还 ISBN: isbn 时间: record.ReturnTime std::endl; return true; } } // 借阅时系统做没有记录或者归还的不是此读者的书 std::cout 归还失败未找到该书的借阅记录 std::endl; return false; } // 获取当前借阅的 ISBN 列表 std::vectorstd::string GetCurrentBorrowedISBNs() const{ std::vectorstd::string isbns; for(const auto record : m_BorrowRecords){ if(record.ReturnTime.empty()){ isbns.emplace_back(record.Isbn); } } return isbns; } // 获取所有借阅记录 const std::vectorBorrowRecord GetBorrowRecords() const { return m_BorrowRecords; } // 打印读者的注册信息 void PrintReaderInfo(){ std::cout ID: m_Id Name: m_Name 注册时间: m_CreateTime std::endl; } // 打印读者信息 void PrintInfo() const { std::cout ID: m_Id Name: m_Name 注册时间: m_CreateTime 当前借阅: GetCurrentBorrowCount() / m_MaxLimit 本 std::endl; if(!m_BorrowRecords.empty()){ std::cout 借阅记录: std::endl; for(const auto record : m_BorrowRecords){ std::cout ISBN: record.Isbn 借阅时间: record.BorrowTime; if(record.ReturnTime.empty()){ std::cout 未归还 std::endl; }else{ std::cout 归还时间: record.ReturnTime std::endl; } } } } // 序列化读者信息 std::string SerializeInfo() const { return R: std::to_string(m_Id) | m_Name | m_CreateTime | std::to_string(m_MaxLimit); } // 序列化借阅记录 std::vectorstd::string SerializeRecords() const { std::vectorstd::string lines; for(const auto record : m_BorrowRecords){ lines.push_back(B: std::to_string(m_Id) | record.Isbn | record.BorrowTime | record.ReturnTime); } return lines; } // 从文件格式反序列化读者信息 static Reader DeserializeInfo(const std::string line) { std::stringstream ss(line.substr(2)); // 跳过 R: std::string idStr, name, createTime, limitStr; std::getline(ss, idStr, |); std::getline(ss, name, |); std::getline(ss, createTime, |); std::getline(ss, limitStr, |); Reader reader(std::stoul(idStr), name, std::stoi(limitStr)); // 恢复注册时间 reader.m_CreateTime createTime; return reader; } // 添加借阅记录从文件恢复时用 void AddBorrowRecord(const BorrowRecord record) { m_BorrowRecords.push_back(record); } }; class LibraryManager { private: // 按键排序的映射表, 红黑树平衡二叉搜索树,分配在堆上 std::mapstd::string, Book m_Books; // ISBN - Book std::mapint,Reader m_Readers; // ReaderID - Reader public: /* 图书管理 */ // 核心方法接收 Book 对象 bool AddBook(const Book book){ if(m_Books.find(book.GetBookIsbn()) ! m_Books.end()){ std::cout 图书: book.GetBookIsbn() 已存在! std::endl; return false; } m_Books.emplace(book.GetBookIsbn(),book); std::cout 成功添加 图书: book.GetBookName() std::endl; return true; } // 便捷添加方法只传必要参数 委托给核心方法 bool AddBook(const std::string isbn, const std::string name, const std::string author, const std::string type, uint32_t stock) { return AddBook(Book(isbn, name, author, type, stock)); } // 初始化列表批量添加 void AddBooks(std::initializer_listBook books){ for(const auto book : books){ AddBook(book); // 逐个调用单本添加方法 } } // 图书列表 void ShowAllBooks() const { for(const auto [isbn,book] : m_Books){ std::cout 书名: book.GetBookName() 作者: book.GetBookAuthor() 类型: book.GetBookType() 可借: book.Get_stock() 借出: book.GetBorrowedCount() ISBN: isbn std::endl; } } Book* FindBook(const std::string isbn) { auto it m_Books.find(isbn); return it ! m_Books.end() ? it-second : nullptr; } // 入库 bool AddBookStock(const std::string isbn, uint32_t count) { auto* book FindBook(isbn); if(!book) { std::cout 该图书不存在 std::endl; return false; } book-AddStock(count); return true; } // 下架 bool RemoveBookStock(const std::string isbn, uint32_t count) { auto* book FindBook(isbn); if(!book) { std::cout 该图书不存在 std::endl; return false; } return book-RemoveStock(count); } // 修改图书信息 bool ResetBookInfo(const std::string oldIsbn, const std::string newIsbn, const std::string name, const std::string author, const std::string type) { auto it m_Books.find(oldIsbn); if (it m_Books.end()) { std::cout 该图书不存在 std::endl; return false; } std::string finalIsbn newIsbn.empty() ? oldIsbn : newIsbn; // 如果 ISBN 变了检查新 ISBN 是否已存在 if(finalIsbn ! oldIsbn m_Books.find(finalIsbn) ! m_Books.end()){ std::cout 新 ISBN 已在数据库中 std::endl; return false; } Book book it-second; book.ResetBookIsbn(finalIsbn); // 非空才更新 if (!name.empty()) book.ResetBookName(name); if (!author.empty()) book.ResetBookAuthor(author); if (!type.empty()) book.ResetBookType(type); m_Books.erase(it); m_Books.emplace(finalIsbn,book); // 同步更新所有读者 借阅记录里的isbn,避免还书失败 if(finalIsbn ! oldIsbn){ for(auto [id,reader] : m_Readers){ reader.UpdateBorrowRecordISBN(oldIsbn,finalIsbn); } } return true; } // 图书馆统计 void ShowStatistics() const { uint32_t stock 0; uint32_t total 0; for(const auto [isbn,book] : m_Books){ stock book.Get_stock(); total book.Get_total(); } std::cout 图书馆统计 std::endl; std::cout 图书种类: m_Books.size() std::endl; std::cout 总藏书量: total 本 std::endl; std::cout 可借数量: stock 本 std::endl; std::cout 已借出: total- stock 本 std::endl; } // 图书 热度排行榜 ( 参考此数据热门图书增加库存冷门图书可做下架处理避免占用库存和资金 ) // value true 降序排列 value false 升序排列 void ShowBookRanking(bool value true) const { struct RankItem { std::string isbn; std::string name; uint32_t borrowed; // 借出数量 uint32_t stock; // 剩余库存 uint32_t total; // 总藏书量 }; std::vectorRankItem ranking; for(const auto [isbn,book] : m_Books){ ranking.push_back({isbn, book.GetBookName(), book.GetBorrowedCount(), book.Get_stock(), book.Get_total()}); } if (ranking.empty()) { std::cout 没有库存信息 std::endl; return; } if(value){ // 按借出数量 降序排列 std::sort(ranking.begin(), ranking.end(), [](const RankItem a,const RankItem b) { return a.borrowed b.borrowed; } ); } else { // 按借出数量 升序排列 std::sort(ranking.begin(), ranking.end(), [](const RankItem a,const RankItem b) { return a.borrowed b.borrowed; } ); } // 输出 std::cout \n 图书热度排行 std::endl; uint32_t count 1; for(const auto item : ranking){ std::cout count 借出: item.borrowed 书名: item.name 库存: item.stock / item.total ISBN: item.isbn std::endl; } } // 图书 按类型排行 void ShowBookType(const std::string type) const { struct RankItem { std::string isbn; std::string name; uint32_t borrowed; // 借出数量 uint32_t stock; // 剩余库存 uint32_t total; // 总藏书量 }; std::vectorRankItem ranking; for(const auto [isbn,book] : m_Books){ if(book.GetBookType() type) { ranking.push_back({isbn, book.GetBookName(), book.GetBorrowedCount(), book.Get_stock(), book.Get_total()}); } } if (ranking.empty()) { std::cout 该类型没有库存信息 std::endl; return; } // 按借出数量 降序排列 std::sort(ranking.begin(), ranking.end(), [](const RankItem a,const RankItem b) { return a.borrowed b.borrowed; } ); // 输出 std::cout \n 图书热度排行 std::endl; std::cout type std::endl; uint32_t count 1; for(const auto item : ranking){ std::cout count 借出: item.borrowed 书名: item.name 库存: item.stock / item.total ISBN: item.isbn std::endl; } } // 读者管理 bool AddReader(const Reader reader) { if(m_Readers.find(reader.GetId()) ! m_Readers.end()){ std::cout 读者ID reader.GetId() 已存在! std::endl; return false; } m_Readers.emplace(reader.GetId(),reader); std::cout 读者 reader.GetName() 注册成功, ID: reader.GetId() std::endl; return true; } // 已注册读者列表 void ShowAllReaders() const { for(const auto [id,reader] : m_Readers){ reader.PrintInfo(); std::cout std::endl; } } // 修改读者信息 bool ResetReaderInfo(uint32_t oldId, uint32_t newId, const std::string name,int limit) { auto it m_Readers.find(oldId); if (it m_Readers.end()) return false; uint32_t finalId (newId ! 0) ? newId : oldId; // 没改就用旧的 // 如果 ID 变了检查新 ID 是否已存在 if (finalId ! oldId m_Readers.find(finalId) ! m_Readers.end()) { std::cout 新 ID 已存在 std::endl; return false; } Reader reader it-second; reader.ResetReaderId(finalId); if (!name.empty()) reader.ResetReaderName(name); if (limit) reader.ResetReaderMaxLimit(limit); m_Readers.erase(it); m_Readers.emplace(finalId, reader); return true; } Reader* FindReader(uint32_t id){ auto it m_Readers.find(id); return it ! m_Readers.end() ? it-second : nullptr; } // 借书 bool BorrowBook(int readerId,const std::string isbn) { auto* reader FindReader(readerId); auto* book FindBook(isbn); if(!reader) { std::cout 借阅失败读者未注册 std::endl; return false; } if(!book) { std::cout 借阅失败数据库没有此书 std::endl; return false; } if(!book-BorrowOne()) { std::cout 借阅失败库存不足 std::endl; return false; } if(!reader-BorrowBook(isbn)) { book-ReturnOne(); // 读者不能借阅此书回滚库存 return false; } return true; // 成功借阅 } // 还书 bool ReturnBook(int readerId,const std::string isbn) { auto* reader FindReader(readerId); auto* book FindBook(isbn); if(!reader) { std::cout 归还失败读者未注册 std::endl; return false; } if(!book) { std::cout 归还失败数据库没有此书 std::endl; return false; } if (!reader-ReturnBook(isbn)) { return false; } book-ReturnOne(); return true; } // 按 ISBN 查询借阅记录 void ShowBookBorrowHistory(const std::string isbn) { auto* book FindBook(isbn); if(!book) { std::cout 数据库中 没有此书 std::endl; return; } std::cout 书名: book-GetBookName() 借阅记录:\n; std::cout 当前库存: book-Get_stock() / book-Get_total() std::endl; bool found false; for(const auto [id,reader] : m_Readers) { for(const auto record : reader.GetBorrowRecords()) { if(record.Isbn isbn) { found true; std::cout ID: id 读者: reader.GetName() 借阅时间: record.BorrowTime; if(record.ReturnTime.empty()) { std::cout 未归还 std::endl; } else { std::cout 归还时间: record.ReturnTime std::endl; } } } } if(!found) { std::cout 暂无借阅记录 std::endl; } } // 数据持久化 ( 存入文件 ) bool SaveToFile(const std::string booksFile BOOKFILE, const std::string readersFile READERFILE) { // 保存图书 std::ofstream bf(booksFile); if(!bf){ std::cout 无法打开 booksFile std::endl; return false; } for(const auto [isbn,book] : m_Books){ bf book.Serialize() std::endl; } bf.close(); // 保存读者和借阅记录 std::ofstream rf(readersFile); if(!rf){ std::cout 无法打开 readersFile std::endl; return false; } for(const auto [id,reader] : m_Readers){ rf reader.SerializeInfo() std::endl; auto records reader.SerializeRecords(); for(const auto rec : records){ rf rec std::endl; // 所有借阅记录 } rf std::endl; // 空行分隔不同读者的信息 } rf.close(); std::cout 数据已保存 std::endl; return true; } bool LoadFromFile(const std::string booksFile BOOKFILE, const std::string readersFile READERFILE) { // 清空现有数据 m_Books.clear(); m_Readers.clear(); // 加载图书 std::ifstream bf(booksFile); if(!bf) { std::cout 未找到 booksFile std::endl; }else { std::string line; while(std::getline(bf, line)){ if(line.empty()) continue; try { Book book Book::Deserialize(line); m_Books.emplace(book.GetBookIsbn(),book); } catch(...) { std::cout 跳过损坏的图书数据: line std::endl; } } bf.close(); } // 加载读者和借阅记录 std::ifstream rf(readersFile); if (!rf) { std::cout 未找到 readersFile std::endl; } else { std::string line; Reader* currentReader nullptr; while(std::getline(rf,line)) { if(line.empty()){ currentReader nullptr; continue; } if(line[0] R line[1] :){ try { // 解析 读者注册信息 Reader reader Reader::DeserializeInfo(line); auto [it,ok] m_Readers.emplace(reader.GetId(),reader); if(ok) { currentReader it-second; } } catch(...) { std::cout 跳过损坏的读者数据: line std::endl; currentReader nullptr; } } else if (line[0] B line[1] : currentReader) { try { // 解析 借阅记录 std::stringstream ss(line.substr(2)); // 跳过 B: std::string idStr, isbn, borrowTime, returnTime; std::getline(ss, idStr, |); std::getline(ss, isbn, |); std::getline(ss, borrowTime, |); std::getline(ss, returnTime, |); BorrowRecord record(isbn, borrowTime); record.ReturnTime returnTime; currentReader-AddBorrowRecord(record); } catch(...) { std::cout 跳过损坏的借阅记录: line std::endl; } } } rf.close(); } std::cout 数据加载完成 std::endl; ShowStatistics(); return true; } }; std::string SafeInputString(const std::string prompt) { std::string line; std::cout prompt; std::getline(std::cin, line); return line; } // 带确认的字符串输入 std::string SafeInputStringConfirm(const std::string prompt) { while (true) { std::string line SafeInputString(prompt); std::cout 输入: \ line \ 确认? (y/n): ; std::string confirm; std::getline(std::cin, confirm); if (confirm y || confirm Y || confirm.empty()) { return line; } std::cout 请重新输入 std::endl; } } uint32_t SafeInputNum(const std::string prompt) { while(true){ std::cout prompt; std::string line; std::getline(std::cin, line); try{ unsigned long value std::stoul(line); // string → unsigned long return static_castuint32_t(value); // unsigned long → uint32_t } catch(...){ // 如果转换失败了跳到这里执行 std::cout 输入无效请输入整数 std::endl; } } } // 带确认的数字输入 uint32_t SafeInputNumConfirm(const std::string prompt) { while (true) { uint32_t value SafeInputNum(prompt); std::cout 输入: value 确认? (y/n): ; std::string confirm; std::getline(std::cin, confirm); if (confirm y || confirm Y || confirm.empty()) { return value; } std::cout 请重新输入 std::endl; } } void CmdlineAddBook(LibraryManager lib) { std::string isbn SafeInputStringConfirm(ISBN:); if (lib.FindBook(isbn)) { std::cout 该 ISBN 已存在 std::endl; return; } std::string name SafeInputStringConfirm(书名:); std::string author SafeInputStringConfirm(作者:); std::string type SafeInputStringConfirm(类型:); uint32_t stock SafeInputNumConfirm(库存:); lib.AddBook(isbn, name, author, type, stock); } void CmdlineAddBookStock(LibraryManager lib) { std::string isbn SafeInputStringConfirm(ISBN:); uint32_t count SafeInputNumConfirm(数量:); lib.AddBookStock(isbn,count); } void CmdlineRemoveBookStock(LibraryManager lib) { std::string isbn SafeInputStringConfirm(ISBN:); uint32_t count SafeInputNumConfirm(数量:); lib.RemoveBookStock(isbn,count); } void CmdlineResetBookInfo(LibraryManager lib) { std::string oldIsbn SafeInputStringConfirm(ISBN:); Book* book lib.FindBook(oldIsbn); if(!book) { std::cout 数据库没有此书! std::endl; return; } book-PrintBookInfo(); std::cout std::endl; std::cout ( 回车保留原值输入新值覆盖 ) std::endl; std::string newIsbn SafeInputStringConfirm(set ISBN:); std::string name SafeInputStringConfirm(set 书名:); std::string author SafeInputStringConfirm(set 作者:); std::string type SafeInputStringConfirm(set 类型:); lib.ResetBookInfo(oldIsbn, newIsbn, name, author, type); std::cout 图书信息 修改完成 std::endl; } void CmdlineAddReader(LibraryManager lib) { uint32_t id SafeInputNumConfirm(读者ID:); if (lib.FindReader(id)) { std::cout 该 ID 已存在 std::endl; return; } std::string name SafeInputStringConfirm(姓名:); int limit SafeInputNumConfirm(最大借阅数:); lib.AddReader(Reader(id, name, limit)); } void CmdlineResetReaderInfo(LibraryManager lib) { uint32_t oldId SafeInputNumConfirm(读者ID:); Reader* reader lib.FindReader(oldId); if(!reader) { std::cout 读者未注册! std::endl; return; } reader-PrintReaderInfo(); std::cout std::endl; std::cout ( 回车保留原值输入新值覆盖 ) std::endl; uint32_t newId SafeInputNumConfirm(set ID:); std::string name SafeInputStringConfirm(set 姓名:); int limit SafeInputNumConfirm(set 最大借阅数:); lib.ResetReaderInfo(oldId, newId, name, limit); std::cout 读者信息 修改完成 std::endl; } void CmdlineBorrowBook(LibraryManager lib) { int readerId SafeInputNumConfirm(读者ID:); std::string isbn SafeInputStringConfirm(ISBN:); lib.BorrowBook(readerId,isbn); } void CmdlineReturnBook(LibraryManager lib) { int readerId SafeInputNumConfirm(读者ID:); std::string isbn SafeInputStringConfirm(ISBN:); lib.ReturnBook(readerId,isbn); } void CmdlineShowBookRanking(LibraryManager lib) { std::string choice SafeInputStringConfirm(降序:y 升序:n ); lib.ShowBookRanking(choice ! n); } void CmdlineShowBookType(LibraryManager lib) { std::string type SafeInputStringConfirm(图书类型:); lib.ShowBookType(type); } void CmdlineShowBookHistory(LibraryManager lib) { std::string isbn SafeInputStringConfirm(ISBN:); lib.ShowBookBorrowHistory(isbn); } void CmdlineSave(LibraryManager lib) { lib.SaveToFile(); } void CmdlineLoad(LibraryManager lib) { std::string confirm SafeInputStringConfirm(加载数据会清空当前未保存的数据确认加载? (y/n): ); if (confirm y || confirm Y) { lib.LoadFromFile(); } else { std::cout 已取消加载操作 std::endl; } } volatile sig_atomic_t stop 0; void handle_sigint(int sig) { stop 1; } int main(int argc,char* argv[]) { #if 1 // 命令行 交互输入 LibraryManager lib; lib.LoadFromFile(); // 启动时自动加载 图书信息/读者信息/借阅信息 /* 捕获 CtrlC 信号 */ signal(SIGINT, handle_sigint); signal(SIGTERM, handle_sigint); int choice; while(!stop){ std::cout std::endl; std::cout 图书管理系统 std::endl; std::cout 1.添加图书 2.修改图书 3.入库 4.下架 5.图书列表 6.统计 std::endl; std::cout 7.读者注册 8.修改读者 9.借书 10.还书 11.读者列表 12.图书排行榜 std::endl; std::cout 13.分类排行 14.保存数据 15.加载数据 16.图书借阅记录 0.退出 std::endl; choice SafeInputNum(请选择: ); switch(choice) { case 0: { std::string saveChoice SafeInputStringConfirm(退出前保存数据? (y/n): ); if (saveChoice y || saveChoice Y) { lib.SaveToFile(); } stop 1; break; } case 1: CmdlineAddBook(lib); break; case 2: CmdlineResetBookInfo(lib); break; case 3: CmdlineAddBookStock(lib); break; case 4: CmdlineRemoveBookStock(lib); break; case 5: lib.ShowAllBooks(); break; case 6: lib.ShowStatistics(); break; case 7: CmdlineAddReader(lib); break; case 8: CmdlineResetReaderInfo(lib); break; case 9: CmdlineBorrowBook(lib); break; case 10: CmdlineReturnBook(lib); break; case 11: lib.ShowAllReaders(); break; case 12: CmdlineShowBookRanking(lib); break; case 13: CmdlineShowBookType(lib); break; case 14: CmdlineSave(lib); break; case 15: CmdlineLoad(lib); break; case 16: CmdlineShowBookHistory(lib); break; default: std::cout 无效选项 std::endl; } } std::cout 已退出程序 std::endl; return 0; #else // 测试 LibraryManager lib; // 单本添加便捷 lib.AddBook(978-7-115-49250-0, C Primer Plus, Stephen Prata, 计算机, 50); lib.AddBook(978-7-115-49250-1, C Primer Plus, Stephen Prata, 计算机, 100); lib.ShowStatistics(); // 批量添加 lib.AddBooks({ {978-7-111-40701-4, Effective Modern C, Scott Meyers, 计算机, 20}, {978-0-13-110362-7, The C Programming Language, Brian Kernighan, 计算机, 15}, {978-7-302-15398-2, Design Patterns, GoF, 计算机, 10}, }); lib.ShowStatistics(); lib.AddReader(Reader(1,leo,10)); lib.AddReader(Reader(2,qq,10)); lib.ShowAllBooks(); // 借书 lib.BorrowBook(1,978-7-111-40701-4); lib.BorrowBook(2,978-7-115-49250-1); lib.BorrowBook(2,978-0-13-110362-7); lib.BorrowBook(2,978-7-115-49250-0); lib.ShowAllBooks(); // 还书 lib.ReturnBook(1,978-7-111-40701-4); lib.ReturnBook(2,978-7-115-49250-1); lib.ShowAllBooks(); lib.ShowAllReaders(); lib.ShowStatistics(); #endif }pch.h 代码#pragma once #include iostream // cin, cout #include string // string #include vector // vector #include fstream // ifstream, ofstream #include sstream // stringstream #include algorithm // sort, find #include map // map #include ctime // time, localtime #include iomanip // put_time #include csignal // signal