精华内容
下载资源
问答
  • 图书馆管理系统C++实现
    万次阅读 多人点赞
    2018-05-19 20:03:15

    写了一个小项目,图书馆系统,功能如下:
    1,添加书籍
    2,删除书籍(可删除还没外借的书籍)
    3,读者借书
    4,读者还书
    5,按书籍登入号查看信息(每一本书的书籍登入号唯一,如有5本相同书名作者的书,那就有5个不同的书籍登入号)
    6,查询所有图书信息(可以直接查看到同本书在图书馆中的剩余和借出情况)
    7,查看指定读者的借书详情
    8,注册新读者
    9,查看所有书籍信息(可以详细到每个登入号和此登入号书籍的借阅情况:如谁借的,借阅日期)


    采用客户端和服务器模式,服务器端接收客户端,一旦接收到便启用线程,然后相应来自此客户端的不同请求


    server端


    serverHead.h

    #ifndef SERVERHEAD
    #define SERVERHEAD
    
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <list>
    #include <iterator>
    #include <fstream>
    #include <cstring>
    #include <thread>
    #include<WINSOCK2.H>  
    #include <mysql.h>
    #pragma comment(lib,"ws2_32.lib")
    
    struct infoData
    {
        int flag;               //各种命令
        int borFlag;            //借阅情况1表示借出,0表示未出借
        char enterName[20];     //书籍登入号,一本份
        char bookName[50];      //书籍名
        char bookNum[20];       //书编号   
        char bookWriter[50];    //书作者
        int remainBook;         //最初设置的库存
        char readerName[50];    //借书者
        char readerNum[50];     //借书证
        char borrowTime[30];    //借书时间
        int remain;             //库中还剩此书数量
        int lend;               //从库中借出的此书数量
    };
    
    class Book_mysql
    {
    public:
        Book_mysql();
        bool connectAndCreate();                            //链接创建数据库和表
        bool selectWhetherEmpty();                          //检测是否为空表
        bool testTheBookWhetherExist(const infoData& Data); //判断书籍存在
        bool insertTo(infoData & Data);                     //插入书籍
        int deleteFrom(infoData & Data);                    //删除相应书籍
        bool readerBorrowBook(infoData & Data);             //读者借书
        int readerReturnBook(infoData & Data);              //还书
        bool whetherSurpass(infoData & Data);               //判断是否超过借书上限(上限一本书最多借两本)
        bool selectBookByEntername(infoData & Data);        //通过书籍登入号查询书籍
        void displayInformation(infoData & Data, const SOCKET& sClient);//打印(笼统)
        void showTheReaderBook(infoData & Data, SOCKET & sClient);//打印指定读者借书情况
        void DISPLAY(infoData & Data, SOCKET& sClient);     //打印(详细)
    private:
        char user[30];                  //登陆名字    
        char pswd[10];                  //密码
        char host[20];                  //表示本地数据库           
        unsigned int port;              //端口
        MYSQL myCont;                   
        MYSQL_RES *result;
        MYSQL_ROW sql_row;
        int res;
    };
    
    class Reader_mysql
    {
    public:
        Reader_mysql();
        bool connectAndCreate();
        bool testTheReaderWhetherExist(infoData & Data);//检测该读者是否已经存在
        void insertTo(infoData & Data); //注册
        bool readerBorrowBook();        //借书
        bool readerReturnBook();        //还书
    private:
        char user[30];                   //登陆名字    
        char pswd[10];                   //密码
        char host[20];                   //表示本地数据库
        unsigned int port;
        MYSQL myCont;
        MYSQL_RES *result;
        MYSQL_ROW sql_row;
        int res;
    };
    
    class serverSocket
    {
    public:
        serverSocket(int port);
        ~serverSocket();
        SOCKET serverAccpetSocket();//阻塞accept
    private:
        WSADATA wsd;
        SOCKET sServer;             //客户端套接字  用来监听
        std::list<SOCKET> listScli; //客户端套接字  用链表来接收,接送一个放一个
        SOCKET temp;                //用来存放中间值
        SOCKADDR_IN addrServ;       //服务器地址
    };
    
    void addBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql);
    void deleteBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql);
    void borrowBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql);
    void returnBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql);
    void searchBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql);
    void displayAllBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql);
    void DISPLAY(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql);
    void showTheReaderBook(infoData & Data, SOCKET & sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql);
    void setNewReader(infoData & Data, const SOCKET & sClient, Reader_mysql & reader_mysql);
    void clientSocketThreadFunction(SOCKET sClient);
    
    #endif

    套接字类的实现
    serverSocket.cpp

    
    #include "serverHead.h"
    
    serverSocket::serverSocket(int port)
    {
        //初始化套结字动态库
        if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
        {
            std::cout << "WSAStartup failed!" << std::endl;
            return;
        }
    
        //开始创建服务端socket
        //创建套接字  AF_INET:ipv4   SOCK_STREAM:使用tcp
        sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == sServer)
        {
            std::cout << "socket failed!" << std::endl;
            return;
        }
    
        //服务器套接字地址   
        addrServ.sin_family = AF_INET;//IPv4 
        addrServ.sin_port = htons(port);//设置端口 建议大于1024
        addrServ.sin_addr.s_addr = INADDR_ANY; //表示接受任何客户端的请求
    
        //绑定套接字  绑定服务端socket 和 端口
        int ret = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
        if (SOCKET_ERROR == ret)
        {
            std::cout << "bind failed!" << std::endl;
            return;
        }
    
        //开始监听   
        ret = listen(sServer, 10);
        if (SOCKET_ERROR == ret)
        {
            std::cout << "listen failed!" << std::endl;
            return;
        }
    }
    
    serverSocket::~serverSocket()
    {
        closesocket(sServer);   //关闭套接字  
        WSACleanup();           //释放套接字资源;  
    }
    
    SOCKET serverSocket::serverAccpetSocket()
    {
        //接受客户端请求  
        sockaddr_in addrClient;
        int addrClientlen = sizeof(addrClient);
        temp = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);
        if (INVALID_SOCKET == temp)
        {
            std::cout << "accept failed!" << std::endl;
            return -1;
        }
        listScli.push_front(temp);
        return temp;
    }

    MySQL中书籍表的实现

    bookMysql.cpp

    #include "serverHead.h"
    
    Book_mysql::Book_mysql()
    {
        strcpy_s(user, "root");
        strcpy_s(pswd, "123456");
        strcpy_s(host, "localhost");
        port = 3306;
        mysql_init(&myCont);
        if (mysql_real_connect(&myCont, host, user, pswd, "mysql", port, NULL, 0))//先链接自带的数据库,以便后面创建专属数据库
        {
            res = mysql_query(&myCont, "create database if not exists zhanghsun");
            mysql_query(&myCont, "SET NAMES GBK");
            if (res)
            {
                std::cout << "创建库失败" << std::endl;
                system("pause");
                exit(-1);;
            }
            res = mysql_query(&myCont, "use zhanghsun");
            if (res)
            {
                std::cout << "use 失败" << std::endl;
                system("pause");
                exit(-1);
            }
            char order[1024];
            sprintf_s(order, "create table IF NOT EXISTS m_book(书籍登入号 char(10) not null, 书名 char(20) default null, 书编号 char(20) default null, 书作者 char(50) default null, 借阅 int default 0, 读者名 char(20) default '%s', 读者借书号 char(20) default '%s', 借阅时间 char(20) default '%s')", "无", "无", "无");
            res = mysql_query(&myCont, order);
            if (res)
            {
                std::cout << "创建表失败" << std::endl;
                system("pause");
                exit(-1);
            }
        }
        else
        {
            std::cout << "链接失败" << std::endl;
            system("pause");
            exit(-1);
        }
    }
    //判断指定书籍是否存在
    bool Book_mysql::testTheBookWhetherExist(const infoData& Data)
    {
        char order[1024];
        //检测是否存在该书
        sprintf_s(order, "SELECT * FROM m_book WHERE 书名='%s' and 书作者 = '%s'", Data.bookName, Data.bookWriter);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if (sql_row = mysql_fetch_row(result))//如果查询不为空
                {
                    return 1;//已有该书
                }                   
            }
        }
        else
        {
            std::cout << "查询失败" << std::endl;
            system("pause");
            exit(-1);
        }
        return 0;//没有该书 
    }
    //插入书籍操作
    bool Book_mysql::insertTo(infoData & Data)
    {
        char order[1024];
        sprintf_s(order, "insert into m_book (书籍登入号,书名,书编号,书作者) values('%s','%s','%s','%s')", Data.enterName,Data.bookName, Data.bookNum, Data.bookWriter);
        res = mysql_query(&myCont, order);
        if (res)
        {
            std::cout << "插入失败" << std::endl;
            system("pause");
            exit(-1);
        }
        return 1;
    }
    //判断表是否为空
    bool Book_mysql::selectWhetherEmpty()
    {
        char order[1024];
        sprintf_s(order, "SELECT * FROM m_book");
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if (sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    return 0;//表不为空
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        return 1;//表为空
    }
    //判断该读者要借书籍是否超出上限
    bool Book_mysql::whetherSurpass(infoData & Data)
    {
        char order[1024];
        int num = 0;
        sprintf_s(order, "select 读者名,读者借书号 from m_book where 书名 = '%s' and 书作者 = '%s'", Data.bookName, Data.bookWriter);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                while (sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    if (strcmp(Data.readerName, sql_row[0]) == 0
                        && strcmp(Data.readerNum, sql_row[1]) == 0)
                    {
                        ++num;
                    }
                    if (num >= 2)
                    {
                        return 1;//已达上限
                    }
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        return 0;//没超
    }
    //删除书籍
    int Book_mysql::deleteFrom(infoData & Data)
    {
        char order[1024];
        int flag = 0;
        sprintf_s(order, "SELECT * FROM m_book WHERE 书名='%s' AND 书作者 = '%s' AND 借阅 = '%d'", Data.bookName, Data.bookWriter, 0);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                while (sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    flag = 1;
                    std::cout << "删除登入号:" << sql_row[0] << std::endl;
                    //根据得到的登入号一一删除
                    sprintf_s(order, "DELETE FROM m_book WHERE 书籍登入号 = '%s'", sql_row[0]);
                    res = mysql_query(&myCont, order);
                    if (res)
                    {
                        std::cout << "删除failed" << std::endl;
                        system("pause");
                        exit(-1);
                    }
                }
                if (flag == 0)
                {
                    return -1;//全借出
                }
                else if (flag == 1)
                {
                    return 1;//删除了相关书籍
                }
            }   
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
    }
    //读者借阅书籍
    bool Book_mysql::readerBorrowBook(infoData & Data)
    {
        char order[1024];
        sprintf_s(order, "SELECT 书籍登入号 FROM m_book WHERE 书名='%s' AND 书作者 = '%s' AND 借阅 = '%d'", Data.bookName, Data.bookWriter, 0);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if(sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    std::cout << "借的书的登入号:" << sql_row[0] << std::endl;
                    sprintf_s(order, "UPDATE m_book SET 借阅 = '%d',读者名 = '%s',读者借书号 = '%s', 借阅时间 = NOW() WHERE 书籍登入号 = '%s'", 1, Data.readerName,Data.readerNum, sql_row[0]);
                    res = mysql_query(&myCont, order);
                    if (res)
                    {
                        std::cout << "更新failed" << std::endl;
                        system("pause");
                        exit(-1);
                    }
                }
                else
                {
                    return 0;//书全借光
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        return 1;//借书成功
    }
    //还书
    int Book_mysql::readerReturnBook(infoData & Data)
    {
        char order[1024];
        sprintf_s(order, "SELECT * FROM m_book WHERE 书籍登入号='%s'", Data.enterName);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if (sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    std::cout << "登入号:" << sql_row[0] << std::endl;
                    sprintf_s(order, "UPDATE m_book SET 借阅 = 0, 读者名 = '%s', 读者借书号 = '%s', 借阅时间 = '%s' WHERE 书籍登入号 = '%s'","无", "无", "无", Data.enterName);
                    res = mysql_query(&myCont, order);
                    if (res)
                    {
                        std::cout << "更新failed" << std::endl;
                        system("pause");
                        exit(-1);
                    }
                }
                else
                {
                    return 0;//没找到该登入号
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        return 1;//成功
    }
    //更具书籍登入号查询书籍信息
    bool Book_mysql::selectBookByEntername(infoData & Data)
    {
        char order[1024];
        int flag = 0;
        sprintf_s(order, "SELECT * FROM m_book WHERE 书籍登入号='%s'", Data.enterName);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if(sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    flag = 1;
                    strcpy_s(Data.enterName, sql_row[0]);
                    strcpy_s(Data.bookName, sql_row[1]);
                    strcpy_s(Data.bookNum, sql_row[2]);
                    strcpy_s(Data.bookWriter, sql_row[3]);
                    if (atoi(sql_row[4]) == 1)
                    {
                        Data.borFlag = 1;
                        strcpy_s(Data.readerName, sql_row[5]);
                        strcpy_s(Data.readerNum, sql_row[6]);
                        strcpy_s(Data.borrowTime, sql_row[7]);
                    }               
                    else
                    {
                        Data.borFlag = 0;
                    }
                }
                if (flag == 0)
                {
                    return 0;//登入号没找到
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        return 1;
    }
    //笼统打印
    void Book_mysql::displayInformation(infoData & Data, const SOCKET& sClient)
    {
        char order[1024];
        char tempName[30];
        char tempWriter[30];
        int lend = 0;
        int remain = 0;
        sprintf_s(order, "SELECT 书名,书编号,书作者 FROM m_book");
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                while (sql_row = mysql_fetch_row(result))//获取具体的数据
                {
                    strcpy_s(Data.bookName, sql_row[0]);
                    strcpy_s(Data.bookNum, sql_row[1]);
                    strcpy_s(Data.bookWriter, sql_row[2]);
                    if (strcmp(Data.bookName, tempName) == 0
                        && strcmp(Data.bookWriter, tempWriter) == 0)//相同书籍不予计算
                    {
                        continue;
                    }
                    lend = 0;
                    remain = 0;
                    char _order[1024];//已借书情况
                    sprintf_s(_order, "SELECT count(*) FROM m_book where 书名= '%s' and 书作者 = '%s' and 借阅 = 1", Data.bookName, Data.bookWriter);
                    res = mysql_query(&myCont, _order);
                    if (!res)
                    {
                        MYSQL_RES *_result = mysql_store_result(&myCont);
                        if (_result)
                        {
                            MYSQL_ROW _sql_row;
                            while (_sql_row = mysql_fetch_row(_result))//获取具体的数据
                            {
                                lend = atoi(_sql_row[0]);
                            }
                        }
                    }
                    else
                    {
                        std::cout << "查询failed" << std::endl;
                        system("pause");
                        exit(-1);
                    }
                    //剩余没借情况
                    sprintf_s(_order, "SELECT count(*) FROM m_book where 书名= '%s' and 书作者 = '%s' and 借阅 = 0", Data.bookName, Data.bookWriter);
                    res = mysql_query(&myCont, _order);
                    if (!res)
                    {
                        MYSQL_RES *_result = mysql_store_result(&myCont);
                        if (_result)
                        {
                            MYSQL_ROW _sql_row;
                            while (_sql_row = mysql_fetch_row(_result))//获取具体的数据
                            {
                                remain = atoi(_sql_row[0]);
                            }
                        }
                    }
                    else
                    {
                        std::cout << "查询failed" << std::endl;
                        system("pause");
                        exit(-1);
                    }
                    Data.lend = lend;
                    Data.remain = remain;
                    if (strcmp(Data.bookName, tempName) != 0
                        && strcmp(Data.bookWriter, tempWriter) != 0)
                    {
                        Data.flag = 0;
                        send(sClient, (char*)&Data, sizeof(Data), 0);
                    }
                    strcpy_s(tempName, Data.bookName);
                    strcpy_s(tempWriter, Data.bookWriter);
                }
            }
        }
        else
        {
            std::cout << "查询failed" << std::endl;
            system("pause");
            exit(-1);
        }
        Data.flag = 1;
        send(sClient, (char*)&Data, sizeof(Data), 0);
    }
    //打印指定读者借书情况
    void Book_mysql::showTheReaderBook(infoData & Data, SOCKET & sClient)
    {
        char order[1024];
        int flag = 0;
        sprintf_s(order, "select 书籍登入号,书名,书编号,书作者,借阅时间 from m_book where 读者名 = '%s' and 读者借书号 = '%s';", Data.readerName, Data.readerNum);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                while (sql_row = mysql_fetch_row(result))//如果查询不为空
                {
                    flag = 1;
                    strcpy_s(Data.enterName, sql_row[0]);
                    strcpy_s(Data.bookName, sql_row[1]);
                    strcpy_s(Data.bookNum, sql_row[2]);
                    strcpy_s(Data.bookWriter, sql_row[3]);
                    strcpy_s(Data.borrowTime, sql_row[4]);
                    Data.flag = 6;
                    send(sClient, (char*)&Data, sizeof(Data), 0);
                }
            }
        }
        else
        {
            std::cout << "查询失败" << std::endl;
            system("pause");
            exit(-1);
        }
        if (flag == 0)
        {
            Data.flag = 0;//没有借书
            send(sClient, (char*)&Data, sizeof(Data), 0);
        }
        Data.flag = -1;
        send(sClient, (char*)&Data, sizeof(Data), 0);
    }
    //打印(详细)
    void Book_mysql::DISPLAY(infoData & Data, SOCKET& sClient)
    {
        char order[1024];
        int flag = 0;
        int i = 0;
        sprintf_s(order, "select * from m_book");
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                while (sql_row = mysql_fetch_row(result))//如果查询不为空
                {
                    flag = 1;
                    strcpy_s(Data.enterName, sql_row[0]);
                    strcpy_s(Data.bookName, sql_row[1]);
                    strcpy_s(Data.bookNum, sql_row[2]);
                    strcpy_s(Data.bookWriter, sql_row[3]);
    
                    if (atoi(sql_row[4]) == 1)
                    {
                        Data.borFlag = 1;
                        strcpy_s(Data.readerName, sql_row[5]);
                        strcpy_s(Data.readerNum, sql_row[6]);
                        strcpy_s(Data.borrowTime, sql_row[7]);
                    }
                    else
                    {
                        Data.borFlag = 0;
                    }
                    Data.flag = 6;      
                    send(sClient, (char*)&Data, sizeof(Data), 0);
                }
            }
            if (flag == 0)//没有结果
            {
                Data.flag = -2;
                send(sClient, (char*)&Data, sizeof(Data), 0);
            }
        }
        Data.flag = -1;//打印退出flag
        send(sClient, (char*)&Data, sizeof(Data), 0);
    }

    MySQL读者表的实现

    readerMysql.cpp

    #include "serverHead.h"
    
    Reader_mysql::Reader_mysql()
    {
        strcpy_s(user, "root");
        strcpy_s(pswd, "123456");
        strcpy_s(host, "localhost");
        port = 3306;
        mysql_init(&myCont);
        if (mysql_real_connect(&myCont, host, user, pswd, "mysql", port, NULL, 0))
        {
            res = mysql_query(&myCont, "create database if not exists zhanghsun");
            mysql_query(&myCont, "SET NAMES GBK");
            if (res)
            {
                std::cout << "创建库失败" << std::endl;
                system("pause");
                exit(-1);
            }
            res = mysql_query(&myCont, "use zhanghsun");
            if (res)
            {
                std::cout << "use 失败" << std::endl;
                system("pause");
                exit(-1);
            }
            char order[1024];
            sprintf_s(order, "create table IF NOT EXISTS m_reader(读者名 char(20) default null, 读者借书号 char(20) default null)");
            res = mysql_query(&myCont, order);
            if (res)
            {
                std::cout << "创建表failed" << std::endl;
                system("pause");
                exit(-1);
            }
        }
        else
        {
            std::cout << "链接失败" << std::endl;
            system("pause");
            exit(-1);
        }
    }
    //判断是否重复注册
    bool Reader_mysql::testTheReaderWhetherExist(infoData & Data)
    {
        char order[1024];
        sprintf_s(order, "select * from m_reader where 读者名 = '%s' and 读者借书号 = '%s'", Data.readerName, Data.readerNum);
        res = mysql_query(&myCont, order);
        if (!res)
        {
            result = mysql_store_result(&myCont);
            if (result)
            {
                if (sql_row = mysql_fetch_row(result))//如果查询不为空
                {
                    return 1;//有该读者
                }           
            }
        }
        else
        {
            std::cout << "查询失败" << std::endl;
            system("pause");
            exit(-1);
        }
        return 0;//没有此人     
    }
    //插入新读者
    void Reader_mysql::insertTo(infoData & Data)
    {
        char order[102];
        sprintf_s(order, "insert into m_reader (读者名, 读者借书号) values('%s','%s')", Data.readerName, Data.readerNum);
        res = mysql_query(&myCont, order);
        if (res)
        {
            std::cout << "插入失败" << std::endl;
            system("pause");
            exit(-1);
        }
        //else 注册成功
    }
    

    服务器端总实现
    server.cpp

    #include "serverHead.h"
    
    //增加书籍
    void addBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在录入书籍  !" << std::endl;
        if (book_mysql.testTheBookWhetherExist(Data))//数据库中判断该书是否已经存在
        {
            std::cout << "客户端" << sClient << " 添加书籍重复已退回" << std::endl;
            Data.flag = -1;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            return;
        }
        //按库存随机每本书的登入号并插入
        srand((unsigned)time(NULL));//通过时间来随机登入号
        for (int i = 0; i < Data.remainBook; i++)
        {
            int x = rand() % 1000;
            _itoa_s(x, Data.enterName, 10);
            book_mysql.insertTo(Data);//在数据库中插入
        }
        Data.flag = 0;
        send(sClient, (char*)&Data, sizeof(Data), 0);
        std::cout << "客户端 " << sClient << " 录入书籍成功 !" << std::endl;
    }
    //删除书籍
    void deleteBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在删除书籍" << std::endl;
        int flag = 0;
        if (!(book_mysql.testTheBookWhetherExist(Data)))//首先判断该书是否存在
        {
            std::cout << "没有该书" << std::endl;
            Data.flag = -1;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            return;
        }
        //删除
        switch (book_mysql.deleteFrom(Data))
        {
        case -1:
            Data.flag = -2;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            std::cout << "该书全部出借,无法进行删除" << std::endl;
            break;
        case 1:
            Data.flag = 0;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            std::cout << "已删除此书的所有未出借书籍" << std::endl;
            break;
        }
    }
    //借阅书籍
    void borrowBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql)
    {   
        std::cout << "客户端 " << sClient << " 正在借阅书籍" << std::endl;
        //判断该读者是否存在
        switch (reader_mysql.testTheReaderWhetherExist(Data))
        {
        case 0:Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return;//没有找到该读者,直接return
        case 1:Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break;//找到该读者,继续操作
        }
        recv(sClient, (char*)&Data, sizeof(Data), 0);
        if (book_mysql.selectWhetherEmpty())
        {
            std::cout << "未录入任何书籍" << std::endl;
            Data.flag = -1;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            return;
        }
        if (!(book_mysql.testTheBookWhetherExist(Data)))
        {
            Data.flag = -2;
            std::cout << "没有这本书" << std::endl;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            return;
        }
        //判断是否多借
        if (!(book_mysql.whetherSurpass(Data)))
        {
            switch (book_mysql.readerBorrowBook(Data))
            {
            case 1:Data.flag = 0; break;//借书成功
            case 0:Data.flag = -3; break;//书全借光
            }
        }
        else
        {
            Data.flag = -4;//借此书已达上限
        }
        send(sClient, (char*)&Data, sizeof(Data), 0);
    }
    //归还书籍
    void returnBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在归还书籍" << std::endl;
        showTheReaderBook(Data, sClient, book_mysql, reader_mysql);
        recv(sClient, (char*)&Data, sizeof(Data), 0);
        switch (book_mysql.readerReturnBook(Data))
        {
        case 0:std::cout << "没有找到该登入号" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); break;
        case 1:std::cout << "还书成功" << std::endl; Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break;
        }
    }
    //通过登入号搜索书籍
    void searchBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在通过登入号搜索书籍" << std::endl;
        switch(book_mysql.selectBookByEntername(Data))
        {
        case 1:send(sClient, (char*)&Data, sizeof(Data), 0);return;
        case 0:Data.flag = 3; send(sClient, (char*)&Data, sizeof(Data), 0); return;                     
        }
    }
    //打印书籍(笼统打印,不打印登入号)
    void displayAllBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在打印书籍(概括)" << std::endl;
        if (book_mysql.selectWhetherEmpty())
        {
            std::cout << "还没有录入书籍" << std::endl;
            Data.flag = -1;
            send(sClient, (char*)&Data, sizeof(Data), 0);
            return;
        }
        book_mysql.displayInformation(Data, sClient);
    }
    //打印每一本书籍的信息(打印每一本书的详细信息)
    void DISPLAY(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在打印全部书籍信息" << std::endl;
        book_mysql.DISPLAY(Data, sClient);
    }
    //打印指定读者的借书情况
    void showTheReaderBook(infoData & Data, SOCKET & sClient, Book_mysql & book_mysql,Reader_mysql & reader_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在打印指定读者的借书情况" << std::endl;
        switch (reader_mysql.testTheReaderWhetherExist(Data))
        {
        case 0:Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return;//没有找到该读者,直接return
        case 1:Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break;//找到该读者,继续操作
        }
        book_mysql.showTheReaderBook(Data, sClient);
    }
    //注册新的读者
    void setNewReader(infoData & Data, const SOCKET & sClient, Reader_mysql & reader_mysql)
    {
        std::cout << "客户端 " << sClient << " 正在注册新读者" << std::endl;
        switch (reader_mysql.testTheReaderWhetherExist(Data))
        {
        case 1:Data.flag = -1; break;//已有该读者
        case 0:Data.flag = 1; reader_mysql.insertTo(Data); break;//注册成功
        }
        send(sClient, (char*)&Data, sizeof(Data), 0);
    }
    //线程
    void clientSocketThreadFunction(SOCKET sClient)
    {   
        Book_mysql book_mysql;
        Reader_mysql  reader_mysql;
        //对客户端的数据进行解析
        while (true)
        {
            infoData Data;
            int ret = recv(sClient, (char*)&Data, sizeof(Data), 0);
            if (SOCKET_ERROR == ret)
            {
                std::cout << sClient << "可能下线" << std::endl;
                return;
            }
            int flag = 0;
            switch (Data.flag)//错误:控制传输跳过的实例化,方法,加{}
            {
                //增加书籍
            case 1:addBook(Data, sClient, book_mysql); break;
                //删除书籍
            case 2:deleteBook(Data, sClient, book_mysql); break;
                //借书
            case 3:borrowBook(Data, sClient, book_mysql, reader_mysql); break;
                //还书
            case 4:returnBook(Data, sClient, book_mysql, reader_mysql); break;
                //搜索借书者
            case 5: searchBook(Data, sClient, book_mysql); break;
                //浏览所有书籍信息
            case 6: displayAllBook(Data, sClient, book_mysql); break;
                //查看登入读者的借书情况
            case 7:showTheReaderBook(Data, sClient,book_mysql, reader_mysql); break;
                //注册
            case 8:setNewReader(Data, sClient,reader_mysql); break;
                //退出flag
            case 9: flag = 1; break;
                //所有书被借情况一览表
            case -10:DISPLAY(Data, sClient, book_mysql); break;
            default:std::cout << "输入错误 请重新输入:" << std::endl;
            }
            if (flag == 1)
            {
                std::cout << "客户端 " << sClient << " 下线" << std::endl;
                break;
            }
        }
    }
    
    int main(int argc, char* argv[])
    {
        serverSocket mySocket(8888);
        while (1)
        {   
            SOCKET sClient = mySocket.serverAccpetSocket();
            if (sClient == -1)
            {
                continue;
            }
            else
            {
                std::cout << "接收到一个客户端 :" << sClient << std::endl;
            }
            std::thread t1(clientSocketThreadFunction, sClient);//启用线程
            t1.detach();
        }
        return 0;
    }

    client


    头文件
    clientHead.h

    #ifndef CLIENTHEAH
    #define CLIENTHEAH
    
    #include <WINSOCK2.H>  
    #include <iostream>  
    #include <string> 
    #include <thread>
    
    using namespace std;
    
    #pragma comment(lib, "ws2_32.lib")
    
    struct infoData
    {
        int flag;               //各种命令
        int borflag;            //借阅情况1表示借出,0表示未出借
        char enter_name[20];    //书籍登入号,一本份
        char book_name[50];     //书籍名
        char book_num[20];      //书编号   
        char book_writer[50];   //书作者
        int remain_book;        //最初设置的库存
        char reader_name[50];   //借书者
        char reader_num[50];    //借书证
        char borrow_time[30];   //借书时间
        int remain;             //库中还剩此书数量
        int lend;               //从库中借出的此书数量
    };
    
    class clientSocket
    {
    public:
        clientSocket(string ipAdress, short port);
        ~clientSocket();
        bool connectToServer();
        void receiveData(infoData & data);
        void sendData(infoData & data);
    
    private:
        WSADATA wsd;            //WSADATA变量  
        SOCKET sClient;         //客户端套接字  
        SOCKADDR_IN servAddr;   //服务器地址  
        int ret;                //返回值 
    };
    
    void menu();
    void tapAnyKeyNext();
    int addBook(infoData & Data, clientSocket & mySocket);
    int displayAllbook(infoData Data, clientSocket & mySocket);
    int deleteBook(infoData & Data, clientSocket & mySocket);
    int borrowBook(infoData & Data, clientSocket & mySocket);
    int returnBook(infoData & Data, clientSocket & mySocket);
    int searchBook(infoData & Data, clientSocket & mySocket);
    int showTheReaderBook(infoData & Data, clientSocket & mySocket);
    int setNewReader(infoData & Data, clientSocket & mySocket);
    void DISPLAY(infoData & Data, clientSocket & mySocket);
    
    #endif

    套接字类的实现
    mySocket.cpp

    #include "clientHead.h"
    
    clientSocket::clientSocket(string ipAdress, short port)
    {
        //初始化套结字动态库  
        if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
        {
            cout << "WSAStartup failed!" << endl;
            return;
        }
        //创建套接字  
        sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == sClient)
        {
            cout << "socket failed!" << endl;
            return;
        }
        servAddr.sin_family = AF_INET;
        //如果编译通不过 属性 c++ 常规  sdl 改成否
        servAddr.sin_addr.s_addr = inet_addr(ipAdress.c_str());//设置服务端地址  这里表示本机
        servAddr.sin_port = htons(port);
        int nServAddlen = sizeof(servAddr);
    }
    
    bool clientSocket::connectToServer()
    {
        //连接服务器  
        ret = connect(sClient, (LPSOCKADDR)&servAddr, sizeof(servAddr));
        if (SOCKET_ERROR == ret)
        {
            cout << "connect failed!" << endl;
            system("pause");
            return false;
        }
        //成功建立连接  可以开始通信了
        return true;
    }
    
    void clientSocket::sendData(infoData & Data)
    {
        //向服务器发送数据  
        ret = send(sClient, (char*)&Data, sizeof(Data), 0);
        if (SOCKET_ERROR == ret)
        {
            cout << "send failed!" << endl;
            return;
        }
    }
    
    void clientSocket::receiveData(infoData & Data)
    {
        // 接收服务器端的数据
        recv(sClient, (char*)&Data, sizeof(Data), 0); 
        /*if (ret < 0)
        {
            cout << "recv failed" << endl;
            return;
        }*/
    }
    
    clientSocket::~clientSocket()
    {
        closesocket(sClient); //关闭套接字  
        WSACleanup(); //释放套接字资源  
    }

    客户端总实现
    client

    #include "clientHead.h"
    
    void menu()
    {
        cout << "*****************************" << endl;
        cout << 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 << "-10.查看所有书籍信息" << endl;
        cout << endl;
        cout << "*****************************" << endl;
    }
    //增加书籍
    int addBook(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 1;
        cout << "开始录入书籍  !" << endl;
        cout << "输入书名:";
        cin >> Data.book_name;
        cout << "输入书编号:";
        cin >> Data.book_num;
        cout << "输入书作者:";
        cin >> Data.book_writer;
        cout << "输入书库存:";
        cin >> Data.remain_book;
    
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
    
        if (Data.flag == -1)
        {
            cout << "已有此书,请勿重复添加" << endl;
        }
        if (Data.flag == 0)
        {
            cout << "添加成功" << endl;
        }
    
        cout << "是否继续增加书籍操作? 1 : 0 ";
        while (1)
        {
            int x;
            cin >> x;
            switch (x)
            {
            case 0:return 0;//退出
            case 1:return 1;//继续
            default:cout << "输入错误 请重新输入:";
            }
        }
    }
    //删除书籍
    int deleteBook(infoData & Data, clientSocket & mySocket)
    {
        if (displayAllbook(Data, mySocket))
        {
            tapAnyKeyNext();
            return 0;
        }
        cout << "已经外借的那本无法删除" << endl;
        cout << "输入书名:";
        cin >> Data.book_name;
        cout << "输入作者:";
        cin >> Data.book_writer;
        Data.flag = 2;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == -1)
        {
            cout << "没有该书" << endl;
        }
        else if (Data.flag == -2)
        {
            cout << "该书全部出借,无法进行删除" << endl;
        }
        else if (Data.flag == 0)
        {
            cout << "删除成功" << endl;
        }
    
        cout << "是否继续删除书籍操作? 1 : 0 ";
        while (1)
        {
            int x;
            cin >> x;
            switch (x)
            {
            case 0:return 0;//退出
            case 1:return 1;//继续
            default:cout << "输入错误 请重新输入:";
            }
        }
    }
    //借书
    int borrowBook(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 3;
        cout << "输入你的姓名:" << endl;
        cin >> Data.reader_name;
        cout << "输入你的借书号:" << endl;
        cin >> Data.reader_num;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == -1)
        {
            cout << "没有找到该读者,是否重新输入?1:2" << endl;
            char ch[10];
            cin >> ch;
            int x = atoi(ch);
            switch (x)
            {
            case 1:return 1; break;
            case 2:return 0; break;
            }
        }
        else if (Data.flag == 0)
        {
            cout << "登入成功" << endl;
        }
        cout << "输入书籍名:";
        cin >> Data.book_name;
        cout << "输入书作者:";
        cin >> Data.book_writer;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == 0)
        {
            cout << "借书成功" << endl;
        }
        else if (Data.flag == -1)
        {
            cout << "未录入任何书籍" << endl;
        }
        else if (Data.flag == -2)
        {
            cout << "没有这本书" << endl;
        }
        else if (Data.flag == -3)
        {
            cout << "该书已借光" << endl;
        }
        else if (Data.flag == -4)
        {
            cout << "借此书此书已达上限" << endl;
        }
        cout << "是否继续借书操作? 1 : 0 ";
        while (true)
        {
            while (1)
            {
                int x;
                cin >> x;
                switch (x)
                {
                case 0:return 0;//退出
                case 1:return 1;//继续
                default:cout << "输入错误 请重新输入:";
                }
            }
        }
    }
    //还书
    int returnBook(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 4;
        cout << "输入你的姓名:" << endl;
        cin >> Data.reader_name;
        cout << "输入你的借书号:" << endl;
        cin >> Data.reader_num;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == -1)
        {
            cout << "没有找到该读者,是否重新输入?1:2" << endl;
            char ch[10];
            cin >> ch;
            int x = atoi(ch);
            switch (x)
            {
            case 1:return 1; break;
            case 2:return 0; break;
            }
        }
        else if (Data.flag == 0)
        {
            cout << "登入成功" << endl;
        }
        cout << "您所借书如下:" << endl;
        cout << endl;
        mySocket.receiveData(Data);
        if (Data.flag == 0)
        {
            cout << endl;
            std::cout << "你没有借书" << std::endl;
            cout << endl;
            return 1;
        }
        while (Data.flag == 6)
        {
            cout << "登入号   :" << Data.enter_name << endl;
            cout << "书籍名   :" << Data.book_name << endl;
            cout << "书籍号   :" << Data.book_num << endl;
            cout << "作者名   : " << Data.book_writer << endl;
            cout << "借阅时间 :" << Data.borrow_time << endl;
            cout << endl;
            mySocket.receiveData(Data);
        }
        cout << "输入登入号还书:" << endl;
        cin >> Data.enter_name;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == -1)
        {
            cout << "没有查询到该登入号" << endl;
        }
        else if (Data.flag == 0)
        {
            cout << "还书成功" << endl;
        }
        cout << "是否继续还书操作? 1 : 0 ";
        while (true)
        {
            while (1)
            {
                int x;
                cin >> x;
                switch (x)
                {
                case 0:return 0;//退出
                case 1:return 1;//继续
                default:cout << "输入错误 请重新输入:";
                }
            }
        }
    }
    //打印(笼统)
    int displayAllbook(infoData Data, clientSocket & mySocket)
    {
        Data.flag = 6;
        mySocket.sendData(Data);
        cout << endl;
        while (true)
        {   
            mySocket.receiveData(Data);
            if (Data.flag == -1)
            {
                cout << "没有录入书籍" << endl;
                return -1;
            }
            else if (Data.flag == 1)
            {
                break;
            }
            else if (Data.flag == 0)
            {
                cout << "书籍名 :" << Data.book_name << endl;
                cout << "书籍号 :" << Data.book_num << endl;
                cout << "作者名 :" << Data.book_writer << endl;
                cout << "还剩余 :" << Data.remain << " 本" << endl;
                cout << "已借出 :" << Data.lend <<" 本"<< endl;
                cout << endl;
            }       
        }
        return 0;
    }
    //通过书籍登入号查找书籍信息
    int searchBook(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 5;
        cout << "请输入书籍登入号" << endl;
        cin >> Data.enter_name;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == 3)
        {
            cout << "没有这个登入号" << endl;
            tapAnyKeyNext();
            return 0;
        }
        cout << endl;
        cout << "查询结果如下" << endl;
        cout << endl;
        cout << "登入号 :" << Data.enter_name << endl;
        cout << "书籍名 :" << Data.book_name << endl;
        cout << "书籍号 :" << Data.book_num << endl;
        cout << "作者名 : " << Data.book_writer << endl;
        if (Data.borflag == 1)
        {
            cout << "**该书已被借**" << endl;
            cout << "借书者 :" << Data.reader_name << endl;
            cout << "借书证 :" << Data.reader_num << endl;
        }
        else if (Data.borflag == 0)
        {
            cout << "**该书没被借**" << endl;
        }
        cout << endl;
        cout << "查询完成" << endl;
        cout << "是否继续查询操作? 1 : 0 ";
        while (true)
        {
            while (1)
            {
                int x;
                cin >> x;
                switch (x)
                {
                case 0:return 0;//退出
                case 1:return 1;//继续
                default:cout << "输入错误 请重新输入:";
                }
            }
        }
    }
    //查看指定读者借书情况
    int showTheReaderBook(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 7;
        cout << "输入你的姓名:" << endl;
        cin >> Data.reader_name;
        cout << "输入你的借书号:" << endl;
        cin >> Data.reader_num;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == -1)
        {
            cout << "没有找到该读者,是否重新输入?1:2" << endl;
            char ch[10];
            cin >> ch;
            int x = atoi(ch);
            switch (x)
            {
            case 1:return 1; break;
            case 2:return 0; break;
            }
        }
        else if (Data.flag == 0)
        {
            cout << "登入成功" << endl;
        }
        mySocket.receiveData(Data);
        if (Data.flag == 0)
        {
            cout << "你还没借书" << endl;
        }
        else
        {
            cout << endl;
            cout << "查询结果如下" << endl;
            cout << endl;
            while (Data.flag == 6)
            {       
                cout << "登入号   :" << Data.enter_name << endl;
                cout << "书籍名   :" << Data.book_name << endl;
                cout << "书籍号   :" << Data.book_num << endl;
                cout << "作者名   : " << Data.book_writer << endl;
                cout << "借书时间 :" << Data.borrow_time << endl;
                cout << endl;
                mySocket.receiveData(Data);
            }
        }
        cout << "以上是您所有的借书情况" << endl;
        cout << "是否继续此查询操作? 1 : 0 ";
        while (true)
        {
            while (1)
            {
                int x;
                cin >> x;
                switch (x)
                {
                case 0:return 0;//退出
                case 1:return 1;//继续
                default:cout << "输入错误 请重新输入:";
                }
            }
        }
    }
    //创建新读者
    int setNewReader(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = 8;
        cout << "输入你的姓名:" << endl;
        cin >> Data.reader_name;
        cout << "输入你的借书号:" << endl;
        cin >> Data.reader_num;
        mySocket.sendData(Data);
        mySocket.receiveData(Data);
        if (Data.flag == 1)
        {
            cout << "注册成功" << endl;
            tapAnyKeyNext();
            return 0;
        }
        else if (Data.flag == -1)
        {
            cout << "名字借书号重复,是否重新输入?1:2" << endl;
            char ch[10];
            cin >> ch;
            int x = atoi(ch);
            switch (x)
            {
            case 1:return 1; break;
            case 2:return 0; break;
            }
        }
    }
    //遍历每一本书的详情信息
    void DISPLAY(infoData & Data, clientSocket & mySocket)
    {
        Data.flag = -10;
        int i = 0;
        mySocket.sendData(Data);
        cout << endl;
        while (true)
        {
            mySocket.receiveData(Data);
            if (Data.flag == -2)
            {
                cout << "没有录入书籍" << endl;
                tapAnyKeyNext();
                return;
            }
            if (Data.flag == -1)
            {
                break;
            }
            /*std::cout << "i = " << i << std::endl;
            ++i;*/
            cout << "登入号  :" << Data.enter_name << endl;
            cout << "书籍名  :" << Data.book_name << endl;
            cout << "书籍号  :" << Data.book_num << endl;
            cout << "作者名  : " << Data.book_writer << endl;
            if (Data.borflag == 1)
            {
            cout << "**该书已被借**" << endl;
            cout << "借书者   :" << Data.reader_name << endl;
            cout << "借书证   :" << Data.reader_num << endl;
            cout << "借阅时间 :" << Data.borrow_time << endl;
            }
            else if (Data.borflag == 0)
            {
                cout << "**该书没被借**" << endl;
            }
            cout << endl;
    
        }
        cout << "查询完成" << endl;
        cout << endl;
        tapAnyKeyNext();
    }
    //按任意键退出
    void tapAnyKeyNext()
    {
        while (1)
        {
            cout << "按任意键返回主菜单" << endl;
            string x;
            cin >> x;
            return;
        }
    }
    
    int main()
    {   
        clientSocket mySocket("127.0.0.1", 8888);
        if (!mySocket.connectToServer())
        {
            return 0;
        }
        //向服务端发送数据
        while (true)
        {
            menu();
            infoData Data;
            char ch[20];
            cout << "输入操作:";
            cin >> ch;
            int x = atoi(ch);   
            int flag = 0;
            switch (x)
            {
            case 1:
            {
                while (1)
                {
                    if (addBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            } break;
            case 2:
            {
                while (1)
                {
                    if (deleteBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 3:
            {
                while (1)
                {
                    if (borrowBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 4:
            {
                while (1)
                {
                    if (returnBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 5:
            {
                while (1)
                {   
                    if (searchBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 6:displayAllbook(Data, mySocket); tapAnyKeyNext(); break;
            case 7:
            {
                while (1)
                {
                    if (showTheReaderBook(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 8:
            {
                while (1)
                {
                    if (setNewReader(Data, mySocket) == 0)
                    {
                        break;
                    }
                }
            }break;
            case 9:flag = 1; break;
            case -10:DISPLAY(Data, mySocket); break;
            default:cout << "输入错误 请重新输入:" << endl;
            }
            if (flag == 1)
            {
                Data.flag = 9;
                mySocket.sendData(Data);
                break;
            }
        }
        WSACleanup();
        return 0;
    }

    平台:vs2013
    MySQL5.7

    综合了MySQL,网络通信,线程等相关知识,看了不少书,但难免有些幼稚的地方请见谅

    更多相关内容
  • 图书馆管理系统c++

    2019-11-24 22:07:25
    图书馆管理系统c++
  • 图书馆管理系统C++

    2015-06-24 18:35:37
    C++写的图书馆管理系统,用了异常处理
  • C++小型图书馆管理系统
  • 图书馆管理系统C++.txt

    2019-09-08 09:31:07
    此代码仅仅用于参考,借鉴学习,没有其他用途,请不要盲目参考。
  • 使用c++语言,开发一个基于控制台的简单的图书管理系统,使用文件的方式存放各种信息(不允许使用数据库)。具体功能要求如下: 1. 图书管理:增加图书、修改图书、删除图书、统计图书(各类图书库存数量); 2. ...
  • (1)图书图书基本信息管理,包括添加、查询、删除等; (2)图书借阅信息管理,包括借阅时修改图书借阅状态和还书时取消借阅状态等; (3)还可以查看图书的借阅状态,是否可借。 (4)借阅信息用图形界面方式展示或以...
  • C++课程,C++实验,图书馆管理系统C++代码。初学C++就能看懂,这是本人C++实验课写的。
  • 基于C++图书管理系统,主要功能是图书的增、删、改、查
  • 图书馆管理系统c++ mfc

    2019-11-24 22:08:30
    图书馆管理系统c++ mfc
  • 图书馆管理系统 c++ mfc
  • 图书馆管理系统C++代码.docx
  • 图书馆管理系统 C++

    2011-05-25 16:04:19
    4、 选择Manage of Book选项,5、 进行图书管理操作。进入后根据提示信息可进行:1、新书入库2、删除旧书3、查询库存图书操作。 选择1:根据相应提示信息输入书号、书名、作者、出版单位、价格、页数,即可进行...
  • 图书馆管理系统C++代码.doc
  • 图书馆管理系统C++课程设计报告.doc
  • 图书馆管理系统 c++

    2011-04-04 20:05:48
    这是我上学期做的课设,用c++写的可以运行,适合用作大一大二的学弟学妹们作为课设的参考,它功能齐全,并且可以运行。 它1.调试正确,可读性好,2.测试充分,描述清晰,输出结果清晰3.报告规范 4.设计有创新
  • C++实现图书管理系统,可以实现查找书籍,编辑书籍,删除书籍,显示书籍,新建书籍等功能
  • 这是我上学期做的课设,用c++写的可以运行,适合用作大一大二的学弟学妹们作为课设的参考,它功能齐全,并且可以运行。 它1.调试正确,可读性好,2.测试充分,描述清晰,输出结果清晰3.报告规范 4.设计有创新
  • 基于控制台的C++图书管理系统(附带效果展示视频) 详情请查看:https://www.nonoas.top/archives/cpp-library
  • 图书馆管理系统可以增添管理员,部门信息的; 在Linux下编写的C++代码; 内部包含有makefile文件;
  • c++图书馆管理系统

    千次阅读 2021-12-17 13:31:28
    c++编写的图书管理图书借阅系统项目,已录入超过4.6 万条的图书信息和超过1.5万条的用户信息,有增删改查图书,增删改查用户,借还图书等功能。

    用c++编写的图书管理图书借阅系统项目,已录入超过4.6万条的图书信息和超过1.5万条的用户信息,有增删改查图书,增删改查用户,借还图书等功能。

    开发语言: C++
    开发工具: Dev-cpp
    其他特点: 超过4.6万条的图书信息,超过1.5万条的用户信息,友好的可视化界面
    源码地址: https://gitee.com/aimaier4869/interlib-library-manager

    介绍

    概况

    页面的组成: 每个页面由可点击的文本Link,仅用于显示的文本Text,输入框InputBox以及用标准输出流输出的文字组成,其中LinkInputBox为可点击元素。
    整体逻辑: 程序开始执行后首先会渲染基本边框、标题等基本框架,然后切换到登录页面,并开始监听控制台内的点击事件,按照鼠标在控制台内点击的坐标和每个元素自身的坐标判断出被点击的元素,如果某个可点击的元素被点击时就通过调用其点击函数来处理不同的事。
    页面是如何切换的? 全局作用域中提供了三个变量LinksArrTextsArrInputBoxsArr分别存放当前页面中所有LinkTextInputBox类型,在每个页面文件中都会提供一个函数,在该函数内按照本页的内容new出相应的元素组成三个数组分别赋给三个全局变量,然后只要先清屏再渲染三个全局变量中的元素即达到了切换页面的效果。见下图:

    主函数运行逻辑

    运行时的截图

    登录界面

    用户管理界面

    图书馆里界面

    帐户设置界面

    使用

    1. 如果你想看成果

    1. 下载 dist 文件夹中的 dist.7z压缩包
    2. 解压
    3. 双击运行 interlib.exe
    4. 开始体验

    2. 如果你想继续开发

    1. git 克隆仓库到本地
    2. 开始开发

    功能

    可以用账号:admin,密码:123456进行登录

    登录

    1. 渲染界面之前自动调整窗口大小,保证页面渲染完整
    2. 登录时验证用户名密码的非空性,再检查是否匹配
    3. 输入框被点击时让页面中的其他元素变暗,而达到输入框聚焦效果
    4. 输入密码时密码以*的形式显示,保护用户隐私
    5. 密码只能由小写、大写字母和数字组合,其他符号无法输入
    6. 密码框失去焦点后再次获取焦点时可接着编辑上次的内容(普通输入框不能)
    7. 所有用户均可以通过自己的用户名和密码以管理员和普通用户两种模式登录,即用户没有身份区别

    用户列表

    1. 管理员可以通过用户名精确查到用户信息
    2. 管理员可以添加新用户,添加时只需输入用户名即可,密码默认为123456
    3. 添加新用户时会先验证用户名的唯一性,如果要添加的用户已经存在则提示用户已存在无法添加
    4. 新用户会被插入到用户数据列表的最前面
    5. 用户列表以分页的形式展现,每页展示10条,可以通过点击页面中的下一页,上一页按钮进行换页
    6. 可以通过点击当前用户信息行末的操作按钮可以对用户进行删除,重置密码等操作
    7. 展示用户密码时,如果用户没改过密码则直接以明文显示,如果用户已经改过密码则会以*的形式显示,而达到保护用户隐私的目的(就算是管理员也不能看到用户的密码,只能重置)

    图书列表

    1. 在图书管理页面中,可以通过图书名称精确查找到某一本书

    2. 可以通过作者查找到该作者的所有书籍

    3. 可以通过ISBN精确查找到某一本书,ISBN唯一且一旦录入后不可修改

    4. 可以通过分类号查找到该分类里的所有书籍,支持多级分类,例如:

      • 当分类号输入框获取焦点时,会在左边列出当前分类层级下的所有分类(参考中图分类法)
      • 搜索T会找到所有的工业技术类书籍
      • 搜索TP会找到所有工业技术 > 自动化技术、计算机技术类书籍
      • 搜索TP3会找到所有工业技术 > 自动化技术、计算机技术 > 计算技术、计算机技术类书籍
      • 搜索TP31会找到所有工业技术 > 自动化技术、计算机技术 > 计算技术、计算机技术 > 计算机软件类书籍等等
    5. 以上四条内容可以进行联合搜索,例如你可以查找某个做个分类为XX的所有书

    6. 图书列表依然以分页的形式展现,每页展示10条,可以通过点击页面中的下一页,上一页按钮进行换页

    新增修改图书

    1. 点击新增图书按钮后会跳转到新增图书页面,可以在该页面中输入图书信息后决定添加或取消
    2. 添加新书时,图书的四项基本信息都不能为空,ISBN不能重复
    3. 通过点击列表行末的操作按钮对图书进行删除,修改操作,点击修改时会跳转到修改图书页面
    4. 修改图书页面中会自动展示出该书的现有信息,ISBN不可修改,其他信息可修改

    借阅图书

    1. 点击退出登录按钮后会跳转到登录页面
    2. 以普通用户模式登陆后会跳转到借阅图书页面,页面中的搜索功能与管理员图书管理页面一致
    3. 可以点击行末的借阅按钮借阅图书,如果已经借过这本书并且尚未归还时不能再次借阅该书
    4. 可以在借阅记录页面中通过ISBN精确查找到自己记录中的某一个本书
    5. 借阅后尚未归还的书籍会在状态处标记尚未归还,并会有归还操作按钮,已归还的书籍的状态处显示空,操作按钮也不会显示

    借阅记录

    1. 可以点击归还按钮归还该书,归还后可以再次在借阅图书页面中借阅该书
    2. 借阅记录页面中,会通过ISBN自动将图书名称显示在列表中,如果图书名称被修改过了也会同步,如果图书被删除那么在图书名称处显示未找到,该图书可能已被删除!

    修改密码

    1. 可以在帐户设置页面中修改自己的密码
      • 当前密码,新密码,重复新密码均不能为空
      • 新密码,重复新密码的内容必须一致
      • 新密码不能与旧密码相同
      • 输入的当前密码要正确
    2. 修改密码后会自动退出登录,然后就可以用新密码登录

    API

    文件

    variable.h

    声明全局变量

    listener.h

    监听器,不断监听页面中的鼠标点击,并调用相应元素的被点击方法

    util.h

    提供一些全局通用的函数

    router.h

    路由,引入所有的页面文件,并提供一个切换页面的函数checkoutPage

    page_[admin | user]_XXX.h

    页面文件,每个页面都会有该类型的文件,在该文件中声明一个拥有与文件名相同的名称的函数,该函数内描述页面内容,调用该函数时会用自己页面中的元素替换掉全局变量InputBoxsArr,TextsArr,LinksArr的内容,再由renderElements函数渲染

    全局变量(部分)

    int clientWidth

    variable.h中声明,客户端宽度,默认值为120个字符

    int clientHeight

    variable.h中声明,客户端高度 ,默认值为34个字符

    int linksArrLen

    variable.h中声明, 数组LinksArr的长度,即当前渲染的页面中的所有Link类型的元素的数量,初始值为0,一般会在切换页面函数内按照当前页面中的Link元素数量被重新赋值

    Link * LinksArr

    variable.h中声明,存储页面中所有Link类型的元素的数组,当某个页面要被渲染时将该页面中的所有Link放到一个数组后把数组地址赋给该变量,再由renderElements函数渲染到页面中

    int textsArrLen

    variable.h中声明, 数组TextsArr的长度,即当前渲染的页面中的所有Text类型的元素的数量,初始值为0,一般会在切换页面函数内按照当前页面中的Text元素数量被重新赋值

    Text * TextsArr

    variable.h中声明,存储页面中所有Link类型的元素的数组,当某个页面要被渲染时将该页面中的所有Text放到一个数组后把数组地址赋给该变量,再由renderElements函数渲染到页面中

    int inputBoxsArrLen

    variable.h中声明, 数组TextsArr的长度,即当前渲染的页面中的所有InputBox类型的元素的数量,初始值为0,一般会在切换页面函数内按照当前页面中的InputBox元素数量被重新赋值

    InputBox * InputBoxsArr

    variable.h中声明,存储页面中所有InputBox类型的元素的数组,当某个页面要被渲染时将该页面中的所有InputBox放到一个数组后把数组地址赋给该变量,再由renderElements函数渲染到页面中

    string currentUser

    variable.h中声明,当前登录的用户的用户名,初始值为空,一般会在登录后被重新赋值。在普通用户更改自己的密码,找出当前用户的所有借阅记录时会用到该变量

    SchoolUserList hnuer

    variable.h中声明,实例化一个SchoolUserList类,即用户列表类,所有对用户的操作将用到该变量

    Library lib

    variable.h中声明,实例化一个Library类,即图书馆类,所有对图书的操作将用到该变量

    Logs logs

    variable.h中声明,实例化一个Logs类,即记录类,所有对借阅记录的操作将用到该变量

    全局函数(部分)

    void gotoxy(short int row, short int col)

    util.h中声明,移动光标到第row行,第col

    int changeColor(int r, int g, int b)

    util.h中声明,更改控制台输出的颜色,当页面中的一个输入框获取焦点时会用该函数将输出颜色改为一个灰色后重新渲染页面,而达到输入框聚焦时出现一个遮挡层的效果,参数r,g,b分别为一个颜色的RGB值

    void printChar(int n, char c)

    util.h中声明,输出nc,一般会在清除屏幕中的某一部分时用到该函数,以输出空格的方式达到清屏效果

    void renderFramework()

    util.h中声明,渲染框架,即标题,右边框,底部边框和导航栏上下边框等

    void renderElements()

    util.h中声明,分别调用三个函数,renderLinks()渲染页面中所有Link元素,renderTexts()渲染页面中所有Text元素,renderInputBoxs()渲染页面中所有InputBoxs元素

    void clearElements()

    util.h中声明,用于清屏(清掉除框架和信息外的所有内容)

    void renderModel(bool isFocus)

    util.h中声明,产生一个遮挡层效果,参数isFocustrue是产生遮挡层,为false时关闭遮挡层,当一个输入框获取焦点时调用这个函数,原理是更改控制台输出颜色后重新输出除当前输入框外的所有元素

    void msg(string str | int n)

    util.h中声明,在页面左下角打印一些信息

    void lunch_listener()

    listener.h中声明,启动监听页面中的监听事件,发现页面中的某个Link类或InputBox类点击时调用其click函数,原理时得到鼠标在控制台点击的坐标,再遍历每个可点击的元素,判断鼠标点击的坐标是否在该元素的身上

    void click_XXX(const Link & self, int row, int col)

    一般会在page_[admin | user]_XXX.h文件中声明若干个,表示页面中Link类型元素的点击事件,一般功能不相同的每个Link类型的实例都会有自己独有的点击事件,当通过Link类的构造函数实例化一个Link类时将该函数作为实参传给Link的构造函数,当listener调用某个Linkclick函数时在函数体内作为回调函数调用该函数

    类(部分)

    Book 类

    图书类,描述一本书

    1. 构造函数
      • Book() // 默认构造
      • Book(string bookName, string bookAuthor, string bookISBN, string bookType) // 有参构造
    2. 公共数据成员
      • string name; // 图书名称
      • string author; // 作者
      • string ISBN; // ISBN,作为key,一旦输入不可修改且不可重复录入
      • string type; // 分类号

    Log 类

    记录类,描述一条借阅记录

    1. 构造函数
      • Log() // 默认构造
      • Log(string logUname, string logISBN, int logState) // 有参构造
    2. 公共数据成员
      • string username; // 借阅图书的用户名
      • string ISBN; // 借阅的图书的ISBN
      • int state; // 借阅状态,0表示还没还,1表示已经还回去了

    SchoolUser 类

    学校用户类,描述个用户

    1. 构造函数
      • SchoolUser() // 默认构造
      • SchoolUser(string uname, string pwd = “123456”) // 有参构造
    2. 公共数据成员
      • string password; // 用户名
      • string username; // 密码
    3. 公共成员函数
      • bool checkPwd(string pwd)
        // 验证密码是否正确,正确返回true,不正确返回false
      • void changePwd(string pwd)
        // 更改密码,会在用户列表数据库文件中更新数据

    Library 类

    图书馆类,管理所有的图书

    1. 构造函数
      • Library() // 默认构造
    2. 私有数据成员
      • Book * booksArr; // 图书数组
    3. 私有数据成员
      • int totalCount; // 图书总数
      • Book ** currentPageBooksArr; // 当前页图书数组
      • Book ** tempBooksArr; // 临时数组,搜索时使用
      • int tempBooksArrLen;
      • int updatePageMode; // 换页模式:0表示从总表中切换,1表示从当前结果中切换
      • int currentPageIndex; // 当前在页面中展示的页面index
      • int currentPageCount; // 当前页面中展示的图书数量
    4. 公共成员函数
      • void readDataFromFile()
        // 读取文件中的图书数据并更新到属性booksArr中
      • int searchBook(Book book)
        // 搜索图书,接受一个Book类型的参数,按照该Book的属性筛选出booksArr中相应的数据后把它们保存到tempBooksArr中,并按照搜索内容切换换页模式updatePageMode,没有找到任何符合条件的内容时返回0,找到了就返回找到的数据数量
      • string getBookNameByISBN(string ISBN)
        // 通过ISBN拿到图书名称,主要用于借阅记录页面
      • int updateCurrentPage(int pageIndex, int count = 10)
        切换页面,pageIndex表示跳转到第几页,count表示每页显示几条记录,按照参数的内容更新currentPageBooksArr的内容,再由页面负责渲染到页面中
      • int getTotalPageCount(int count = 10)
        // 获取总页数,返回每页展示count条数据时话共可以分多少页
      • void removeBook(int index)
        // 删除图书,传入currentPageBooksArr中的index,删除直接从数据文件中删除
      • int addBook(Book book)
        // 新增图书,传入一个Book类型,新增成功返回当前页图书数量 ,失败了返回-1,直接将图书信息写入到数据文件
      • int modifyBook(Book book)
        // 修改图书,修改成功返回当前页图书数量,失败了返回-1,一般失败的原因为ISBN不存在

    Logs 类

    借阅记录们类,管理所有的记录

    1. 构造函数
      • Logs() // 默认构造
    2. 私有数据成员
      • Log * logsArr; // 记录数组
    3. 私有数据成员
      • int totalCount; // 记录总数
      • Log ** currentPageLogsArr; // 当前页记录数组
      • Log ** tempLogsArr; // 临时数组,文件读取完成后请把该用户的所有记录找出来放到这个数组中
      • int tempLogsArrLen;
      • int currentPageIndex; // 当前在页面中展示的页面index
      • int currentPageCount; // 当前页面中展示的记录数量
    4. 公共成员函数
      • void readDataFromFile()
        // 读取文件中的记录数据并更新到属性logsArr中
      • int searchLogByISBN(string ISBN)
        // 通过条件查找,返回找到的数量,没找到就是0
      • int updateCurrentPage(int pageIndex, int count = 10)
        切换页面,pageIndex表示跳转到第几页,count表示每页显示几条记录,按照参数的内容更新tempLogsArr的内容,再由页面负责渲染到页面中
      • int getTotalPageCount(int count = 10)
        // 获取总页数,返回每页展示count条数据时话共可以分多少页
      • int borrowBook(string ISBN)
        // 借阅图书,传入ISBN,用户默认为当前用户,借阅失败返回-1,该用户以借阅该书并尚未归还时会借阅失败
      • int returnBook(string ISBN)
        // 归还图书

    SchoolUserList 类

    学校用户们类,管理所有的用户

    1. 构造函数
      • SchoolUserList() // 默认构造
    2. 私有数据成员
      • SchoolUser * usersArr; // 用户数组
    3. 私有数据成员
      • int totalCount; // 用户总数
      • SchoolUser ** currentPageUsersArr; // 当前页用户数组
      • int currentPageIndex; // 当前在页面中展示的页面index
      • int currentPageCount; // 当前页面中展示的用户数量
    4. 公共成员函数
      • void readDataFromFile()
        // 读取文件中的记录数据并更新到属性usersArr中
      • int searchUserByUname(string uname)
        // 通过用户名找到唯一的用户,找到了返回1,未找到返回0;
      • int updateCurrentPage(int pageIndex, int count = 10)
        切换页面,pageIndex表示跳转到第几页,count表示每页显示几条记录,按照参数的内容更新tempLogsArr的内容,再由页面负责渲染到页面中
      • int getTotalPageCount(int count = 10)
        // 获取总页数,返回每页展示count条数据时话共可以分多少页
      • int userLogin(string username, string pwd)
        // 用户登录,-1该用户不存在,0密码不正确,1登录成功
      • int userChangePwd(string username, string pwd, string newPwd)
        // 修改密码,-1输入的当前密码不正确,1修改成功
      • void resetPassword(int index)
        // 重置密码,传入currentPageUsersArr中的index
      • void removeUser(int index)
        // 删除用户,传入currentPageUsersArr中的index
      • int addUserByUname(string uname)
        // 新增用户,新增成功返回当前页用户数量 ,失败了返回-1
    展开全文
  • C++ 图书馆管理系统的源代码,可以下载跟着练习,适合初级C++开发人员

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,634
精华内容 7,853
关键字:

图书馆管理系统c++

c++ 订阅