#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
// --- CẤU TRÚC DỮ LIỆU ---
struct Book {
string title, author;
int year, quantity;
};
struct Member {
string name, address, phone, type; // "librarian" hoặc "member"
};
struct BorrowRecord {
Book book; // Lưu thông tin sách tại thời điểm mượn
Member member; // Lưu thông tin người mượn
string borrow_date, return_date;
int extended; // Số lần gia hạn
};
// --- HÀM TIỆN ÍCH (HELPER FUNCTIONS) ---
// Hàm nhập chuỗi nhanh
string input(string prompt) {
cout << prompt;
string s;
getline(cin, s);
return s;
// Hàm nhập số an toàn
int inputInt(string prompt) {
cout << prompt;
int n;
cin >> n;
[Link](); // Xóa bộ đệm để không bị trôi lệnh getline phía sau
return n;
// --- KHAI BÁO HÀM (PROTOTYPES) ---
string login(const vector<Member>& members, string role);
void registerMember(vector<Member>& members);
void librarianMenu(vector<Book>& books, vector<Member>& members, vector<BorrowRecord>&
records);
void memberMenu(const vector<BorrowRecord>& records, const vector<Book>& books, const
string& memberName);
void modifyBook(vector<Book>& books, bool isAdd);
void removeBook(vector<Book>& books);
void modifyMember(vector<Member>& members, bool isAdd);
void removeMember(vector<Member>& members);
void processBorrowReturn(vector<BorrowRecord>& records, vector<Book>& books, const
vector<Member>& members, bool isBorrow);
void displayBooks(const vector<Book>& books, bool onlyAvailable);
void displayRecords(const vector<BorrowRecord>& records, string filterMember = "");
void extendBorrowPeriod(vector<BorrowRecord>& records);
void generateStatistics(const vector<BorrowRecord>& records);
void searchData(const vector<Book>& books, const vector<Member>& members, bool
searchBook);
// --- MAIN FUNCTION ---
int main() {
vector<Book> books;
vector<Member> members;
vector<BorrowRecord> records;
// Dữ liệu mẫu
members.push_back({"Librarian1", "Hanoi", "090123456", "librarian"});
members.push_back({"Member1", "HCM", "090999999", "member"});
books.push_back({"C++ Programming", "Stroustrup", 2013, 5});
while (true) {
cout << "\n=== LIBRARY SYSTEM ===\n";
cout << "1. Login as Librarian\n2. Login as Member\n3. Register New Member\n4. Exit\n";
int choice = inputInt("Enter choice: ");
if (choice == 1 || choice == 2) {
// Xác định vai trò muốn đăng nhập
string role = (choice == 1) ? "librarian" : "member";
// Hàm login trả về Tên người dùng nếu thành công
string loggedInName = login(members, role);
if (![Link]()) {
cout << "Login successful! Welcome " << loggedInName << ".\n";
// FIX LỖI: Kiểm tra role để mở menu tương ứng
if (role == "librarian") {
librarianMenu(books, members, records);
} else {
memberMenu(records, books, loggedInName);
else if (choice == 3) {
registerMember(members);
else if (choice == 4) {
cout << "Goodbye!\n";
break;
else {
cout << "Invalid choice.\n";
return 0;
}
// --- TRIỂN KHAI CÁC HÀM ---
string login(const vector<Member>& members, string role) {
string name = input("Enter username (" + role + "): ");
for (const auto& m : members) {
if ([Link] == name && [Link] == role) {
return [Link]; // Trả về tên nếu tìm thấy đúng người đúng quyền
cout << "User not found or wrong role type.\n";
return "";
void registerMember(vector<Member>& members) {
Member m;
cout << "\n--- Register ---\n";
[Link] = input("Enter name: ");
[Link] = input("Enter address: ");
[Link] = input("Enter phone: ");
[Link] = input("Enter type (librarian/member): ");
members.push_back(m);
cout << "Registered successfully.\n";
void librarianMenu(vector<Book>& books, vector<Member>& members, vector<BorrowRecord>&
records) {
int choice;
do {
cout << "\n--- LIBRARIAN MENU ---\n";
cout << "1. Add Book\t\t2. Remove Book\t\t3. Update Book\n";
cout << "4. Add Member\t\t5. Remove Member\t6. Update Member\n";
cout << "7. Borrow Book\t\t8. Return Book\t\t9. View Borrowed Books\n";
cout << "10. View Available Books\t11. Extend Borrow\t12. Statistics\n";
cout << "13. Search Book\t\t14. Search Member\t15. Logout\n";
choice = inputInt("Select function: ");
switch (choice) {
case 1: modifyBook(books, true); break;
case 2: removeBook(books); break;
case 3: modifyBook(books, false); break;
case 4: modifyMember(members, true); break;
case 5: removeMember(members); break;
case 6: modifyMember(members, false); break;
case 7: processBorrowReturn(records, books, members, true); break;
case 8: processBorrowReturn(records, books, members, false); break;
case 9: displayRecords(records); break;
case 10: displayBooks(books, true); break;
case 11: extendBorrowPeriod(records); break;
case 12: generateStatistics(records); break;
case 13: searchData(books, members, true); break;
case 14: searchData(books, members, false); break;
case 15: cout << "Logging out...\n"; break;
default: cout << "Invalid choice.\n";
}
} while (choice != 15);
void memberMenu(const vector<BorrowRecord>& records, const vector<Book>& books, const
string& memberName) {
int choice;
do {
cout << "\n--- MEMBER MENU (" << memberName << ") ---\n";
cout << "1. My Borrowed Books\n2. View All Available Books\n3. Logout\n";
choice = inputInt("Select function: ");
if (choice == 1) {
displayRecords(records, memberName);
} else if (choice == 2) {
displayBooks(books, true);
} else if (choice == 3) {
cout << "Logging out...\n";
} else {
cout << "Invalid choice.\n";
} while (choice != 3);
// Gộp chức năng Add và Update Book
void modifyBook(vector<Book>& books, bool isAdd) {
string title = input(isAdd ? "Enter new book title: " : "Enter title of book to update: ");
for (auto& b : books) {
if ([Link] == title) {
if (isAdd) {
cout << "Error: Book already exists.\n";
return;
// Update logic
cout << "Found book. Enter new info:\n";
[Link] = input("New title: ");
[Link] = input("New author: ");
[Link] = inputInt("New year: ");
[Link] = inputInt("New quantity: ");
cout << "Book updated.\n";
return;
if (isAdd) {
Book b; [Link] = title;
[Link] = input("Author: ");
[Link] = inputInt("Year: ");
[Link] = inputInt("Quantity: ");
books.push_back(b);
cout << "Book added.\n";
} else {
cout << "Book not found.\n";
}
void removeBook(vector<Book>& books) {
string t = input("Enter title to remove: ");
auto it = remove_if([Link](), [Link](), [&](const Book& b){ return [Link] == t; });
if (it != [Link]()) {
[Link](it, [Link]());
cout << "Book removed.\n";
} else {
cout << "Book not found.\n";
// Gộp chức năng Add và Update Member
void modifyMember(vector<Member>& members, bool isAdd) {
if (isAdd) {
registerMember(members);
return;
string name = input("Enter member name to update: ");
for (auto& m : members) {
if ([Link] == name) {
[Link] = input("New name: ");
[Link] = input("New address: ");
[Link] = input("New phone: ");
[Link] = input("New type (librarian/member): ");
cout << "Member updated.\n";
return;
cout << "Member not found.\n";
void removeMember(vector<Member>& members) {
string n = input("Enter name to remove: ");
auto it = remove_if([Link](), [Link](), [&](const Member& m){ return [Link]
== n; });
if (it != [Link]()) {
[Link](it, [Link]());
cout << "Member removed.\n";
} else {
cout << "Member not found.\n";
// Xử lý Mượn (isBorrow=true) và Trả (isBorrow=false)
void processBorrowReturn(vector<BorrowRecord>& records, vector<Book>& books, const
vector<Member>& members, bool isBorrow) {
string bTitle = input("Book title: ");
string mName = input("Member name: ");
string date = input(isBorrow ? "Borrow date (YYYY-MM-DD): " : "Return date (YYYY-MM-DD): ");
if (isBorrow) {
auto bit = find_if([Link](), [Link](), [&](Book& b){ return [Link] == bTitle; });
auto mit = find_if([Link](), [Link](), [&](const Member& m){ return [Link]
== mName; });
if (bit != [Link]() && mit != [Link]() && bit->quantity > 0) {
BorrowRecord rec;
[Link] = *bit;
[Link] = *mit;
rec.borrow_date = date;
[Link] = 0;
records.push_back(rec);
bit->quantity--; // Giảm số lượng sách
cout << "Book borrowed successfully.\n";
} else {
cout << "Error: Book unavailable (qty=0) or Member/Book not found.\n";
} else {
// Logic Trả sách
auto rit = find_if([Link](), [Link](), [&](BorrowRecord& r){
return [Link] == bTitle && [Link] == mName && r.return_date.empty();
});
if (rit != [Link]()) {
rit->return_date = date;
// Tăng số lượng sách trong kho
auto bit = find_if([Link](), [Link](), [&](Book& b){ return [Link] == bTitle; });
if (bit != [Link]()) {
bit->quantity++;
cout << "Book returned successfully.\n";
} else {
cout << "No active borrow record found for this book and member.\n";
void displayRecords(const vector<BorrowRecord>& records, string filterMember) {
cout << "\n--- BORROW RECORDS ---\n";
bool found = false;
for (const auto& r : records) {
// Nếu filterMember rỗng (Librarian xem tất cả) HOẶC tên khớp (Member xem của mình)
// VÀ sách chưa trả
if (([Link]() || [Link] == filterMember) && r.return_date.empty()) {
cout << "[Book]: " << [Link]
<< " | [Borrower]: " << [Link]
<< " | [Date]: " << r.borrow_date << "\n";
found = true;
if (!found) cout << "(No active borrow records found)\n";
void displayBooks(const vector<Book>& books, bool onlyAvailable) {
cout << "\n--- BOOK LIST ---\n";
for (const auto& b : books) {
if (!onlyAvailable || [Link] > 0) {
cout << "Title: " << [Link]
<< " | Author: " << [Link]
<< " | Year: " << [Link]
<< " | Qty: " << [Link] << "\n";
void extendBorrowPeriod(vector<BorrowRecord>& records) {
string bTitle = input("Book title: ");
string mName = input("Member name: ");
for (auto& r : records) {
if ([Link] == bTitle && [Link] == mName && r.return_date.empty()) {
if ([Link] < 2) {
[Link]++;
cout << "Extended successfully. Total extensions: " << [Link] << "/2\n";
} else {
cout << "Cannot extend more than 2 times.\n";
return;
cout << "Record not found.\n";
}
void generateStatistics(const vector<BorrowRecord>& records) {
map<string, int> counts;
for (const auto& r : records) {
counts[[Link]]++;
cout << "\n--- STATISTICS (Total Borrows per Book) ---\n";
for (auto const& [title, count] : counts) {
cout << title << ": " << count << " time(s)\n";
void searchData(const vector<Book>& books, const vector<Member>& members, bool searchBook)
{
string kw = input("Enter keyword to search: ");
bool found = false;
if (searchBook) {
for (const auto& b : books) {
if ([Link](kw) != string::npos) {
cout << "Found Book: " << [Link] << " (" << [Link] << ")\n";
found = true;
} else {
for (const auto& m : members) {
if ([Link](kw) != string::npos) {
cout << "Found Member: " << [Link] << " (" << [Link] << ")\n";
found = true;
if (!found) cout << "No results found.\n";