news 2026/7/17 21:40:48

C++ 图书管理系统--单机版 ( 约 1000行 代码 )

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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::vector<BorrowRecord> 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::vector<std::string> GetCurrentBorrowedISBNs() const{ std::vector<std::string> isbns; for(const auto& record : m_BorrowRecords){ if(record.ReturnTime.empty()){ isbns.emplace_back(record.Isbn); } } return isbns; } // 获取所有借阅记录 const std::vector<BorrowRecord>& 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::vector<std::string> SerializeRecords() const { std::vector<std::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::map<std::string, Book> m_Books; // ISBN -> Book std::map<int,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_list<Book> 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::vector<RankItem> 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::vector<RankItem> 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_cast<uint32_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(); // 启动时自动加载 图书信息/读者信息/借阅信息 /* 捕获 Ctrl+C 信号 */ 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
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 21:40:44

临时设计方案

架构设计 采用"内核布局 全局共享模块 独立应用外壳"的模块化系统。超级管理员通过配置组合模块生成独立应用&#xff0c;每个应用拥有专属侧边栏与布局&#xff0c;确保不污染原版代码&#xff0c;支持平滑升级与渐进式扩展。 存储方案 所有动态配置与映射…

作者头像 李华
网站建设 2026/7/17 21:40:17

从VC++运行库到现代C++开发:解决兼容性难题与生态演进

1. 从一本经典书籍出发&#xff0c;聊聊Visual C的过去、现在与未来提到《Visual C从入门到精通》这本书&#xff0c;尤其是它的第三版&#xff0c;我相信很多在Windows平台上摸爬滚打多年的C开发者&#xff0c;都会会心一笑。这本书&#xff0c;连同那个经典的Visual C 6.0开发…

作者头像 李华
网站建设 2026/7/17 21:36:11

C语言:打印菱形(作业考试学习必备系列007)

用C语言在屏幕上输出以下图案&#xff1a;#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>void chongzhi(char arr[13]){int a 0;for (a 0;a < 12;a){arr[a] ;}}void dayin(char arr[13]){int a 0;for (a 0;a < 12;a){printf("%c", arr[a]);}p…

作者头像 李华
网站建设 2026/7/17 21:24:36

【python】函数详解

目录 一、函数 1.1 函数是什么 1.2 语法格式 1.3 函数参数 1.4 函数的返回值 1.5 变量作用域 1.6 函数的执行过程 1.7 链式调用 1.8 嵌套调用 1.9 函数递归 1.10 参数默认值 1.11 关键字参数 1.12 小结 一、函数 1.1 函数是什么 编程中的函数和数学中的函数有一定…

作者头像 李华