之前实现过学生管理系统今天来看看图书馆管理系统,其相对学生管理系统来说会复杂一些
一、完整代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 图书结构体
struct Book {
string title;
string author;
int year;
};
// 添加图书函数
void addBook(vector<Book>& books) {
Book newBook;
cout << "请输入图书标题: ";
cin.ignore();
getline(cin, newBook.title);
cout << "请输入图书作者: ";
getline(cin, newBook.author);
cout << "请输入出版年份: ";
cin >> newBook.year;
books.push_back(newBook);
cout << "图书添加成功!" << endl;
}
// 删除图书函数
void deleteBook(vector<Book>& books) {
string title;
cout << "请输入要删除的图书标题: ";
cin.ignore();
getline(cin, title);
for (auto it = books.begin(); it!= books.end(); ++it) {
if (it->title == title) {
books.erase(it);
cout << "图书删除成功!" << endl;
return;
}
}
cout << "未找到该图书,删除失败!" << endl;
}
// 查找图书函数
void searchBook(const vector<Book>& books) {
string title;
cout << "请输入要查找的图书标题: ";
cin.ignore();
getline(cin, title);
for (const auto& book : books) {
if (book.title == title) {
cout << "图书找到!" << endl;
cout << "标题: " << book.title << endl;
cout << "作者: " << book.author << endl;
cout << "出版年份: " << book.year << endl;
return;
}
}
cout << "未找到该图书!" << endl;
}
// 显示所有图书函数
void displayBooks(const vector<Book>& books) {
if (books.empty()) {
cout << "当前没有图书!" << endl;
return;
}
for (const auto& book : books) {
cout << "标题: " << book.title << endl;
cout << "作者: " << book.author << endl;
cout << "出版年份: " << book.year << endl;
cout << "-------------------" << endl;
}
}
int main() {
vector<Book> books;
int choice;
do {
cout << "图书管理系统" << endl;
cout << "1. 添加图书" << endl;
cout << "2. 删除图书" << endl;
cout << "3. 查找图书" << endl;
cout << "4. 显示所有图书" << endl;
cout << "0. 退出" << endl;
cout << "请选择操作: ";
cin >> choice;
switch (choice) {
case 1:
addBook(books);
break;
case 2:
deleteBook(books);
break;
case 3:
searchBook(books);
break;
case 4:
displayBooks(books);
break;
case 0:
cout << "退出系统" << endl;
break;
default:
cout << "无效的选择,请重新输入" << endl;
}
} while (choice!= 0);
return 0;
}
二、程序逐行分析
1、基本程序
#include <iostream>
#include <string>
#include <vector>
这些头文件提供了程序所需的基本功能,包括输入输出流(<iostream>
),字符串处理(<string>
),以及动态数组(<vector>
)。
using namespace std;
这允许我们在后续代码中直接使用std
命名空间下的类型和函数,例如cout
和string
。
struct Book {
string title;
string author;
int year;
};
Book
结构体包含三个成员变量:title
(标题)、author
(作者)和year
(出版年份)。
2、添加新书
void addBook(vector<Book>& books) {
Book newBook;
cout << "请输入图书标题: ";
cin.ignore();
getline(cin, newBook.title);
cout << "请输入图书作者: ";
getline(cin, newBook.author);
cout << "请输入出版年份: ";
cin >> newBook.year;
books.push_back(newBook);
cout << "图书添加成功!" << endl;
}
定义一个名为 addBook
的函数,向图书馆系统中添加一本新书。下面是该函数的逐行解析:
- 函数签名:
这行定义了函数void addBook(vector<Book>& books)
addBook
,它接受一个类型为vector<Book>
的引用参数books
。这里的引用参数允许函数直接修改传递给它的图书向量,而不是其副本。 - 创建新的图书实例:
Book newBook;
这里创建了一个 Book
结构体的新实例 newBook
,用于存储即将添加的图书信息。 3. 输入图书标题:
cout << "请输入图书标题: ";
输出提示信息要求用户输入图书标题。
cin.ignore();
cin.ignore()
被用来忽略输入流中的任何现有字符,这通常用于清理缓冲区,因为在之前的输入操作中可能留下了换行符或其它字符。
getline(cin, newBook.title);
使用 getline
函数读取一行输入并将其存储在 newBook.title
中,这样可以读取包含空格的标题。 4. 输入图书作者:
cout << "请输入图书作者: ";
getline(cin, newBook.author);
类似地,这里请求用户输入图书的作者,并将输入的值赋给 newBook.author
。 5. 输入出版年份:
cout << "请输入出版年份: ";
cin >> newBook.year;
这次使用 cin
直接读取整数输入,并将其赋给 newBook.year
。注意,在此之后没有调用 cin.ignore()
,因为接下来的操作不需要读取整行输入。 6. 将新图书添加到列表:
books.push_back(newBook);
这行代码将新创建的图书 newBook
添加到 books
向量的末尾。 7. 输出确认消息:
cout << "图书添加成功!" << endl;
最后,向用户输出一条确认消息,表示图书已成功添加到系统中。
3、删除图书
void deleteBook(vector<Book>& books) {
string title;
cout << "请输入要删除的图书标题: ";
cin.ignore();
getline(cin, title);
for (auto it = books.begin(); it!= books.end(); ++it) {
if (it->title == title) {
books.erase(it);
cout << "图书删除成功!" << endl;
return;
}
}
cout << "未找到该图书,删除失败!" << endl;
}
定义一个 deleteBook
函数,从图书馆系统中删除指定标题的图书。以下是函数的逐行解析:
-
函数签名:
void deleteBook(vector<Book>& books)
这行定义了函数
deleteBook
,它接受一个vector<Book>
类型的引用参数books
。通过引用传递,函数可以直接修改原始图书列表。 -
获取图书标题:
string title; cout << "请输入要删除的图书标题: ";
输出提示信息要求用户输入想要删除的图书标题。
cin.ignore(); getline(cin, title);
cin.ignore()
清理输入缓冲区,以确保getline
可以正确读取完整的行输入,即使上一次输入操作以回车结束。然后getline
读取用户输入的图书标题并存储在变量title
中。 -
遍历图书列表:
for (auto it = books.begin(); it != books.end(); ++it) { // 循环体 }
这里使用迭代器
it
来遍历图书列表books
。迭代器从books.begin()
开始,指向第一个元素,并在每次循环迭代时递增,直到到达books.end()
,即列表的末尾。 -
检查并删除图书:
if (it->title == title) { books.erase(it); cout << "图书删除成功!" << endl; return; }
在循环体内,比较当前迭代器指向的图书的标题
it->title
是否与用户提供的标题title
相匹配。如果匹配,使用books.erase(it)
删除当前迭代器所指的图书。随后输出一条确认消息,并使用return
立即退出函数,停止进一步的搜索和删除操作。 -
如果图书未找到:
cout << "未找到该图书,删除失败!" << endl;
如果循环结束后没有找到匹配的图书标题,执行这行代码,输出一条错误消息,告知用户图书未找到,删除操作失败。
4、查找图书
void searchBook(const vector<Book>& books) {
string title;
cout << "请输入要查找的图书标题: ";
cin.ignore();
getline(cin, title);
for (const auto& book : books) {
if (book.title == title) {
cout << "图书找到!" << endl;
cout << "标题: " << book.title << endl;
cout << "作者: " << book.author << endl;
cout << "出版年份: " << book.year << endl;
return;
}
}
cout << "未找到该图书!" << endl;
}
定义一个名为 searchBook
的函数,在图书馆系统中查找一本特定的图书。下面是函数的逐行解析:
- 函数签名:
这行定义了函数void searchBook(const vector<Book>& books)
searchBook
,它接受一个vector<Book>
类型的常量引用参数books
。由于不打算修改图书列表,所以使用常量引用,避免不必要的数据复制。 - 获取图书标题:
输出提示信息要求用户输入想要查找的图书标题。string title; cout << "请输入要查找的图书标题: ";
cin.ignore(); getline(cin, title);
cin.ignore()
清理输入缓冲区,确保getline
能够正确读取用户输入的完整行。getline
读取用户输入的图书标题并存储在变量title
中。 - 遍历图书列表:
这里使用范围基础的for (const auto& book : books) { // 循环体 }
for
循环来遍历图书列表books
。const auto& book
表示循环中每次迭代都会访问列表中的一个常量引用图书对象。 - 检查图书标题:
对于列表中的每一本书,检查其标题if (book.title == title) { // 匹配时的代码块 }
book.title
是否与用户提供的标题title
相匹配。 - 找到图书:
如果找到了匹配的图书,输出一条确认消息,并列出图书的详细信息,包括标题、作者和出版年份。之后,使用cout << "图书找到!" << endl; cout << "标题: " << book.title << endl; cout << "作者: " << book.author << endl; cout << "出版年份: " << book.year << endl; return;
return
语句立即退出函数,不再继续搜索。 - 图书未找到:
如果遍历完所有图书都没有找到匹配的标题,执行这行代码,输出一条错误消息,告诉用户未找到该图书。cout << "未找到该图书!" << endl;
5、显示所有图书
void displayBooks(const vector<Book>& books) {
if (books.empty()) {
cout << "当前没有图书!" << endl;
return;
}
for (const auto& book : books) {
cout << "标题: " << book.title << endl;
cout << "作者: " << book.author << endl;
cout << "出版年份: " << book.year << endl;
cout << "-------------------" << endl;
}
}
定义一个 displayBooks
函数,其功能是在图书馆系统中显示所有已存在的图书信息。下面是函数的逐行解析:
- 函数签名:
这里定义了void displayBooks(const vector<Book>& books)
displayBooks
函数,它接受一个vector<Book>
类型的常量引用books
作为参数。常量引用意味着函数不会修改传入的图书列表,同时避免了不必要的数据拷贝。 - 检查图书列表是否为空:
函数首先检查图书列表是否为空。如果列表为空,即if (books.empty()) { cout << "当前没有图书!" << endl; return; }
books.empty()
返回true
,则输出一条消息告知用户当前没有图书,随后使用return
语句提前结束函数执行。 - 遍历图书列表并显示信息:
如果图书列表非空,函数将继续执行并使用范围基础的for (const auto& book : books) { // 显示图书信息的代码 }
for
循环遍历列表中的每一本书。const auto& book
表示每次迭代都会访问列表中的一个常量引用图书对象。 - 输出图书信息:
对于列表中的每一本书,函数会输出其标题、作者和出版年份。每本书的信息展示后,还会输出一行分隔线,以便清晰地区分不同的图书信息。cout << "标题: " << book.title << endl; cout << "作者: " << book.author << endl; cout << "出版年份: " << book.year << endl; cout << "-------------------" << endl;
6、主程序
这段代码是整个图书馆管理系统的核心控制部分,定义在main()
函数中。它提供了用户交互界面,允许用户执行添加、删除、查找图书和显示所有图书等操作。下面是逐行解析: - 初始化图书列表和用户选择变量:
创建一个空的vector<Book> books; int choice;
vector
用于存储图书信息,以及一个整型变量choice
用于存储用户的选择。 - 用户交互循环:
使用do { // 用户界面和选择处理代码 } while (choice != 0);
do-while
循环来持续显示菜单并接收用户输入,直到用户选择退出(输入0
)。do-while
循环至少会执行一次,保证用户至少能看到一次菜单。 - 显示菜单:
这段代码负责输出菜单,让用户知道可选的操作。cout << "图书管理系统" << endl; cout << "1. 添加图书" << endl; cout << "2. 删除图书" << endl; cout << "3. 查找图书" << endl; cout << "4. 显示所有图书" << endl; cout << "0. 退出" << endl;
- 请求用户输入:
提示用户输入他们的选择,并使用cout << "请选择操作: "; cin >> choice;
cin
读取用户输入的整数值到变量choice
。 - 根据用户选择调用相应函数:
使用switch (choice) { // 案例处理 }
switch
语句根据用户的选择调用相应的函数。 - 案例处理:
- 添加图书 (
case 1
):调用addBook(books);
函数。 - 删除图书 (
case 2
):调用deleteBook(books);
函数。 - 查找图书 (
case 3
):调用searchBook(books);
函数。 - 显示所有图书 (
case 4
):调用displayBooks(books);
函数。 - 退出 (
case 0
):输出 “退出系统” 并终止循环。 - 默认情况 (
default
):输出 “无效的选择,请重新输入”,让用户知道他们输入了无效的选择。
- 添加图书 (
- 控制循环条件:
循环将持续执行,直到用户输入} while (choice != 0);
0
,表示退出程序。 - 返回值:
return 0;
main()
函数最后返回0
,表示程序正常结束。