기존 도서관 관리 프로그램에 검색 기능을 추가해주세요
필수 기능 구현 완료 후 전체적인 구조를 그리면 아래와 같습니다.
어디까지나 참조일 뿐 꼭 이대로 구현할 필요는 없습니다.

기존 도서관 관리 프로그램에 필수 기능을 추가한 상태에서 아래 대여 기능을 추가해주세요
도전 기능 구현까지 완료한 후 전체적인 구조를 그리면 아래와 같습니다.
어디까지나 참조일 뿐 꼭 이대로 구현할 필요는 없습니다.

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std; // namespace std 사용
class Book {
public:
string title;
string author;
Book(const string& title, const string& author)
: title(title), author(author) {
}
};
class BookManager {
private:
vector<Book> books; // 책 목록 저장
public:
// 책 추가 메서드
void addBook(const string& title, const string& author) {
books.push_back(Book(title, author)); // push_back 사용
cout << "책이 추가되었습니다: " << title << " by " << author << endl;
}
// 모든 책 출력 메서드
void displayAllBooks() const {
if (books.empty()) {
cout << "현재 등록된 책이 없습니다." << endl;
return;
}
cout << "현재 도서 목록:" << endl;
for (size_t i = 0; i < books.size(); i++) { // 일반적인 for문 사용
cout << "- " << books[i].title << " by " << books[i].author << endl;
}
}
// 책 제목 검색
void searchByTitle(const string& title) {
bool isFind = false;
for (size_t i = 0; i < books.size(); i++) {
if (books[i].title == title) {
cout << "찾은 책 : " << books[i].title << " by " << books[i].author << endl;
isFind = true;
}
}
if (!isFind) cout << "검색한 책이 존재하지 않습니다." << endl;
}
// 작가 검색
void searchByAuthor(const string& author) {
bool isFind = false;
for (size_t i = 0; i < books.size(); i++) {
if (books[i].author == author) {
cout << "찾은 책 : " << books[i].title << " by " << books[i].author << endl;
isFind = true;
}
}
if(!isFind) cout << "검색한 작가가 존재하지 않습니다." << endl;
}
const vector<Book>& getBooks() const {
return books;
}
// 마지막에 들어온 책 == 방금 들어온 책 반환
const Book& getLastBooks() const {
return books.back();
}
};
class BorrowManager {
private:
unordered_map<string, int> stock; // 책 제목 -> 재고 수량
public:
// 초기화 (Book 목록 받아서 재고 3으로 설정)
void initializeStock(const Book& book, int quantity = 3) {
stock[book.title] = quantity;
}
// 제목으로 대여
void borrowBookByTitle(const vector<Book>& books, const string& title) {
for (const auto& book : books) {
if (book.title == title) {
if (stock[title] > 0) {
stock[title]--;
cout << "[" << title << "] 책을 대여했습니다. 남은 재고: " << stock[title] << endl;
}
else {
cout << "[" << title << "] 책은 현재 모두 대여 중입니다." << endl;
}
return;
}
}
cout << title << "' 에 해당하는 책이 없습니다." << endl;
}
// 작가로 대여
void borrowBookByAuthor(const vector<Book>& books, const string& author) {
for (const auto& book : books) {
if (book.author == author) {
if (stock[book.title] > 0) {
stock[book.title]--;
cout << "[" << book.title << "] 책을 대여했습니다. 남은 재고: " << stock[book.title] << endl;
}
else {
cout << "[" << book.title << "] 책은 현재 모두 대여 중입니다." << endl;
}
return;
}
}
cout << author << " 작가의 책이 없습니다." << endl;
}
// 반납 처리
void returnBook(const string& title) {
if (stock.find(title) != stock.end()) {
stock[title]++;
cout << "[" << title << "] 책을 반납했습니다. 현재 재고: " << stock[title] << endl;
}
else {
cout << "[" << title << "] 책은 존재하지 않아 반납할 수 없습니다." << endl;
}
}
// 모든 책 재고 출력
void dispalyStock() {
if (stock.empty()) {
cout << "등록된 책이 없습니다." << endl;
return;
}
cout << "현재 도서 재고 목록:" << endl;
for (const auto& entry : stock) {
cout << "- " << entry.first << " : " << entry.second << "권 남음" << endl;
}
}
};
int main() {
BookManager manager;
BorrowManager borrowManager;
// 도서관 관리 프로그램의 기본 메뉴를 반복적으로 출력하여 사용자 입력을 처리합니다.
// 프로그램 종료를 선택하기 전까지 계속 동작합니다.
while (true) {
cout << "\n도서관 관리 프로그램" << endl;
cout << "1. 책 추가" << endl; // 책 정보를 입력받아 책 목록에 추가
cout << "2. 모든 책 출력" << endl; // 현재 책 목록에 있는 모든 책 출력
cout << "3. 책 제목 검색" << endl; // 현재 책 목록에 있는 책 제목 검색
cout << "4. 작가 검색" << endl; // 현재 책 목록에 있는 책 작가 검색
cout << "5. 책 제목으로 대여" << endl;
cout << "6. 작가로 대여" << endl;
cout << "7. 책 반납" << endl;
cout << "8. 전체 재고 확인" << endl;
cout << "9. 종료" << endl; // 프로그램 종료
cout << "선택: ";
int choice; // 사용자의 메뉴 선택을 저장
cin >> choice;
cin.ignore(); // 이전 입력의 잔여 버퍼를 제거
if (choice == 1) {
// 1번 선택: 책 추가
// 사용자로부터 책 제목과 저자명을 입력받아 BookManager에 추가합니다.
string title, author;
cout << "책 제목: ";
getline(cin, title); // 제목 입력 (공백 포함)
cout << "책 저자: ";
getline(cin, author); // 저자명 입력 (공백 포함)
manager.addBook(title, author); // 입력받은 책 정보를 추가
borrowManager.initializeStock(manager.getLastBooks());
}
else if (choice == 2) {
// 2번 선택: 모든 책 출력
// 현재 BookManager에 저장된 책 목록을 출력합니다.
manager.displayAllBooks();
}
else if (choice == 3) {
// 3번 선택: 제목 검색
// 현재 책 목록에 있는 책 제목을 검색합니다.
cout << "검색 할 책 제목: ";
string title;
getline(cin, title);
manager.searchByTitle(title);
}
else if (choice == 4) {
// 3번 선택: 작가 검색
// 현재 책 목록에 있는 책 작가를 검색합니다.
cout << "검색 할 작가: ";
string author;
getline(cin, author);
manager.searchByAuthor(author);
}
else if (choice == 5) {
// 5 번 선택: 책의 이름으로 대여
//책의 이름으로 대여 여부를 검색하고 대여가 아닌 경우 대여할 수 있어야 합니다.
string title;
cin.ignore();
cout << "대여할 책 제목: ";
getline(cin, title);
borrowManager.borrowBookByTitle(manager.getBooks(), title);
}
else if (choice == 6) {
// 6 번 선택: 작가의 이름으로 대여
//작가의 이름으로 대여 여부를 검색하고 대여가 아닌 경우 대여할 수 있어야 합니다.
string author;
cin.ignore();
cout << "대여할 작가 이름: ";
getline(cin, author);
borrowManager.borrowBookByAuthor(manager.getBooks(), author);
}
else if (choice == 7) {
// 7 번 선택: 책 반납
//책을 반납할 수 있어야 합니다.
string title;
cin.ignore();
cout << "반납할 책 제목: ";
getline(cin, title);
borrowManager.returnBook(title);
}
else if (choice == 8) {
// 8 번 선택: 재고 확인
// 현재 등록된 책의 재고를 확인 합니다.
borrowManager.dispalyStock();
}
else if (choice == 9) {
// 3번 선택: 종료
// 프로그램을 종료하고 사용자에게 메시지를 출력합니다.
cout << "프로그램을 종료합니다." << endl;
break; // while 루프 종료
}
else {
// 잘못된 입력 처리
// 메뉴에 없는 번호를 입력했을 경우 경고 메시지를 출력합니다.
cout << "잘못된 입력입니다. 다시 시도하세요." << endl;
}
}
return 0; // 프로그램 정상 종료
}
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
class Book
{
public:
string title;
string author;
Book(const string& title, const string& author)
: title(title), author(author)
{
}
};
class BookManager
{
private:
vector<Book> books;
public:
void addBook(const string& title, const string& author)
{
books.push_back(Book(title, author));
cout << "책이 추가되었습니다: " << title << " by " << author << endl;
}
void displayAllBooks() const
{
if (books.empty())
{
cout << "현재 등록된 책이 없습니다." << endl;
return;
}
cout << "현재 도서 목록:" << endl;
for (size_t i = 0; i < books.size(); i++)
{
cout << "- " << books[i].title << " by " << books[i].author << endl;
}
}
void searchByTitle(const string& title)
{
// 범위 기반 포문 C++ 11
for (Book& book : books)
{
if (title == book.title)
{
cout << "책 제목: " << title << "을(를) 찾았습니다." << endl;
return;
}
}
cout << title << "라는 책을 찾지 못했습니다." << endl;
}
void searchByAuthor(const string& author)
{
for (Book& book : books)
{
if (author == book.author)
{
cout << "책 제목: " << book.title << "을(를) 찾았습니다." << endl;
return;
}
}
cout << "저자 " << author << "의 책을 찾지 못했습니다." << endl;
}
Book* findBookByTitle(const string& title)
{
for (Book& book : books)
{
if (title == book.title)
{
return &book;
}
}
return nullptr;
}
Book* findBookByAuthor(const string& author)
{
for (Book& book : books)
{
if (author == book.author)
{
return &book;
}
}
return nullptr;
}
};
//- 특정 책의 대여 여부를 알 수 있어야 합니다.
//- 책의 이름으로 대여 여부를 검색하고 대여가 아닌 경우 대여할 수 있어야 합니다.
//- 책의 작가로 대여 여부를 검색하고 대여가 아닌 경우 대여할 수 있어야 합니다.
//- 책을 반납할 수 있어야 합니다.
//- 모든 책의 재고는 난이도를 낮추기 위해 3권으로 통일 합니다.
class BorrowManager
{
private:
unordered_map<string, int> stock;
public:
void initializeStock(const Book* book, int quantity = 3)
{
if (nullptr == book)
{
return;
}
stock[book->title] = quantity;
cout << "책이 추가되었습니다: " << book->title << " by " << book->author << endl;
}
void borrowBook(const string& title)
{
if (stock.end() != stock.find(title))
{
if (0 < stock[title])
{
--stock[title];
cout << title << "을(를) 대여했습니다." << endl;
}
else
{
cout << "재고가 부족하여 " << title << "을(를) 대여하지 못했습니다." << endl;
}
}
else
{
cout << title << "이라는 책을 찾지 못했습니다." << endl;
}
}
void returnBook(const string& title)
{
if (stock.end() != stock.find(title))
{
if (3 > stock[title])
{
++stock[title];
cout << title << "을(를) 반납했습니다." << endl;
}
else
{
cout << title << "을(를) 반납하지 못했습니다." << endl;
}
}
else
{
cout << title << "이라는 책을 찾지 못했습니다." << endl;
}
}
void displayStock()
{
for (pair<const string, int> e : stock)
{
cout << "책 제목: " << e.first << "책 재고: " << e.second << endl;
}
}
};
int main()
{
BookManager bookManager;
BorrowManager borrowManager;
bookManager.addBook("홍길동전", "허균");
bookManager.addBook("반지의 제왕", "J.R.P 톨킨");
borrowManager.initializeStock(bookManager.findBookByTitle("홍길동전"));
borrowManager.initializeStock(bookManager.findBookByTitle("반지의 제왕"));
while (true)
{
system("cls");
cout << "\n도서관 관리 프로그램" << endl;
cout << "1. 책 목록 출력" << endl;
cout << "2. 책 대여" << endl;
cout << "3. 책 반납" << endl;
cout << "4. 책 재고 출력" << endl;
cout << "5. 종료" << endl;
cout << "선택: ";
int choice;
cin >> choice;
cin.ignore();
if (1 == choice)
{
bookManager.displayAllBooks();
}
else if (2 == choice)
{
cout << "대여할 책 제목 또는 작가 이름: ";
string query;
getline(cin, query);
Book* book = bookManager.findBookByTitle(query);
if (book)
{
borrowManager.borrowBook(book->title);
}
else
{
book = bookManager.findBookByAuthor(query);
if (book)
{
borrowManager.borrowBook(book->title);
}
else
{
cout << "관련된 책 정보가 존재하지 않습니다." << endl;
}
}
}
else if (3 == choice)
{
cout << "반납할 책 제목 또는 작가 이름: ";
string query;
getline(cin, query);
Book* book = bookManager.findBookByTitle(query);
if (book)
{
borrowManager.returnBook(book->title);
}
else
{
book = bookManager.findBookByAuthor(query);
if (book)
{
borrowManager.returnBook(book->title);
}
else
{
cout << "관련된 책 정보가 존재하지 않습니다." << endl;
}
}
}
else if (4 == choice)
{
borrowManager.displayStock();
}
else if (5 == choice)
{
cout << "프로그램을 종료합니다." << endl;
break;
}
else
{
cout << "잘못된 입력입니다. 다시 시도하세요." << endl;
}
system("pause");
}
return 0;
}
Book* findBookByTitle(const string& title)
{
for (Book& book : books)
{
if (title == book.title)
{
return &book;
}
}
return nullptr;
}
타이틀을 검색해서 빌리는 부분을 어렵게 했었는데 저런 경우엔 레퍼런스보단 포인터를 사용하는 게 좋을 거 같다.