#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cctype>
#include <sstream>
#include <ctime>
using namespace std;
// 1. CAU TRUC DU LIEU
struct Nguoimuon {
string Tennguoi;
string Ngaymuon;
string Hantra;
};
struct Sach {
int Id;
string Tensach;
string Tacgia;
string Theloai;
int Soluong;
vector<Nguoimuon> Dsmuon;
};
vector<Sach> Khosach;
vector<Sach> Thungrac;
// 2. CAC HAM HO TRO (TIEN ICH)
// Ham nhap so nguyen an toan (chong trôi lenh)
int Nhapsonguyen(string Thongbao) {
int n;
while (true) {
cout << Thongbao;
if (cin >> n) {
[Link](32767, '\n');
return n;
} else {
cout << "LOI: Dinh dang khong hop le! Vui long nhap SO." << endl;
[Link]();
[Link](32767, '\n');
string Inttostring(int a) {
stringstream ss;
ss << a;
return [Link]();
string Chuyenvechuthuong(string str) {
string Ketqua = str;
for (size_t i = 0; i < [Link](); i++) {
Ketqua[i] = tolower(Ketqua[i]);
return Ketqua;
bool Sosanhid(const Sach& a, const Sach& b) {
return [Link] < [Link];
// Ten ham dong nhat: Sapxepsach (Viet hoa chu S dau)
void Sapxepsach() {
sort([Link](), [Link](), Sosanhid);
// --- XU LY NGAY THANG & KIEM TRA LOI ---
bool Kiemtranamnhuan(int y) {
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
// Ham kiem tra ngay hop le (DA SUA: Chap nhan 1/1/2026)
bool Kiemtrangayhople(string s) {
int d, m, y;
char sep1, sep2;
stringstream ss(s);
ss >> d >> sep1 >> m >> sep2 >> y;
// Kiem tra xem co tach duoc so khong va dau phan cach co phai '/' khong
if ([Link]() || sep1 != '/' || sep2 != '/') return false;
if (y < 1900 || y > 3000) return false;
if (m < 1 || m > 12) return false;
int Ngaytrongthang[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (Kiemtranamnhuan(y)) Ngaytrongthang[2] = 29;
if (d < 1 || d > Ngaytrongthang[m]) return false;
return true;
string Nhapngaychuan(string Thongbao) {
string Ngay;
while (true) {
cout << Thongbao;
getline(cin, Ngay);
if (Kiemtrangayhople(Ngay)) {
return Ngay;
} else {
cout << "LOI: Ngay khong hop le (dd/mm/yyyy) hoac khong ton tai! Vui long nhap lai." << endl;
tm Chuyenchuoisangtime(string Ngaystr) {
tm Timestruct = {};
int d, m, y;
char delimiter;
stringstream ss(Ngaystr);
ss >> d >> delimiter >> m >> delimiter >> y;
Timestruct.tm_mday = d;
Timestruct.tm_mon = m - 1;
Timestruct.tm_year = y - 1900;
Timestruct.tm_isdst = -1;
return Timestruct;
string Congngay(string Ngaystr, int Songaycong) {
tm Timestruct = Chuyenchuoisangtime(Ngaystr);
time_t rawTime = mktime(&Timestruct);
rawTime += Songaycong * 24 * 60 * 60;
tm* Timenew = localtime(&rawTime);
stringstream ss;
ss << (Timenew->tm_mday < 10 ? "0" : "") << Timenew->tm_mday << "/"
<< (Timenew->tm_mon + 1 < 10 ? "0" : "") << Timenew->tm_mon + 1 << "/"
<< Timenew->tm_year + 1900;
return [Link]();
int Tinhsongaytre(string Hantra, string Ngaytrathucte) {
tm Tmhan = Chuyenchuoisangtime(Hantra);
tm Tmthuc = Chuyenchuoisangtime(Ngaytrathucte);
time_t tHan = mktime(&Tmhan);
time_t tThuc = mktime(&Tmthuc);
double seconds = difftime(tThuc, tHan);
return seconds / (60 * 60 * 24);
}
// 3. XU LY FILE
void Luuvectorvaofile(const vector<Sach>& v, string Tenfile) {
ofstream f(Tenfile.c_str());
if (f.is_open()) {
f << [Link]() << endl;
for (size_t i = 0; i < [Link](); i++) {
f << v[i].Id << endl;
f << v[i].Tensach << endl;
f << v[i].Tacgia << endl;
f << v[i].Theloai << endl;
f << v[i].Soluong << endl;
f << v[i].[Link]() << endl;
for (size_t j = 0; j < v[i].[Link](); j++) {
f << v[i].Dsmuon[j].Tennguoi << endl;
f << v[i].Dsmuon[j].Ngaymuon << endl;
f << v[i].Dsmuon[j].Hantra << endl;
[Link]();
void Docvectortufile(vector<Sach>& v, string Tenfile) {
ifstream f(Tenfile.c_str());
if (f.is_open()) {
int n;
f >> n;
[Link]();
for (int i = 0; i < n; i++) {
Sach s;
f >> [Link];
[Link]();
getline(f, [Link]);
getline(f, [Link]);
getline(f, [Link]);
f >> [Link];
int Songuoimuon;
f >> Songuoimuon;
[Link]();
for (int j = 0; j < Songuoimuon; j++) {
Nguoimuon nm;
getline(f, [Link]);
getline(f, [Link]);
getline(f, [Link]);
[Link].push_back(nm);
v.push_back(s);
[Link]();
void Luudulieu() {
Luuvectorvaofile(Khosach, "[Link]");
Luuvectorvaofile(Thungrac, "[Link]");
}
void Taidulieu() {
Docvectortufile(Khosach, "[Link]");
Docvectortufile(Thungrac, "[Link]");
// 4. CAC CHUC NANG CHINH
void Taodulieumacdinh() {
if (![Link]()) return;
cout << "\n[KHOI TAO] Tao du lieu mau..." << endl;
Sach s1; [Link] = 105; [Link] = "Doraemon"; [Link] = "Fujiko F"; [Link] = "Truyen Tranh";
[Link] = 5; Khosach.push_back(s1);
Sach s2; [Link] = 101; [Link] = "Mat Biec"; [Link] = "Nguyen Nhat Anh"; [Link] = "Lang
Man"; [Link] = 4; Khosach.push_back(s2);
Sach s3; [Link] = 103; [Link] = "Conan"; [Link] = "Gosho Aoyama"; [Link] = "Trinh Tham";
[Link] = 3; Khosach.push_back(s3);
Sapxepsach(); // Goi dung ten ham
Luudulieu();
void Hienthitatcasach() {
cout << "\n============================== DANH SACH KHO SACH
==============================" << endl;
cout << left << setw(10) << "ID" << setw(30) << "Ten Sach" << setw(20) << "Tac Gia" << setw(15) <<
"The Loai" << setw(5) << "SL" << endl;
cout << "--------------------------------------------------------------------------------" << endl;
for (size_t i = 0; i < [Link](); i++) {
cout << left << setw(10) << Khosach[i].Id << setw(30) << Khosach[i].Tensach
<< setw(20) << Khosach[i].Tacgia << setw(15) << Khosach[i].Theloai
<< setw(5) << Khosach[i].Soluong << endl;
cout << "--------------------------------------------------------------------------------" << endl;
void Hienthisachdangmuon() {
cout << "\n========================== SACH DANG DUOC MUON ========================="
<< endl;
bool Cosachmuon = false;
for (size_t i = 0; i < [Link](); i++) {
if (!Khosach[i].[Link]()) {
Cosachmuon = true;
cout << "+ SACH: [" << Khosach[i].Id << "] " << Khosach[i].Tensach
<< " (Dang muon: " << Khosach[i].[Link]() << ")" << endl;
for (size_t j = 0; j < Khosach[i].[Link](); j++) {
cout << " - " << Khosach[i].Dsmuon[j].Tennguoi
<< " | Han: " << Khosach[i].Dsmuon[j].Hantra << endl;
if (!Cosachmuon) cout << "Chua co sach nao duoc muon!" << endl;
void Hienthisach() {
int Luachon = Nhapsonguyen("\n--- CHON CHE DO HIEN THI ---\n1. Tat ca sach\n2. Sach dang muon\
nChon: ");
if (Luachon == 1) Hienthitatcasach();
else if (Luachon == 2) Hienthisachdangmuon();
else cout << "Lua chon khong hop le!" << endl;
void Timkiemsach() {
cout << "\n=== TIM KIEM SACH ===" << endl;
cout << "1. Tim theo Tu khoa (Ten, ID, Tac gia)" << endl;
cout << "2. Tim theo The loai" << endl;
int Kieutim = Nhapsonguyen("Chon cach tim: ");
string Tukhoa;
cout << "Nhap tu khoa tim kiem: ";
getline(cin, Tukhoa);
string Tukhoathuong = Chuyenvechuthuong(Tukhoa);
bool Timthay = false;
cout << "\n=== KET QUA TIM KIEM ===" << endl;
if (Kieutim == 2) {
cout << left << setw(10) << "ID" << setw(30) << "Ten Sach" << setw(20) << "The Loai" << setw(5) <<
"SL" << endl;
} else {
cout << left << setw(10) << "ID" << setw(30) << "Ten Sach" << setw(20) << "Tac Gia" << setw(5) <<
"SL" << endl;
cout << "----------------------------------------------------------------------" << endl;
for (size_t i = 0; i < [Link](); i++) {
bool Match = false;
if (Kieutim == 1) {
string Tensach = Chuyenvechuthuong(Khosach[i].Tensach);
string Tacgia = Chuyenvechuthuong(Khosach[i].Tacgia);
string Idsach = Inttostring(Khosach[i].Id);
if ([Link](Tukhoathuong) != string::npos || [Link](Tukhoa) != string::npos ||
[Link](Tukhoathuong) != string::npos) {
Match = true;
} else if (Kieutim == 2) {
string Theloai = Chuyenvechuthuong(Khosach[i].Theloai);
if ([Link](Tukhoathuong) != string::npos) {
Match = true;
if (Match) {
if (Kieutim == 2) {
cout << left << setw(10) << Khosach[i].Id
<< setw(30) << Khosach[i].Tensach
<< setw(20) << Khosach[i].Theloai
<< setw(5) << Khosach[i].Soluong << endl;
} else {
cout << left << setw(10) << Khosach[i].Id
<< setw(30) << Khosach[i].Tensach
<< setw(20) << Khosach[i].Tacgia
<< setw(5) << Khosach[i].Soluong << endl;
Timthay = true;
}
}
if (!Timthay) cout << "Khong tim thay ket qua nao phu hop!" << endl;
void Themsach() {
Sach s; cout << "\n--- THEM SACH ---" << endl;
[Link] = Nhapsonguyen("Nhap ID: ");
for (size_t i = 0; i < [Link](); i++) { if (Khosach[i].Id == [Link]) { cout << "Loi: ID trung!" << endl;
return; } }
cout << "Ten sach: "; getline(cin, [Link]);
cout << "Tac gia: "; getline(cin, [Link]);
cout << "The loai: "; getline(cin, [Link]);
[Link] = Nhapsonguyen("So luong: ");
Khosach.push_back(s);
Sapxepsach(); Luudulieu(); cout << "Them thanh cong!" << endl;
void Muonsach() {
int Id = Nhapsonguyen("\nNhap ID muon: ");
for (size_t i = 0; i < [Link](); i++) {
if (Khosach[i].Id == Id) {
if (Khosach[i].Soluong > 0) {
Nguoimuon nm;
cout << "Ten nguoi muon: "; getline(cin, [Link]);
// --- SU DUNG HAM NHAP NGAY CHUAN ---
[Link] = Nhapngaychuan("Ngay muon (dd/mm/yyyy): ");
[Link] = Congngay([Link], 7);
cout << "-> Han tra: " << [Link] << endl;
Khosach[i].Soluong--;
Khosach[i].Dsmuon.push_back(nm);
Luudulieu(); cout << "Muon thanh cong!" << endl;
} else cout << "Het hang!" << endl;
return;
cout << "Sai ID!" << endl;
void Trasach() {
cout << "\n=== TRA SACH ===" << endl;
string Tukhoa; cout << "Nhap ID/Ten: "; getline(cin, Tukhoa);
string Lowerk = Chuyenvechuthuong(Tukhoa);
for(size_t i=0; i<[Link](); i++) {
if(Inttostring(Khosach[i].Id)==Tukhoa || Chuyenvechuthuong(Khosach[i].Tensach).find(Lowerk)!
=string::npos) {
if(Khosach[i].[Link]()) { cout << "Sach nay khong ai muon.\n"; return; }
cout << "Dang muon: " << Khosach[i].Tensach << endl;
for(size_t j=0; j<Khosach[i].[Link](); j++)
cout << j+1 << ". " << Khosach[i].Dsmuon[j].Tennguoi << " (Han: " <<
Khosach[i].Dsmuon[j].Hantra << ")\n";
int Stt = Nhapsonguyen("Chon STT tra (0 huy): ");
if(Stt>0 && Stt<=(int)Khosach[i].[Link]()) {
// --- SU DUNG HAM NHAP NGAY CHUAN ---
string Ngaytra = Nhapngaychuan("Ngay tra thuc te (dd/mm/yyyy): ");
int Tre = Tinhsongaytre(Khosach[i].Dsmuon[Stt-1].Hantra, Ngaytra);
if(Tre>0) cout << "PHAT QUA HAN: " << Tre*10000 << "d\n";
Khosach[i].[Link](Khosach[i].[Link]()+(Stt-1));
Khosach[i].Soluong++;
Luudulieu(); cout << "Tra thanh cong!\n";
return;
cout << "Khong tim thay!\n";
void Xoasach() {
int Id = Nhapsonguyen("\n--- XOA SACH ---\nNhap ID can xoa: ");
for (size_t i = 0; i < [Link](); i++) {
if (Khosach[i].Id == Id) {
cout << "Tim thay: " << Khosach[i].Tensach << " (SL: " << Khosach[i].Soluong << ")" << endl;
cout << "1. Giam so luong sach" << endl;
cout << "2. Xoa HAN khoi thu vien (Chuyen vao thung rac)" << endl;
cout << "0. Huy" << endl;
int Chon = Nhapsonguyen("Chon: ");
if (Chon == 1) {
int Slgiam = Nhapsonguyen("Nhap so luong muon bo bot: ");
if (Slgiam > 0 && Slgiam <= Khosach[i].Soluong) {
Khosach[i].Soluong -= Slgiam;
Luudulieu();
cout << "Da giam so luong! Con lai: " << Khosach[i].Soluong << endl;
} else {
cout << "So luong nhap khong hop le!" << endl;
} else if (Chon == 2) {
if (!Khosach[i].[Link]()) {
cout << "LOI: Khong the xoa vi dang co nguoi muon!" << endl; return;
Thungrac.push_back(Khosach[i]);
[Link]([Link]() + i);
Luudulieu();
cout << "Da chuyen sach vao Thung Rac. Ban co the khoi phuc sau." << endl;
return;
cout << "Khong tim thay ID!" << endl;
void Khoiphucsach() {
if ([Link]()) {
cout << "\n[THONG BAO] Thung rac trong!" << endl; return;
cout << "\n================= THUNG RAC =================" << endl;
cout << left << setw(10) << "ID" << setw(30) << "Ten Sach" << setw(20) << "Tac Gia" << endl;
cout << "-----------------------------------------------------------" << endl;
for (size_t i = 0; i < [Link](); i++) {
cout << left << setw(10) << Thungrac[i].Id
<< setw(30) << Thungrac[i].Tensach
<< setw(20) << Thungrac[i].Tacgia << endl;
cout << "-----------------------------------------------------------" << endl;
int Id = Nhapsonguyen("Nhap ID khoi phuc (0 de huy): ");
if (Id == 0) return;
for (size_t i = 0; i < [Link](); i++) {
if (Thungrac[i].Id == Id) {
for (size_t j = 0; j < [Link](); j++) {
if (Khosach[j].Id == Id) {
cout << "LOI: ID " << Id << " da ton tai trong kho (Trung ID)." << endl;
return;
Khosach.push_back(Thungrac[i]);
[Link]([Link]() + i);
Sapxepsach();
Luudulieu();
cout << "Khoi phuc thanh cong!" << endl;
return;
cout << "Khong tim thay ID trong thung rac!" << endl;
int main() {
Taidulieu();
if ([Link]() && [Link]()) Taodulieumacdinh();
int Luachon;
do {
cout << "\n=== QUAN LY THU VIEN ===" << endl;
cout << "1. Hien thi sach" << endl;
cout << "2. Tim kiem sach" << endl;
cout << "3. Them sach moi" << endl;
cout << "4. Muon sach" << endl;
cout << "5. Tra sach" << endl;
cout << "6. Xoa sach" << endl;
cout << "7. Khoi phuc sach da xoa" << endl;
cout << "0. Thoat" << endl;
Luachon = Nhapsonguyen("Chon chuc nang: ");
switch (Luachon) {
case 1: Hienthisach(); break;
case 2: Timkiemsach(); break;
case 3: Themsach(); break;
case 4: Muonsach(); break;
case 5: Trasach(); break;
case 6: Xoasach(); break;
case 7: Khoiphucsach(); break;
case 0: cout << "Ket thuc!"; break;
default: cout << "Lua chon khong hop le!";
} while (Luachon != 0);
return 0;
}