第二十五篇 -- C++宝典中的图书管理系统

此篇文章是基于C++宝典写的图书管理系统,本人对其中的部分做了相应修改,并且以现有格式替代原有格式,使程序更加清晰明了。此程序运行在VS2017上。

系统设计

图书管理系统分为四个模块:图书管理模块、读者管理模块、借书模块和还书模块。

总体设计

图书管理:对图书基本信息进行维护,主要包括新增图书、更改图书基本信息、删除图书、查找图书等功能模块。

读者管理:对读者的基本信息进行维护,主要包括增加读者、删除读者信息、查找特定读者等功能模块。

借书:进行图书借阅操作,该部分是整个图书管理系统中最主要的部分,需要对图书文件和读者文件同时进行读写。

还书:进行图书归还操作,该功能模块也需要对图书文件和读者文件同时进行读写。

                                                   系统结构图

效果图:

输入3,进入图书管理

输入5,显示图书

代码:

Book.h

#pragma once
#include <iostream>
#include <iomanip>
using namespace std;
class Book       //图书类,实现对图书的描述,图书的编号、书名、借出、还入等
{
private:
    int tag;           //删除标记,1:已删,0:未删
    int no;            //图书编号
    char name[20];     //书名
    int onshelf;       //是否可借,1:可借,2:不可借

public:
    Book() {}            //构造函数

    char *getname();

    int getno();

    int gettag();

    void setname(char na[]);

    void delbook();

    void addbook(int n, char *na);

    int borrowbook();

    void retbook();

    void disp();
};
View Code

Book.cpp

#include "pch.h"
#include "Book.h"

char* Book:: getname() {
    return name;     //获取姓名
}

int Book:: getno() {
    return no;       //获取图书编号
}

int Book:: gettag() {
    return tag;     //获取删除标记
}

void Book:: setname(char na[]) {
    strcpy_s(name, 20, na);              //设置书名
}

void Book:: delbook() {
    tag = 1;          //删除图书
}

void Book:: addbook(int n, char *na) {    //增加图书
    tag = 0;
    no = n;
    strcpy_s(name, 20, na);
    onshelf = 1;
}

int Book:: borrowbook() {    //借书操作
    if (onshelf == 1) {          //当前图书可借
        onshelf = 0;
        return 1;
    }
    return 0;
}

void Book:: retbook() {         //还书操作
    onshelf = 1;
}

void Book:: disp() {
    cout << setw(6) << no << setw(18) << name << setw(10) << (onshelf == 1 ? "可借" : "不可借") << endl;
    //cout << setw(6) << no << setw(18) << name << setw(10) << (onshelf == 1 ? "Yes" : "No") << endl;
}
View Code

BDatabase.h

#pragma once
#include "Book.h"
#include <iostream>
#include <fstream>
using namespace std;

#define Maxb 100
class BDatabase         //图书库类,实现对图书的维护、查找、删除等
{
private:
    int top;     //图书记录指针
    Book book[Maxb];      //图书记录

    

public:
    BDatabase();
    ~BDatabase();

    void clear();
    int addbook(int n, char *na);      //增加图书
    Book *query(int bookid);          //查找图书
    void bookdata();                  //图书库维护
    void disp();
};
View Code

BDatabase.cpp

#include "pch.h"
#include "BDatabase.h"

BDatabase:: BDatabase() {          //构造函数,将book.txt读到book[]中
    Book b;           //定义图书对象
    top = -1;         //初始化图书记录指针
    fstream file;
    //ifstream file;
    file.open("book.txt", ios::in);    //以读取方式打开数据文件book.txt
    //file.open("book.txt");    //以读取方式打开数据文件book.txt
    while (1) {          //读取数据文件book.txt中的图书记录
        file.read((char *)&b, sizeof(b));
        if (!file) break;
        top++;
        book[top] = b;
    }
    file.close();
}

BDatabase::~BDatabase() {           //析构函数,将book[]写到book.txt文件中
    fstream file("book.txt", ios::out);              //以写入方式打开数据文件book.txt
    //ofstream file("book.txt");              //以写入方式打开数据文件book.txt
    for (int i = 0; i <= top; i++) {
        if (book[i].gettag() == 0) {
            file.write((char*)&book[i], sizeof(book[i]));
            //file << book[i].gettag();
            //file.write("", 3);
            //file << book[i].getno();
            //file.write("", 3);
            //file.write(book[i].getname(), 20);
            //file.write("", 4);
        }    
    }
    file.close();       //关闭文件
}

void BDatabase:: clear() {     //全删
    top = -1;
}

void BDatabase::disp() {
    for (int i = 0; i <= top; i++) {
        if (book[i].gettag() == 0) {
            book[i].disp();       //显示该图书记录
        }
    }
}

Book* BDatabase::query(int bookid) {   //查找图书
    for (int i = 0; i <= top; i++) {
        if (book[i].getno() == bookid && book[i].gettag() == 0) {
            return &book[i];         //返回查找结果
        }
    }
    return NULL;
}

int BDatabase::addbook(int n, char *na) {    //增加图书
    Book *p = query(n);         //查找是否有重复图书编号
    if (NULL == p) {        //该图书编号无重复
        top++;           //记录指针加1
        book[top].addbook(n, na);          //调用图书类的增加图书成员函数
        return 1;
    }
    return 0;       //该图书编号重复
}

void BDatabase::bookdata() {    //维护图书成员函数
    char choice = '1';      //定义变量
    char bname[40];
    int bookid;
    Book *b;          //创建图书对象
    while (choice != '0') {      //当输入不等于0时
        cout << "


**************    图书维护    **************" << endl << endl;
        cout << "		1    新    增
		2    更    改
		3    删    除
		4    查    找
		5    显    示
		6    全    删
		0    退    出" << endl;
        cout << "请选择操作:";
        cin >> choice;     //输入选项
        switch (choice)
        {
        case '1':            //选择新增图书功能
            cout << "输入图书编号:" << endl;
            cin >> bookid;
            cout << "输入图书书名:" << endl;
            cin >> bname;
            addbook(bookid,bname);      //调用addbook函数
            break;

        case '2':         //选择更改图书功能
            cout << "输入图书编号:" << endl;
            cin >> bookid;
            b = query(bookid);     //调用query函数
            if (b == NULL) {          //未找到该图书
                cout << " 该图书不存在 " << endl;
                break;
            }
            cout << "输入新的书名:" << endl;
            cin >> bname;
            b->setname(bname);     //重新设置图书名称
            break;

        case '3':           //选择删除图书功能
            cout << "请输入要删除的图书编号:" << endl;
            cin >> bookid;
            b = query(bookid);       //调用query函数
            if (b == NULL) {
                cout << " 该图书不存在" << endl;
                break;
            }
            b->delbook();         //删除图书
            break;

        case '4':            //选择查找图书功能
            cout << "请输入要查找的图书编号:" << endl;
            cin >> bookid;
            b = query(bookid);         //调用query函数
            if (b == NULL) {
                cout << " 该图书不存在" << endl;
                break;
            }
            b->disp();          //显示找到的图书信息
            break;

        case '5':                       //选择显示所有图书功能
            disp();
            break;

        case '6':       //选择全部删除图书功能
            clear();
            break;

        default:
            cout << "输入错误,请重新输入:";      //错误的输入
            break;
        }
    }
}
View Code

Reader.h

#pragma once
#include <string.h>
#include <iostream>
#include <iomanip>
using namespace std;

#define Maxbor 5
class Reader         //读者类,实现对读者信息的描述
{
public:
    Reader();
    ~Reader();

private:
    int tag;          //删除标记,1:已删,0:未删
    int no;           //读者编号
    char name[10];    //读者姓名
    int borbook[Maxbor];    //所借图书

public:
    char *getname();        //获取姓名
    int gettag();           //获取删除标记
    int getno();            //获取读者编号
    void setname(char na[]);      //设置姓名
    void delreader();             //设置删除标记,1:已删,0:未删
    void addreader(int n, char *na);        //增加读者
    void borrowbook(int bookid);          //借书操作
    int retbook(int bookid);              //还书操作
    void disp();             //读出读者信息
};
View Code

Reader.cpp

#include "pch.h"
#include "Reader.h"



Reader::Reader()
{
}


Reader::~Reader()
{
}

char* Reader::getname() {
    return name;
}

int Reader::gettag() {
    return tag;
}

int Reader::getno() {
    return no;
}

void Reader::setname(char na[]) {
    strcpy_s(name, 10, na);
}

void Reader::delreader() {
    tag = 1;
}

void Reader::addreader(int n, char *na) {
    tag = 0;
    no = n;
    strcpy_s(name, 10, na);          //设置读者姓名
    for (int i = 0; i < Maxbor; i++)
        borbook[i] = 0;        //设置所借书籍为空
}

void Reader::borrowbook(int bookid) {
    for (int i = 0; i < Maxbor; i++) {      //小于最大借书数目
        if (borbook[i] == 0) {
            borbook[i] = bookid;        //设置所借书籍的图书编号
            return;
        }
    }
}

int Reader::retbook(int bookid) {
    for (int i = 0; i < Maxbor; i++) {
        if (borbook[i] == bookid) {       //设置读者所借书籍字段中对应的图书编号为空
            borbook[i] = 0;
            return 1;
        }
    }
    return 0;
}

void Reader::disp() {
    cout << setw(5) << no << setw(10) << name << "借书编号:[";
    for (int i = 0; i < Maxbor; i++)
    {
        if (borbook[i] != 0) {
            cout << borbook[i] << "|";
        }
    }
    cout << "]" << endl;
}
View Code

RDatabase.h

#pragma once
#include "Reader.h"
#include <iostream>
#include <fstream>
using namespace std;

#define Maxr 100
class RDatabase          //读者库类,实现建立读者的个人资料
{
public:
    RDatabase();   //构造函数,将reader.txt读到read[]中
    ~RDatabase();      //析构函数,将read[]写到reader.txt文件中

public:
    void clear();          //删除所有读者信息
    int addreader(int n, char *na);       //添加读者时先查找是否存在
    Reader *query(int readerid);          //按编号查找
    void disp();         //输出所有读者信息
    void readerdata();        //读者库维护

private:
    int top;           //读者记录指针
    Reader read[Maxr];     //读者记录
};
View Code

RDatabase.cpp

#include "pch.h"
#include "RDatabase.h"


RDatabase::RDatabase()
{
    Reader s;
    top = -1;
    fstream file("reader.txt", ios::in);       //打开一个输入文件
    while (1) {
        file.read((char*)&s, sizeof(s));
        if (!file) break;
        top++;
        read[top] = s;
    }
    file.close(); //关闭reader.txt
}


RDatabase::~RDatabase()
{
    fstream file("reader.txt", ios::out);
    for (int i = 0; i <= top; i++) {
        if (read[i].gettag() == 0) {
            file.write((char*)&read[i], sizeof(read[i]));
        }
    }
    file.close();
}

void RDatabase::clear() {
    top = -1;
}

void RDatabase::disp() {
    for (int i = 0; i <= top; i++) {
        read[i].disp();
    }
}

Reader* RDatabase::query(int readerid) {
    for (int i = 0; i <= top; i++) {
        if (read[i].getno() == readerid && read[i].gettag() == 0) {
            return &read[i];
        }
    }
    return NULL;
}

int RDatabase::addreader(int n, char *na) {      //添加读者时先查找是否存在
    Reader *p = query(n);        //首先查找读者
    if (p == NULL) {             //未找到该读者编号
        top++;
        read[top].addreader(n, na);
        return 1;
    }
    return 0;
}

void RDatabase::readerdata() {
    char choice = '1';       //定义变量
    char rname[20];
    int readerid;
    Reader *r;           //创建对象
    while (choice != '0') {
        cout << "


**************    读者维护    **************" << endl << endl;
        cout << "		1    新    增
		2    更    改
		3    删    除
		4    查    找
		5    显    示
		6    全    删
		0    退    出" << endl;
        cout << "请选择操作:";
        cin >> choice;     //输入选项
        switch (choice)
        {
        case '1':            //选择新增读者功能
            cout << "输入读者编号:" << endl;
            cin >> readerid;
            cout << "输入读者姓名:" << endl;
            cin >> rname;
            addreader(readerid, rname);      //调用addreader函数
            break;

        case '2':         //选择更改读者功能
            cout << "输入读者编号:" << endl;
            cin >> readerid;
            r = query(readerid);     //调用query函数
            if (r == NULL) {          //未找到该图书
                cout << " 该读者不存在 " << endl;
                break;
            }
            cout << "输入新的姓名:" << endl;
            cin >> rname;
            r->setname(rname);     //重新设置读者姓名
            break;

        case '3':           //选择删除读者功能
            cout << "请输入要删除的读者编号:" << endl;
            cin >> readerid;
            r = query(readerid);       //调用query函数
            if (r == NULL) {
                cout << " 该读者不存在" << endl;
                break;
            }
            r->delreader();         //删除读者
            break;

        case '4':            //选择查找读者功能
            cout << "请输入要查找的读者编号:" << endl;
            cin >> readerid;
            r = query(readerid);         //调用query函数
            if (r == NULL) {
                cout << " 该读者不存在" << endl;
                break;
            }
            r->disp();          //显示找到的读者信息
            break;

        case '5':                       //选择显示所有读者功能
            disp();
            break;

        case '6':       //选择全部删除读者功能
            clear();
            break;

        default:
            cout << "输入错误,请重新输入:";      //错误的输入
            break;
        }
    }
}
View Code

Main.cpp

// 图书管理系统.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"
#include <iostream>
using namespace std;

#include "BDatabase.h"
#include "RDatabase.h"

int borrow();
int ret();

int main()               //main函数的实现,程序的主界面的引导
{
    char choice = '1';
    int bookid, readerid;
    RDatabase ReaderDB;
    Reader *r;
    BDatabase BookDB;
    Book *b;
    while (choice != '0') {
        cout << endl << endl << "********************    图 书 管 理 系 统    ********************


";
        cout << "			1    借    书

			2    还    书

			3    图  书  管  理

			4    读  者  管  理

			0    离    开" << endl;
        cout << endl << endl << "******************************************************************


";
        cout << "请选择需要进行的操作序号:";
        cin >> choice;            //接收用户输入的选项
        switch (choice)
        {
        case '1':        //选择借书模块
            borrow();
            break;

        case '2':       //选择还书模块
            ret();
            break;

        case '3':      //选择图书管理模块
            BookDB.bookdata();
            break;

        case '4':     //选择读者管理模块
            ReaderDB.readerdata();
            break;

        default:
            cout << "输入错误,请重新输入:";
            break;
        }
    }
}

int borrow() {           //借书模块
    int bookid, readerid;          //定义变量
    RDatabase ReaderDB;            //创建对象
    Reader *r;                     //定义对象指针
    BDatabase BookDB;
    Book *b;
    cout << " 借书
请输入读者编号:" << endl;
    cin >> readerid;
    cout << "请输入图书编号:" << endl;
    cin >> bookid;
    r = ReaderDB.query(readerid);           //按编号查找读者
    if (NULL == r) {                        //读者编号不存在
        cout << " 不存在该读者,不能借书" << endl;
        exit(0);         //正常结束程序
    }
    b = BookDB.query(bookid);              //按编号查找图书
    if (b == NULL) {                       //图书编号不存在
        cout << " 不存在该图书,不能借书" << endl;
        exit(0);
    }
    if (b->borrowbook() == 0) {           //是否借出
        cout << " 该图书已借出,不能借书" << endl;
        exit(0);
    }
    r->borrowbook(b->getno());              //结束
    cout << "借书成功!" << endl;
    return 0;
}

int ret() {              //还书模块
    int bookid, readerid;
    RDatabase ReaderDB;
    Reader *r;
    BDatabase BookDB;            //定义对象指针
    Book *b;
    cout << "还书
请输入读者编号:";
    cin >> readerid;
    cout << "请输入图书编号:";
    cin >> bookid;
    r = ReaderDB.query(readerid);          //调用读者库的query函数
    if (r == NULL) {                       //未找到读者
        cout << " 不存在该读者,不能还书" << endl;
        exit(0);                   //正常退出
    }
    b = BookDB.query(bookid);        //调用图书库的query函数
    if (b == NULL) {                       //未找到读者
        cout << " 不存在该图书,不能还书" << endl;
        exit(0);                   //正常退出
    }
    b->retbook();             //图书类成员函数还书
    r->retbook(b->getno());         //读者类成员函数还书
    cout << "还书成功!" << endl;
}
View Code

如此,一个简单的图书管理系统就完成了,做的过程中,可能会有些许疑惑,比如,为什么两个库文本打开为什么乱码,那是因为是以二进制的方式写入文本的,自然会乱码,不过读取时也是以二进制的方式,所以没有什么问题,那么为什么要用二进制的方式呢,因为用文本方式存储信息不但浪费空间,而且不便于检索,具体可以看看这篇文章:http://c.biancheng.net/view/302.html

另外,这个管理确实简单,针对数量不多的存储。这里面规定的最大数量也就是100,但是现实中的数据量是很大的,用文本来存储学生信息等是很不友好的,所以还得用数据库的方式。此外,这图书也得不一样,借走了就没有,但是如果是真正的图书馆的话,每种类型的书不可能都只有一本,所以如果想添砖加瓦的话,也可以加上书的数量,判断有无剩余,是否可借等。现在,相信整个结构也是非常清晰的,想要添加修改也只需要到相应的地方,并不需要做大的结构变动。

原文地址:https://www.cnblogs.com/smart-zihan/p/11393564.html