简单的图书馆管理系统
一、概要
1、题目意义
为更好管理图书馆,制作一个简易的图书管理系统,实现新书录入、图书资料查询、显示所有图书信息等功能。通过这个案例可以系统地了解类以及文件的输入输出流。
2、设计思想
①能够借阅图书;
②能够归还图书;
③能够对图书信息进行集中管理。可以设置二级菜单,能够对图书信息实现增、删、改、查操作;
④能够对用户信息进行集中管理。可以设置二级菜单,对用户信息实现增、删、改、查操作。
二、整体架构流程
- 总设计框架图
- 功能设计功能
根据案例需求,可以定义一个图书类,图书的基本信息有书名和作者(其实还可以添加其他信息,例如出版社、价格等,这里只选用最重要的两条信息为代表)。对图书的管理包括设置书名、设置作者名、查询书名等功能,这些功能需要调用图书类的成员函数实现。
由于需要对图书资料进行读入和存储,在程序中需要文件的输入输出操作。先从相应的文件中读入图书资料,用户在对资料进行处理后,在退出系统时将已修改的资料重新存储到原文件中。
- 功能模块介绍
主要分为四大模块:借阅图书、归还图书、图书管理模块和用户管理模块。管理员便可以对图书的信 息进行增加、删除、修改、查询以及统计等的功能。下面就来详细介绍:
-
借阅图书:输入学号及想借阅的书号,就能借阅图书,在图书管理页面可以查到这本书是否被借阅。
-
归还图书:输入学号及想借阅的书号,就能归还图书,在图书管理页面可以查到这本书是否被借阅。
-
图书管理模块
(1)增加图书信息:输入书号和书名,即可实现图书信息的增加。
(2)更改图书信息:输入书号和书名,即可实现图书信息的更改。
(3)删除图书信息:输入书号,即可实现图书信息的删除,删除后该图书信息将不存在图书管理系统中。
(4)查找图书信息:输入书号,即可显示要查找图书的信息,可以显示图书的名称和状态(是否在架)。
(5)显示图书信息:可显示所有图书的信息,包括书号、书名和图书状态(是否在架)。
(6)返回主菜单:可以返回主菜单,进行其他操作。 -
用户管理模块
(1)增加用户信息:输入学号和姓名,即可实现用户信息的增加。
(2)更改用户信息:输入学号和姓名,即可实现用户信息的更改。
(3)删除用户信息:输入学号,即可实现用户信息的删除,删除后该用户信息将不存在图书管理系统中。
(4)查找用户信息:输入学号,即可显示要查找用户的信息,可以显示用户的姓名和是否借书。
(5)显示用户信息:可显示所有用户的信息,包括学号、书名和姓名和是否借书。
(6)返回主菜单:可以返回主菜单,进行其他操作。
三、技术细节
功能模块分析
1.类的设计
Book 类的设计
2.数据成员设计
(1)char name[StrNum];用来存放书名。
(2)char writer[StrNum];用来存放作者姓名。
3.函数成员设计
(1)Book();无参构造函数,用于为书名和作者姓名设置默认值。
(2)Book(const char *Name,const char *Writer)带参构造函数,按照入口参数设置书名和作者姓名。
(3)char *get_name();用于获取书名。
(2) char *get_writer();用于获取作者姓名。
(5)void changeName(const char *newName);用于设置书名。
(6)void changeWriter(const char *newWriter);用于设置作者姓名。
(7)int cmpName(const char *Name);用于比较查询词和书名,如果相等则返回“1”。
4.主程序设计
(1)函数的设计
- void showBook(Book book)——用于输出一册图书的书名。
- void showAll(Book *book,int Num)——用于输出 Num 册图书的书名。
(2)主函数的设计
- 在主函数中创建了一个 Book 类的对象数组,对图书资料的操作都将通过该类所创建对象的函数成员完成。
- 在主函数中通过调用两个函数 showBook()和 showAll()实现图书资料的显示功能。
四、详细代码
头文件
//图书管理模块
//图书类头文件
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class book
{
public:
int no;//图书编号
char name[20];//图书名称
int b_flag;//1 为在架,2 为借出
int b_del;//1 为存在, 2 为删除
public:
book();//构造函数
void setno(int n);
int getno();
void setname(char na[]);
char* getname();
void borbook();
void delbook();
void addbook(int no, char na[]);//增加图书功能
};
//图书数据库类
//图书数据库类头文件
#include"book.h"
const int BMAX = 50;//书最多个数
class bdatabase
{
public:
book btarray[BMAX];//图书集合
int top;
public:
bdatabase();
~bdatabase();
void addbooks();
int findbooks(int suffix);
int findbooks();
void editbooks();
void delbooks();
void listbooks();
};
//读者管理模块
//读者类头文件
#include "book.h"
class reader{
public:
int no;
char name[20];
int r_del;//1 存在,2 删除
int r_bor;//1 借过书,2 没有借书
book brbook;
public:
void addreader(int id, char na[]);//增加读者
void setbrbook(book bt);//设置借书标记
book getbrbook();
};
//读者数据库类
//读者数据库类头文件
#include"reader.h"
const int RMAX = 50;//书最多个数
class rdatabase
{
public:
reader rdarray[RMAX];
int top;
public:
rdatabase();
~rdatabase();
void addreaders();
int findreaders(int suffix);
int findreaders();
void editreaders();
void delreaders();
void listreaders();
};
源文件
//主函数源文件
#include<string>
#include<fstream>
#include<iostream>
#include "bdatabase.h"
#include "rdatabase.h"
void bookjiemain()//图书维护子菜单
{
cout<<"______________________"<<endl;
cout << "| 图书维护 |" << endl;
cout << "| (1)增加 |" << endl;
cout << "| (2)更改 |" << endl;
cout << "| (3)删除 |" << endl;
cout << "| (4)查找 |" << endl;
cout << "| (5)显示 |" << endl;
cout << "| (6)返回上一层 |" << endl;
cout<<"______________________"<<endl;
}
void readerjiemian()//读者维护子菜单
{
cout << "______________________" << endl;
cout << "| 读者维护 |" << endl;
cout << "| (1)增加 |" << endl;
cout << "| (2)更改 |" << endl;
cout << "| (3)删除 |" << endl;
cout << "| (4)查找 |" << endl;
cout << "| (5)显示 |" << endl;
cout << "| (6)返回上一层 |" << endl;
cout << "______________________" << endl;
}
void mainjiemian()//主界面
{
cout << "***********************" << endl;
cout << "* 图书管理系统 *" << endl;
cout << "* (1)借书 *" << endl;
cout << "* (2)还书 *" << endl;
cout << "* (3)图书管理 *" << endl;
cout << "* (4)用户管理 *" << endl;
cout << "* (0)退出 *" << endl;
cout << "***********************" << endl;
}
void borrowtoreturn(char br)//借书还书函数.参数 br 用来判断是“借书”还是“还书”.1 为“借书”,2 为“还书”
{
int rdid = 0;
int bkid = 0;
int rsuffix, bsuffix;
bdatabase t_bd;
rdatabase t_rd;
if (br == '1')
{
rsuffix = t_rd.findreaders(rdid);
bsuffix = t_bd.findbooks(bkid);
if (rsuffix == -1 || bsuffix == -1)
return;
if (t_bd.btarray[bsuffix].b_flag == 2)
{
cout << "图书已经借出,请选择其他图书" << endl;
return;
}
if (t_rd.rdarray[rsuffix].r_bor == 1)
{
cout << "你已经借过图书,请先归还其他图书" << endl;
return;
}
t_bd.btarray[bsuffix].b_flag = 2;
t_rd.rdarray[rsuffix].r_bor = 1;
t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
return;
}
if (br == '2')
{
rsuffix = t_rd.findreaders(rdid);
bsuffix = t_bd.findbooks(bkid);
if (rsuffix == -1 || bsuffix == -1)
return;
if (t_rd.rdarray[rsuffix].brbook.no == t_bd.btarray[bsuffix].no)
{
t_bd.btarray[bsuffix].b_flag = 1;
t_rd.rdarray[rsuffix].r_bor = 2;
t_rd.rdarray[rsuffix].brbook = t_bd.btarray[bsuffix];
}
else
{
cout << "请重新输入,读者借的图书号不正确" << endl;
return;
}
return;
}
}
void booksmange()
{
char in;
bdatabase bd;
do {
bookjiemain();
cin >> in;
switch (in)
{
case'1':
bd.addbooks();
break;
case'2':
bd.editbooks();
break;
case'3':
bd.delbooks();
break;
case'4':
bd.findbooks();
break;
case'5':
bd.listbooks();
break;
case'6':
break;
default:cout << "输入错误,请重新输入" << endl;;
}
} while (in != '6');
return;
}
void readersmange()
{
char in;
rdatabase bd;
do {
readerjiemian();
cin >> in;
switch (in)
{
case'1':
bd.addreaders();
break;
case'2':
bd.editreaders();
break;
case'3':
bd.delreaders();
break;
case'4':
bd.findreaders();
break;
case'5':
bd.listreaders();
break;
case'6':
break;
default:cout << "输入错误,请重新输入" << endl;
}
} while (in != '6');
return;
}
int main()
{
char in;
do {
mainjiemian();
cin >> in;
switch (in)
{
case'1':
borrowtoreturn(in);
break;
case'2':
borrowtoreturn(in);
break;
case'3':
booksmange();
break;
case'4':
readersmange();
break;
case'0':
break;
default:cout << "输入错误,请重新输入" << endl;
}
} while (in != '0');
return 0;
}
//图书类源文件
#include"book.h"
book::book()
{
}//构造函数
void book::setno(int n)
{
no = n;//图书编号取值
}
int book::getno()
{
return no;//返回图书编号值
}
void book::setname(char na[])
{
strcpy_s(name, na);//字符串复制
}
char* book::getname()
{
return name;//返回图书名称
}
void book::borbook()
{
b_flag = 2;//借书标志
}
void book::delbook()
{
b_del = 2;//删除标志
}
void book::addbook(int no, char na[])//增加图书功能
{
setno(no);
setname(na);
b_flag = 1;
b_del = 1;
}
//图书数据库类源文件
#include "bdatabase.h"
bdatabase::bdatabase()
{ book b;
top = -1;
fstream file("book.txt", ios::in);//打开文件
while(1)
{
file.read((char*)&b, sizeof(b));
if (!file)
break;
top++; btarray[top] = b;
}
file.close();//关闭文件
}
bdatabase::~bdatabase()
{
fstream file("book.txt", ios::out);
for (int i = 0; i <= top; i++)
{
if (btarray[i].b_del == 1)
file.write((char*)&btarray[i], sizeof(btarray[i]));
}
file.close();
}
void bdatabase::addbooks()//往图书数据库中加图书
{
book bk; int no;
char bname[20]; cout << "请输入书号: "; cin >> no;
cout << endl << "请输入书名: ";
cin >> bname; cout << endl; bk.b_flag = 1; bk.addbook(no, bname); top++;
btarray[top] = bk; return;
}
int bdatabase::findbooks(int suffix)//查找图书,这个函数用于借书这书操作,suffix 是数组下标
{
int no;
cout << "请输入书号: "; cin >> no;
for (int i = 0; i <= top; i++)
{
if (btarray[i].no == no && btarray[i].b_del == 1)
{
return i;
}
}
return -1;
}
int bdatabase::findbooks()//查找图书,这个函数用于图书维护
{
int no;
char value[6];
cout << "请输入书号: "; cin >> no;
for (int i = 0; i <= top; i++)
{
if (btarray[i].no == no && btarray[i].b_del == 1)
{
if (btarray[i].b_flag == 1) strcpy_s(value, "在架");
if (btarray[i].b_flag == 2) strcpy_s(value, "借出");
cout << "书号: " << btarray[i].no << " 书的名称: " << btarray[i].name << " 图书状态 :" << value << endl;
return i;
}
}
return -1;
}
void bdatabase::editbooks() //编辑图书
{
int cur;
cur = findbooks(); if (cur == -1)
{
cout << "没有这本书" << endl;
return;
}
cout << "书号: " << btarray[cur].no << " 书的名称: " << btarray[cur].name << endl; cout << "请修改数据:" << endl;
cout << endl << "书的名称: ";
cin >> btarray[cur].name; return;
}
void bdatabase::delbooks()//删除图书
{
int cur;
cur = findbooks(); if (cur == -1)
{
return;
}
if (btarray[cur].b_flag == 2)//删除时判断图书是否借出
{
cout << "该图书已经借出,请在归还后再删除。" << endl;
return;
}
btarray[cur].b_del = 2; return;
}
void bdatabase::listbooks()//显示全部图书
{
char value[6];
for (int i = 0; i <= top; i++)
{
if (btarray[i].b_del == 1)
{
if (btarray[i].b_flag == 1) strcpy_s(value, "在架");
if (btarray[i].b_flag == 2) strcpy_s(value, "借出");
cout << "书号: " << btarray[i].no << " 书的名称: " << btarray[i].name << " 图书状态 :" << value << endl;
}
}
return;
}
//读者类源文件
#include "reader.h"
void reader::addreader(int id, char na[])//增加读者
{
no = id;
strcpy_s(name, na);
r_del = 1;
}
void reader::setbrbook(book bt)//设置借书标记
{
brbook = bt;
}
book reader::getbrbook()
{
return brbook;//返回借书信息
}
//读者数据库类源文件
#include "rdatabase.h"
rdatabase::rdatabase()
{
reader rd;
top = -1;
fstream file("reader.txt", ios::in);//打开文件
while (1)
{
file.read((char*)&rd, sizeof(rd));
if (!file) break;
top++;
rdarray[top] = rd;
}
file.close();//关闭文件
}
rdatabase::~rdatabase()
{
fstream file("reader.txt", ios::out);
for (int i = 0; i <= top; i++)
{
if (rdarray[i].r_del == 1)
file.write((char*)&rdarray[i], sizeof(rdarray[i]));
}
file.close();
}
void rdatabase::addreaders()//添加读者
{
reader rd; int no;
char rname[20]; cout << "请输入学号: "; cin >> no;
cout << endl << "请输入姓名: ";
cin >> rname; cout << endl;
rd.addreader(no, rname); rd.r_bor = 2;
top++; rdarray[top] = rd; return;
}
int rdatabase::findreaders(int suffix) //查找读者,这个函数用于借书还书操作。
{
int no;
cout << "请输入学号: "; cin >> no;
for (int i = 0; i <= top; i++)
{
if (rdarray[i].no == no && rdarray[i].r_del == 1)
{
return i;
}
}
return -1;
}
int rdatabase::findreaders()//查找读者,这个函数用于读者维护操作
{
int no;
char value[3];
cout << "请输入学号: "; cin >> no;
for (int i = 0; i <= top; i++)
{
if (rdarray[i].no == no && rdarray[i].r_del == 1)
{
if (rdarray[i].r_bor == 1) strcpy_s(value, "借");
if (rdarray[i].r_bor == 2) strcpy_s(value, "无");
cout << "学号: " << rdarray[i].no << " 姓名: " << rdarray[i].name << " 是否借书: " << value << endl;
return i;
}
}
return -1;
}
void rdatabase::editreaders() //编辑读者信息
{
int cur;
cur = findreaders(); if (cur == -1)
{
cout << "没有该学生" << endl;
return;
}
cout << "请修改数据:" << endl; cout << endl << " 姓名: ";
cin >> rdarray[cur].name; return;
}
void rdatabase::delreaders() //删除读者,读者如果借书要还书后才能删除
{
int cur;
cur = findreaders(); if (cur == -1)
{
return;
}
if (rdarray[cur].r_bor == 1)
{
cout << "该用户借了图书,请还书后再删除" << endl;
return;
}
rdarray[cur].r_del = 2; return;
}
void rdatabase::listreaders()//显示所有读者
{
char value[3];
for (int i = 0; i <= top; i++)
{
if (rdarray[i].r_del == 1)
{
if (rdarray[i].r_bor == 1) strcpy_s(value, "借");
if (rdarray[i].r_bor == 2) strcpy_s(value, "无");
cout << "学号: " << rdarray[i].no << " 姓名: " << rdarray[i].name << " 是否借书: " << value << endl;
}
}
return;
}
五、项目总结
本案例只是完成了图书管理系统中的一部分基础功能,需求相对简单,采用数组和链表也可以实现。 案例涉及到了对象数组及文件的操作,这些知识点并不难理解,读者需要注意的是类结构的设计。除此以外,读者还需要注意以下几点:
1.C++是一门过程语言,无法在源程序中实现数据的存储,必须将数据存储在外部文件中,在必要时可以读入和输出。
2.在不使用文件时要及时关闭,且文件的打开和关闭都要作异常处理。
本系统只是完成了图书管理系统中的一部分基础功能,还有很多功能没有实现,可以在以下方面继续完善本案例:
1.增加图书信息,例如出版社、价格、摘要等。
2.提供多样化的查询和预览方式。
3.提供删除、借还书等功能。
4.改用链表形式制作图书管理系统也是很好的选择。
5.用 MFC 结合数据库可以制作出理想而优秀的图书管理系统。