1、 总体功能分析
实用的图书馆管理系统应该至少包括一下功能:
1、上传:新进图书以及基本信息的输入
2、删除:旧图书以及基本信息的删除
3、显示:显示图书馆已有的所有图书
4、查找:查询要借阅的图书信息
5、借阅:实现用户办理借阅手续
6、归还:实现用户办理归还手续
系统以菜单方式工作使界面友好,易于操作。
2、建立相关属性
由于系统设计的是一些图书和读者的信息存储,因此,需要定义一个数据结构来存储相关信息。
首先需要建立一个图书类、图书数据库类、读者类以及读者数据库类,并定义图书和读者的各种属性。
#include "iostream"
#include "string"
#include "conio.h"
using namespace std;
struct Date{//日期结构
int m_nYear;//年
int m_nMonth;//月
int m_nDay;//日
};
struct Reader{//读者结构
string name;//读者姓名
Date bro;//借出时间
Date back;//归还时间
};
struct Book{//图书结构
int m_nBook_Number;//图书编号
string m_strTitle;//书名
string m_strWroter;//作者
int m_nMoreNum;//当前在图书馆数量
int m_nTotalHoldNum;//图书馆共计数量
string m_sttrComment;//图书介绍
Reader reader[20];
};
struct Info{//借书信息结构
Info *m_pParentPoint;//前驱节点
Book *m_oBookInfo;//对应图书信息
Info *m_pNextPoint;//后继节点
};
3、图书馆菜单
程序开始运行,将显示选择菜单,供用户选择需要的功能,用户根据需要,输入不同的数字来选择相应功能。
int Select_Menu(){
//图书管理系统主界面
cout << "--------------------------------------------------" << endl << endl;
cout << " 图 书 馆 管 理 系 统 " << endl;
cout << " 主 菜 单 " << endl << endl;
cout << " 1.上传图书" << endl;
cout << " 2.下架图书" << endl;
cout << " 3.显示图书" << endl;
cout << " 4.借阅图书" << endl;
cout << " 5.归还图书" << endl;
cout << " 6.退出系统" << endl << endl;
cout << " 请选择菜单项:(1-6)" << endl;
cout << "--------------------------------------------------" << endl;
int id = 0;//编号
cout << "请输入您的选择:";
cin >> id;
return id;
}
4、图书上传
将图书信息添加到图书馆中
Book *InputNode(){
//上传图书
Book *p = new Book;//动态分配一片大小为sizeof(Book)字节的空间,并将该内存空间的起始位置赋值给p
system("cls");//清屏
fflush(stdin);//清楚以前的输入
cout << "请输入图书编号:"; cin >> p->m_nBook_Number;
cout << "请输入图书:"; cin >> p->m_strTitle;
cout << "请输入作者:"; cin >> p->m_strWroter;
cout << "请输入当前在图书馆数量:"; cin >> p->m_nMoreNum;
cout << "请输入图书馆共计数量:"; cin >> p->m_nTotalHoldNum;
cout << "请输入图书介绍:"; cin >> p->m_sttrComment;
for(int i = 0; i < 20; i++){//初始化书本结构成员中相关读者指针内容为空
(p->reader[i]).name = '\0';
}
return p;//返回成功读入的书本信息
}
Info *Insert_BookInfo(Info *bth){
//上传图书
int flag, k, x;
cout << "请输入您想上传的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){//找到直接对已有的数量进行修改
cout << "当前图书馆内拥有这本书" << p->m_oBookInfo->m_nMoreNum << "本,您想在增加一本" << p->m_oBookInfo->m_strTitle << "书?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
p->m_oBookInfo->m_nMoreNum++;
p->m_oBookInfo->m_nTotalHoldNum++;
cout << "增加后图书馆内拥有这本书" << p->m_oBookInfo->m_nMoreNum << "本,一共拥有" << p->m_oBookInfo->m_nTotalHoldNum << "本" << endl;
}
return bth;
}
//图书管内未找到这本图书编号
Book * r = InputNode();
if(bth == NULL){//当bth指针为空时,需要对其进行单独处理,链表表头内存的分配
bth = new Info;
bth->m_pParentPoint = NULL;
bth->m_oBookInfo = r;
bth->m_pNextPoint = NULL;
}
else {
//说明存在头指针
p = bth;
while (p->m_pNextPoint != NULL)
p = p->m_pNextPoint;
Info *q = new Info;
q->m_oBookInfo = r;
q->m_pNextPoint = NULL;
q->m_pParentPoint = p;
p->m_pNextPoint = q;
}
return bth;
}
5、 删除图书
将图书信息从图书馆中删除
Info *Delete_BookInfo(Info * bth){
//删除图书
int flag, k, x;
cout << "请输入您想删除的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 0){//为查找图书编号
cout << "图书馆内并没有这本书!!!" << endl;
return bth;
}
else{
if(p == NULL){//确保当前操作是有效的,防止出现非法操作
cout << "查找错误" << endl;
return bth;
}
else {
cout << "你想删除的图书信息如下:" << endl;
cout << "图书编号:" << p->m_oBookInfo->m_nBook_Number << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定删除吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || 'y'){
if(p->m_pNextPoint != NULL && p->m_pParentPoint != NULL){//夹在链表中间的节点
Info *Left = p->m_pParentPoint;//将要删除节点的前驱节点指向赋值给前驱结点指针变量
Info *Right = p->m_pNextPoint;//将要删除节点的后继结点指向赋值给后继结点指针变量
Left->m_pNextPoint = Right;//将后继结点指针指向的地址作为前驱结点的后继域
Right->m_pParentPoint = Left;//将前驱结点指针指向的地址作为后继结点的前驱域
//释放空间
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
else if(p->m_pParentPoint == NULL){//首结点的前驱为空,处理首结点删除操作
if(p->m_pNextPoint == NULL){//说明只有一个结点
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
bth = p->m_pNextPoint;
bth->m_pParentPoint = NULL;
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
else if(p->m_pNextPoint == NULL){
Info *Left = p->m_pParentPoint;
Left->m_pNextPoint = NULL;
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
}
}
}
}
6、 查找图书
根据输入的图书编号,是心啊图书的查找。
Info *Sreach(Info *bth, int x, int *k, int *flag){
//搜索图书
Info *p = bth;
*flag = 0;
while(p){
if(p->m_oBookInfo->m_nBook_Number == x){//寻到相同的图书编号
*flag = 1;
return p;
}
else {
*flag = 0;
}
if(p->m_pNextPoint != NULL) {
p = p->m_pNextPoint;
}
else{
break;
}
}
return bth;
}
7、显示图书信息
显示图书馆中所有的图书信息。
void Output_BookInfo(Info * bth){
//输出图书信息
system("cls");
Info *p = bth;
while (p){
cout << "图书编号:" << p->m_oBookInfo->m_nBook_Number;
cout << "书名:" << p->m_oBookInfo->m_strTitle;
cout << "作者:" << p->m_oBookInfo->m_strWroter;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
p = p->m_pNextPoint;
}
}
8、图书借阅
根据输入的相关信息,实现借阅
void Borrow_TheBook(Info *bth){
//图书借出
system("cls");
int flag, k, x, i = 0;
cout << "请输入您想借阅的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){
Book *r = p->m_oBookInfo;
cout << "你想借阅的图书信息如下:" << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定借阅吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
if(r->m_nMoreNum == 0) cout << "对不起,本书 已经全部借出···" << endl;
else{
system("cls");
for(i = 0; i < 20; i++)
if((r->reader[i]).name[0] == '\0') break;
cout << "请输入借阅者的姓名:";cin >> (r->reader[i]).name;
cout << "请输入借出日期:" << endl;
cout << "请输入借出年份:";cin >> (r->reader[i]).bro.m_nYear;
cout << "请输入借出月份:";cin >> (r->reader[i]).bro.m_nMonth;
cout << "请输入借出日:";cin >> (r->reader[i]).bro.m_nDay;
cout << "请输入归还日期:" << endl;
cout << "请输入归还年份:";cin >> (r->reader[i]).back.m_nYear;
cout << "请输入归还月份:";cin >> (r->reader[i]).back.m_nMonth;
cout << "请输入归还日:";cin >> (r->reader[i]).back.m_nDay;
r->m_nMoreNum--;
cout << endl << "成功接到这本书" << endl;
}
}
}
}
9、图书归还
根据输入的图书编号归还图书。
void TurnBack_TheBook(Info *bth){
//图书归还
system("cls");
int flag, k, x, i = 0, j = 0;
cout << "请输入您想借阅的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){
Book *r = p->m_oBookInfo;
cout << "你想归还的图书信息如下:" << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定归还吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
system("cls");
cout << "请输入借阅者的姓名:";
string nm;
cin >> nm;
for(i = 0; i < 20; i++)
if((r->reader[i]).name == nm) {
j = 1;
break;
}
if(j == 0) {
cout << "你未借阅过这本书" << endl;
return;
}
(r->reader[i]).name[0] = '\0';
r->m_nMoreNum++;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
}
}
else cout << "您不能归还不存在的图书" << endl;
}
10、完整代码
#include "iostream"
#include "string"
#include "conio.h"
using namespace std;
struct Date{//日期结构
int m_nYear;//年
int m_nMonth;//月
int m_nDay;//日
};
struct Reader{//读者结构
string name;//读者姓名
Date bro;//借出时间
Date back;//归还时间
};
struct Book{//图书结构
int m_nBook_Number;//图书编号
string m_strTitle;//书名
string m_strWroter;//作者
int m_nMoreNum;//当前在图书馆数量
int m_nTotalHoldNum;//图书馆共计数量
string m_sttrComment;//图书介绍
Reader reader[20];
};
struct Info{//借书信息结构
Info *m_pParentPoint;//前驱节点
Book *m_oBookInfo;//对应图书信息
Info *m_pNextPoint;//后继节点
};
Book *InputNode(){
//上传图书
Book *p = new Book;//动态分配一片大小为sizeof(Book)字节的空间,并将该内存空间的起始位置赋值给p
system("cls");//清屏
fflush(stdin);//清楚以前的输入
cout << "请输入图书编号:"; cin >> p->m_nBook_Number;
cout << "请输入图书:"; cin >> p->m_strTitle;
cout << "请输入作者:"; cin >> p->m_strWroter;
cout << "请输入当前在图书馆数量:"; cin >> p->m_nMoreNum;
cout << "请输入图书馆共计数量:"; cin >> p->m_nTotalHoldNum;
cout << "请输入图书介绍:"; cin >> p->m_sttrComment;
for(int i = 0; i < 20; i++){//初始化书本结构成员中相关读者指针内容为空
(p->reader[i]).name = '\0';
}
return p;//返回成功读入的书本信息
}
Info *Sreach(Info *bth, int x, int *k, int *flag){
//搜索图书
Info *p = bth;
*flag = 0;
while(p){
if(p->m_oBookInfo->m_nBook_Number == x){//寻到相同的图书编号
*flag = 1;
return p;
}
else {
*flag = 0;
}
if(p->m_pNextPoint != NULL) {
p = p->m_pNextPoint;
}
else{
break;
}
}
return bth;
}
Info *Insert_BookInfo(Info *bth){
//上传图书
int flag, k, x;
cout << "请输入您想上传的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){//找到直接对已有的数量进行修改
cout << "当前图书馆内拥有这本书" << p->m_oBookInfo->m_nMoreNum << "本,您想在增加一本" << p->m_oBookInfo->m_strTitle << "书?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
p->m_oBookInfo->m_nMoreNum++;
p->m_oBookInfo->m_nTotalHoldNum++;
cout << "增加后图书馆内拥有这本书" << p->m_oBookInfo->m_nMoreNum << "本,一共拥有" << p->m_oBookInfo->m_nTotalHoldNum << "本" << endl;
}
return bth;
}
//图书管内未找到这本图书编号
Book * r = InputNode();
if(bth == NULL){//当bth指针为空时,需要对其进行单独处理,链表表头内存的分配
bth = new Info;
bth->m_pParentPoint = NULL;
bth->m_oBookInfo = r;
bth->m_pNextPoint = NULL;
}
else {
//说明存在头指针
p = bth;
while (p->m_pNextPoint != NULL)
p = p->m_pNextPoint;
Info *q = new Info;
q->m_oBookInfo = r;
q->m_pNextPoint = NULL;
q->m_pParentPoint = p;
p->m_pNextPoint = q;
}
return bth;
}
Info *Delete_BookInfo(Info * bth){
//删除图书
int flag, k, x;
cout << "请输入您想删除的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 0){//为查找图书编号
cout << "图书馆内并没有这本书!!!" << endl;
return bth;
}
else{
if(p == NULL){//确保当前操作是有效的,防止出现非法操作
cout << "查找错误" << endl;
return bth;
}
else {
cout << "你想删除的图书信息如下:" << endl;
cout << "图书编号:" << p->m_oBookInfo->m_nBook_Number << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定删除吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || 'y'){
if(p->m_pNextPoint != NULL && p->m_pParentPoint != NULL){//夹在链表中间的节点
Info *Left = p->m_pParentPoint;//将要删除节点的前驱节点指向赋值给前驱结点指针变量
Info *Right = p->m_pNextPoint;//将要删除节点的后继结点指向赋值给后继结点指针变量
Left->m_pNextPoint = Right;//将后继结点指针指向的地址作为前驱结点的后继域
Right->m_pParentPoint = Left;//将前驱结点指针指向的地址作为后继结点的前驱域
//释放空间
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
else if(p->m_pParentPoint == NULL){//首结点的前驱为空,处理首结点删除操作
if(p->m_pNextPoint == NULL){//说明只有一个结点
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
bth = p->m_pNextPoint;
bth->m_pParentPoint = NULL;
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
else if(p->m_pNextPoint == NULL){
Info *Left = p->m_pParentPoint;
Left->m_pNextPoint = NULL;
p->m_pNextPoint = NULL;
p->m_pParentPoint = NULL;
delete p->m_oBookInfo;
p->m_oBookInfo = NULL;
delete p;
p = NULL;
return bth;
}
}
}
}
}
void Output_BookInfo(Info * bth){
//输出图书信息
system("cls");
Info *p = bth;
while (p){
cout << "图书编号:" << p->m_oBookInfo->m_nBook_Number;
cout << "书名:" << p->m_oBookInfo->m_strTitle;
cout << "作者:" << p->m_oBookInfo->m_strWroter;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
p = p->m_pNextPoint;
}
}
void Borrow_TheBook(Info *bth){
//图书借出
system("cls");
int flag, k, x, i = 0;
cout << "请输入您想借阅的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){
Book *r = p->m_oBookInfo;
cout << "你想借阅的图书信息如下:" << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定借阅吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
if(r->m_nMoreNum == 0) cout << "对不起,本书 已经全部借出···" << endl;
else{
system("cls");
for(i = 0; i < 20; i++)
if((r->reader[i]).name[0] == '\0') break;
cout << "请输入借阅者的姓名:";cin >> (r->reader[i]).name;
cout << "请输入借出日期:" << endl;
cout << "请输入借出年份:";cin >> (r->reader[i]).bro.m_nYear;
cout << "请输入借出月份:";cin >> (r->reader[i]).bro.m_nMonth;
cout << "请输入借出日:";cin >> (r->reader[i]).bro.m_nDay;
cout << "请输入归还日期:" << endl;
cout << "请输入归还年份:";cin >> (r->reader[i]).back.m_nYear;
cout << "请输入归还月份:";cin >> (r->reader[i]).back.m_nMonth;
cout << "请输入归还日:";cin >> (r->reader[i]).back.m_nDay;
r->m_nMoreNum--;
cout << endl << "成功接到这本书" << endl;
}
}
}
}
void TurnBack_TheBook(Info *bth){
//图书归还
system("cls");
int flag, k, x, i = 0, j = 0;
cout << "请输入您想借阅的图书编号:";//按照书本编号进行查找
cin >> x;
Info *p = Sreach(bth, x, &k, &flag);
if(flag == 1){
Book *r = p->m_oBookInfo;
cout << "你想归还的图书信息如下:" << endl;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
cout << "您确定归还吗?(Y/N)" << endl;
char ch;
cin >> ch;
if(ch == 'Y' || ch == 'y'){
system("cls");
cout << "请输入借阅者的姓名:";
string nm;
cin >> nm;
for(i = 0; i < 20; i++)
if((r->reader[i]).name == nm) {
j = 1;
break;
}
if(j == 0) {
cout << "你未借阅过这本书" << endl;
return;
}
(r->reader[i]).name[0] = '\0';
r->m_nMoreNum++;
cout << "书名:" << p->m_oBookInfo->m_strTitle << endl;
cout << "作者:" << p->m_oBookInfo->m_strWroter << endl;
cout << "当前在馆图书数量:" << p->m_oBookInfo->m_nMoreNum << endl;
cout << "图书共计数量:" << p->m_oBookInfo->m_nTotalHoldNum << endl;
cout << "这本图书简介:" << p->m_oBookInfo->m_sttrComment << endl;
}
}
else cout << "您不能归还不存在的图书" << endl;
}
int Select_Menu(){
//图书管理系统主界面
cout << "--------------------------------------------------" << endl << endl;
cout << " 图 书 馆 管 理 系 统 " << endl;
cout << " 主 菜 单 " << endl << endl;
cout << " 1.上传图书" << endl;
cout << " 2.下架图书" << endl;
cout << " 3.显示图书" << endl;
cout << " 4.借阅图书" << endl;
cout << " 5.归还图书" << endl;
cout << " 6.退出系统" << endl << endl;
cout << " 请选择菜单项:(1-6)" << endl;
cout << "--------------------------------------------------" << endl;
int id = 0;//编号
cout << "请输入您的选择:";
cin >> id;
return id;
}
int main(){
Info *bth = NULL;
while(true){
int id = Select_Menu();
switch (id) {
case 1:
bth = Insert_BookInfo(bth);
break;
case 2:
bth = Delete_BookInfo(bth);
break;
case 3:
Output_BookInfo(bth);
break;
case 4:
Borrow_TheBook(bth);
break;
case 5:
TurnBack_TheBook(bth);
break;
case 6:
system("cls");
cout << "您确定要退出系统(Y/N)";
char t;
cin >> t;
if(t == 'y' || t == 'Y') exit(0);
break;
}
cout << "按任意键返回主菜单.......";
}
}