您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何用C++實現簡單圖書館管理系統”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“如何用C++實現簡單圖書館管理系統”文章能幫助大家解決問題。
功能如下:
1,添加書籍
2,刪除書籍(可刪除還沒外借的書籍)
3,讀者借書
4,讀者還書
5,按書籍登入號查看信息(每一本書的書籍登入號唯一,如有5本相同書名作者的書,那就有5個不同的書籍登入號)
6,查詢所有圖書信息(可以直接查看到同本書在圖書館中的剩余和借出情況)
7,查看指定讀者的借書詳情
8,注冊新讀者
9,查看所有書籍信息(可以詳細到每個登入號和此登入號書籍的借閱情況:如誰借的,借閱日期)
采用客戶端和服務器模式,服務器端接收客戶端,一旦接收到便啟用線程,然后相應來自此客戶端的不同請求
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
關于“如何用C++實現簡單圖書館管理系統”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。