用面向对象思想===>
设计图书管理数据库 并实现c++代码控制,可以完成以下业务逻辑:
1 查询图书:书籍名称模糊查询,编号查询
2 借书:学号 借多久(天)
3 还书:学号 附加:反馈:小伙子 你逾期了,交¥¥。。。
mysql创建表:
表1 学生管理 :id 姓名 性别 生日 年龄 学号 手机号 学号 其他(自定义)
表2图书管理:id 书籍名称 书籍编号 状态0,1 借阅人编号(学号) 借书日期 还书日期 其他
数据库表格样式:
客户端Client程序包含:Myhead.h ; main.cpp ; cfun.cpp;
Myhead.h↓
#include "winsock2.h"
#include
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
extern int shutdownf;
extern int goon;
using namespace std;
const int BUF_SIZE = 2048;
//发送数据包
typedef struct message
{
int action; //命令
int book_id; //书id
int stu_id; //学生id
int day;
char bookname[64];
char send1[2048];
}mgc;
class MySocket
{
public:
MySocket(int port, char* ip);
~MySocket();
void connectToServer();
void reveiveData(mgc *rec_data);
void sendData(mgc *send_data);
void Choose(mgc *send_data);
void find_book();
void Borrow();
void Return();
void find_book(mgc *user);
void find_idbookinf(int id);
void Borrow(mgc *send_data);
void Return(mgc *send_data);
private:
WSADATA wsd; //WSADATA变量
SOCKET sHost; //客户端套接字
SOCKADDR_IN servAddr; //服务器地址
char buf[BUF_SIZE]; //接收数据缓冲区
int retVal; //返回值
};
void sqlface1();
void sqlface2();
main.cpp↓
#include "Myhead.h"
#include
using namespace std;
int shutdownf = 0;//控制while循环
int goon = 0;//防止与服务器连接失败还进入主界面
int main()
{
cout <<" ||~●~●~●●~●~●~||"<< endl;
cout << "************正在连接服务器***********" << endl;
mgc send_data; //数据发送包
mgc recv_data; //数据接受包
MySocket MySocket(2333, "127.0.0.1");
MySocket.connectToServer();
if (goon == 0)
{
cout << "正在进入图书馆服务窗口......" << endl;
while (1)
{
MySocket.Choose(&send_data);
MySocket.sendData(&send_data);//需要返回值
ZeroMemory(&send_data, sizeof(&send_data));
MySocket.reveiveData(&recv_data);//接受反馈指令
ZeroMemory(&recv_data, sizeof(&recv_data));
if (shutdownf == 1)
{
MySocket.~MySocket();
//break;
}
}
}
else
{
cout << " o(╥﹏╥)o 糟糕,服务器连接失败了." << endl;
system("pause");
}
}
cfun.cpp↓
#include "Myhead.h"
void sqlface1()//主界面函数
{
cout << "******欢迎使用图书管理系统******" << endl;
cout << "| 1.查询 |" << endl;
cout << "| 2.借书 |" << endl;
cout << "| 3.还书 |" << endl;
cout << "| 0.退出 |" << endl;
cout << "********************************" << endl;
}
void sqlface2()//查询书目函数界面
{
cout << "*******欢迎进入查询系统********" << endl;
cout << "| 1.书名模糊查询 |" << endl;
cout << "| 2.编号查询 |" << endl;
cout << "| 3.退出 |" << endl;
cout << "*******************************" << endl;
}
//主页选项函数
void MySocket::Choose(mgc *send_data)
{
Sleep(2 * 1000);
int Bchoose;
sqlface1();
cout << "请选择你需要使用的功能:" ;
cin >> Bchoose;
while ((Bchoose<0) || (Bchoose>3))
{
cout << "输入有误!请输入正确的选项: ";
cin >> Bchoose;
}
switch (Bchoose)
{
case 1:find_book(send_data); break;//1.模糊;2.精确;
case 2:Borrow(send_data); break;//3.借书
case 3:Return(send_data); break;//4.还书
case 0:shutdownf=1; break;
}
}
//查询选项函数
void MySocket::find_book(mgc *send_data)
{
int i, Sid;
char Sname[64];
cout << "正在进入查询模式......" << endl;
Sleep(1000);
sqlface2();
cout << "请选择你需要使用的功能:";
cin >> i;
while ((i<1) || (i>3))
{
cout << "输入有误!输入正确的选项: ";
cin >> i;
}
send_data->action = i; //1.模糊;2.精确;
switch (i)
{
case 1:
{
cout << "请输入书名关键词:";
cin >> Sname;
strcpy_s(send_data->bookname, Sname);
break;
}
case 2:
{
cout << "请输入要查找书的编号bookid:";
cin >> Sid;
send_data->book_id = Sid;
break;
}
case 3:break;
default:cout << "请重新输入" << endl;
break;
}
}
void MySocket::Borrow(mgc *send_data)
{
cout << "正在进入借书系统......" << endl;
Sleep(1000);
send_data->action = 3; //借书;
int stu_id, book_id, bortime;
cout << "请输入你的学号";
cin >> stu_id;
send_data->stu_id = stu_id;
cout << endl;
cout << "请输入你要借的书的编号:";
cin >> book_id;
send_data->book_id = book_id;
cout << endl;
cout << "请输入你要借阅的天数:";
cin >> bortime;
send_data->day = bortime;
cout << endl;
}
void MySocket::Return(mgc *send_data)
{
cout << "正在进入还书系统......" << endl;
Sleep(1000);
send_data->action = 4; //还书;
int book_id;
cout << "请输入书的编号:";
cin >> book_id;
send_data->book_id = book_id;
}
/**********************以上是与界面有关的*************************/
/**********************以下是与通信有关的*************************/
MySocket::MySocket(int port, char* ip)
{
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup failed!" << endl;
}
//创建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
cout << "socket failed!" << endl;
WSACleanup();//释放套接字资源
}
servAddr.sin_family = AF_INET;
//如果编译通不过 属性 c++ 常规 sdl 改成否
servAddr.sin_addr.s_addr = inet_addr(ip);//设置服务端地址 这里表示本机
servAddr.sin_port = htons(port);
}
MySocket::~MySocket()
{
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
}
void MySocket::connectToServer()
{
//连接服务器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == retVal)
{
cout << "connect failed!" << endl;
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
goon = 1;//终止后面的进入窗口
}
else
{
cout << "*********服务器连接成功**********" << endl;
}
}
void MySocket::sendData(mgc *send_data)
{
cout << "正在向服务器发送数据......";
retVal = send(sHost, (char*)send_data, sizeof(*send_data), 0);
}
void MySocket::reveiveData(mgc *rec_data)
{
ZeroMemory(buf, BUF_SIZE);
memset(rec_data, 0, sizeof(*rec_data));
retVal = recv(sHost, buf, sizeof(*rec_data), 0); // 接收服务器端的数据
memcpy(rec_data, buf, sizeof(buf));
cout << endl<<"从服务器接收到数据:\n" << endl;
cout << "-----------------------------------------------------------" << endl;
cout<send1 << endl;
cout <<"-----------------------------------------------------------" << endl;
Sleep(3*1000);
cout << "正在返回图书馆服务窗口......" << endl;
}
Myhead.h ↓
#include "winsock2.h"
#include
#include
#include
#include
#pragma comment(lib, "ws2_32.lib") //附加依赖lib库 也可以在属性中设置
#include
#include
//using namespace std;
using std::cout;
using std::endl;
using std::thread;
extern char Sgetbookinf[2048];
extern int Aifstate;
extern int Afindstu;
extern char Agetretime[64];
extern char Agetbacktime[64];
const int BUF_SIZE = 2048;
//发送数据包
typedef struct message
{
int action; //命令
int book_id; //书id
int stu_id; //学生id
int day;
char bookname[64];
char send1[2048];
}mgc;
class MySocket
{
public:
MySocket(int port);
~MySocket();
void mybind();
void mylisten();
void myaccept(mgc* rec_data, mgc *send_data);
void reveiveData(mgc *rec_data, int fd);
void sendData(mgc *data, int fd);
void fun_thread(int t, mgc*rec_data, mgc *send_data);
private:
WSADATA wsd; //WSADATA变量
SOCKET sServer; //服务器套接字 用来监听
SOCKET sClient; //客户端套接字 连接
SOCKADDR_IN addrServ;; //服务器地址
char buf[BUF_SIZE]; //接收数据缓冲区
char sendBuf[BUF_SIZE];//返回给客户端得数据
int retVal; //返回值
};
class mysqldata{
private:
//char user[8] ; //数据库用户名
//char pswd[8] ; //数据库登录密码
// char host[18] ; //本地连接
// char databasename[8] ; //已存在需要对其操作的数据库
//unsigned int port = 3306; //接入端口号
MYSQL myCont; //句柄 数据库变量
MYSQL_RES *result; //运行结果值
MYSQL_ROW sql_row; //数据库列变量
int res;
int borrow;
int overtime;
char getretime[64];
char getbacktime[64];
char ifstate[64];
char getbookinf[2048];
public:
mysqldata();
~mysqldata();
bool sqlConnection();
void user_select_all();
void user_select_allbook();
void Choose();
void find_book();
void find_namebook(char* bookname);
void find_idbook(int id);
void find_idbookgettime(int id);
void display(MYSQL_RES* result);
void Borrow();
void find_idstu(int id);
void Update(int Stu_id, int Book_id, int bortime);
void Return();
void Updatereturn(int Book_id);
void Whetherovertime(int book_id);
void displaygettime(MYSQL_RES* result);
void find_idbookinf(int id);
void displaygetinf(MYSQL_RES* result);
void find_namebookinf(char* bookname);
};
main.cpp ↓
#include "Myhead.h"
#include
//using namespace std;
char Sgetbookinf[2048];
int Aifstate=0;
int Afindstu = 0;
char Agetretime[64];
char Agetbacktime[64];
int main()
{
cout << " ||~●~●~●●~●~●~||" << endl;
cout << "***********正在等待客户端登录************" << endl;
MySocket mysocket(2333);
mgc recv_data; //数据接收包
mgc send_data; //数据发送包
while (1)
{
mysocket.myaccept(&recv_data, &send_data);
cout << endl;
}
system("pause");
return 0;
}
sfun.cpp ↓
#include "Myhead.h"
MySocket::~MySocket()
{
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
}
MySocket::MySocket(int port)
{
//初始化套结字动态库 代码健壮
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup failed!" << endl;
}
//开始创建服务端socket
//创建套接字 AF_INET:ipv4 SOCK_STREAM:使用tcp
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
cout << "socket failed!" << endl;
WSACleanup();//释放套接字资源;
}
//服务器套接字地址
addrServ.sin_family = AF_INET;//IPv4
addrServ.sin_port = htons(port);//设置端口 建议大于1024
addrServ.sin_addr.s_addr = INADDR_ANY; //表示接受任何客户端的请求
mybind();
mylisten();
}
void MySocket::mybind()
{
//绑定套接字 绑定服务端socket 和 端口
retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)
{
cout << "bind failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
}
}
void MySocket::mylisten()
{
//开始监听
retVal = listen(sServer, 10);
if (SOCKET_ERROR == retVal)
{
cout << "listen failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
}
}
void MySocket::myaccept(mgc* recv_data,mgc *send_data)
{
//接受客户端请求
int clientfd;
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
clientfd = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);//使用sClient进行数据收发
if (INVALID_SOCKET == sClient)
// if (INVALID_SOCKET == clientfd)
{
cout << "accept failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
}
cout << "客户端【" << clientfd <<"】连接成功"<< endl;
thread t1(&MySocket::fun_thread, this, clientfd, recv_data, send_data);
t1.detach();
}
void MySocket::fun_thread(int fd, mgc*recv_data, mgc *send_data)
{
while (1)
{
reveiveData(recv_data,fd);
sendData(send_data,fd);
}
}
void MySocket::reveiveData(mgc *recv_data,int fd)
{
ZeroMemory(buf, BUF_SIZE);
retVal = recv(fd, buf, sizeof(*recv_data), 0);
if (retVal == SOCKET_ERROR)
{
cout << "error接收数据失败!" << endl;
}
else if (retVal == 0)
{
cout << "客户端【" << fd << "】已关闭" << endl;
}
else
{
memcpy(recv_data, buf, sizeof(*recv_data));
cout << "已接收到客户端数据" << recv_data << endl;
switch (recv_data->action)
{
case 1:
{
cout << "进入按书名模糊查询模式" << endl;
cout << "查找关键字为:" << recv_data->bookname<< endl;
/*************************进数据库*************************/
mysqldata MyDate;
MyDate.sqlConnection();
MyDate.find_namebook(recv_data->bookname);
}break;
case 2:
{
cout << "进入按书籍编号精确查找模式" << endl;
cout << "查找的编号为:" << recv_data->book_id << endl;
mysqldata MyDate;
MyDate.sqlConnection();
MyDate.find_idbookinf(recv_data->book_id);
}break;
case 3:
{
cout << "进入借书系统" << endl;
mysqldata MyDate;
MyDate.sqlConnection();
Afindstu = 0;
MyDate.find_idstu(recv_data->stu_id);
if (Afindstu ==0)
{
strcpy_s(Sgetbookinf, "o(╥﹏╥)o 学号验证失败,请确认您输入的学号是否正确!\n");
}
else
{
MyDate.find_idbookinf(recv_data->book_id);
ZeroMemory(Sgetbookinf, sizeof(Sgetbookinf));
if (Aifstate== 1)
{
strcpy_s(Sgetbookinf, "o(╥﹏╥)o 借书失败,该书已经被借阅!\n");
Aifstate == 0;
}
else
{
MyDate.Update(recv_data->stu_id, recv_data->book_id, recv_data->day);
strcpy_s(Sgetbookinf, "借阅成功,借书期限为 ");
char day[64];
ZeroMemory(day, sizeof(day));
itoa(recv_data->day, day, 10);
strcat_s(Sgetbookinf,day);
strcat_s(Sgetbookinf, " 天, 请按时归还\n");
}
}
}break;
case 4:
{
cout << "进入还书系统" << endl;
mysqldata MyDate;
MyDate.sqlConnection();
MyDate.find_idbookinf(recv_data->book_id);
ZeroMemory(Sgetbookinf, sizeof(Sgetbookinf));
if (Aifstate == 0)
{
strcpy_s(Sgetbookinf, "o(╥﹏╥)o 无借阅记录,请您确认要归还的书籍编号是否输入正确!\n");
}
else
{
Aifstate = 0;
MyDate.Updatereturn(recv_data->book_id);
MyDate.find_idbookgettime(recv_data->book_id);
MyDate.Whetherovertime(recv_data->book_id);
}
}break;
}
}
ZeroMemory(recv_data, sizeof(recv_data));
}
void MySocket::sendData(mgc* send_data,int fd)
{
memset(send_data, 0, sizeof(*send_data));
memcpy(send_data->send1, Sgetbookinf, sizeof(*send_data));
send(fd, (char*)send_data, sizeof(*send_data), 0);
cout << "已向客户端发送数据" <
librarymannager.cpp↓
#include "Myhead.h"
//以下到L10是STL的头文件,记得删除
#include
#include
#include
#include
#include
#include
using namespace std;
mysqldata::mysqldata(){ };
mysqldata::~mysqldata(){ };
bool mysqldata::sqlConnection()
{
mysql_init(&myCont);
if (mysql_real_connect(&myCont, "localhost", "root", "123456", "library", 3306, NULL, 0))
{
cout << "connect sucess!" << endl;
mysql_query(&myCont, "SET NAMES GBK");
return true;
}
else
{
cout << "connect failed!" << endl;
return false;
}
}
void mysqldata::find_namebook(char* bookname)
{
char ss[256];
sprintf_s(ss, "select * from book where bookname like '%%%s%%'", bookname);
res = mysql_query(&myCont, ss);
if (!res)
{
result = mysql_store_result(&myCont);
display(result);
}
}
void mysqldata::display(MYSQL_RES* result)
{
vector s;//vector
ZeroMemory(getbookinf, sizeof(getbookinf));
ZeroMemory(Sgetbookinf, sizeof(Sgetbookinf));
ZeroMemory(ifstate, sizeof(ifstate));
int row_num = 0;
row_num = mysql_num_rows(result);
if (result)
{
if (row_num != 0)
{
while (sql_row = mysql_fetch_row(result))
{
strcat_s(getbookinf, "bookid:");
strcat_s(getbookinf, sql_row[0]);
strcat_s(getbookinf, " || bookname:");
strcat_s(getbookinf, sql_row[1]);
strcat_s(getbookinf, " || bookid:");
strcat_s(getbookinf, sql_row[2]);
strcat_s(getbookinf, " || \n||state:");
strcpy_s(ifstate, sql_row[3]);
//下面到L76是用vector来打印的,记得删除L49,L83,L92
s.push_back(" vector中的信息为:\n");
s.push_back("bookid:");
s.push_back(sql_row[0]);
s.push_back(" || bookname:");
s.push_back(sql_row[1]);
s.push_back(" || bookid:\n");
s.push_back(sql_row[2]);
Aifstate = atoi(ifstate);
if (atoi(ifstate) == 0)
{
strcat_s(getbookinf, "↑该书在馆,可以借阅↑\n");
s.push_back("↑该书在馆,可以借阅↑\n");//vector
}
else
{
strcat_s(getbookinf, "↑该书已被借阅↑\n");
s.push_back("↑该书已被借阅↑\n");//vector
}
}
// cout << "查询到的书籍信息为:\n" << getbookinf << endl;
copy(s.begin(), s.end(), ostream_iterator(cout, " "));//vector
strcpy_s(Sgetbookinf, getbookinf);
}
else
{
cout << "未能找到该书!" << endl;
strcat_s(getbookinf, "未能找到该书!");
strcpy_s(Sgetbookinf, getbookinf);
}
}
else
{
cout << "查询失败!" << endl;
strcat_s(getbookinf, "查询失败!");
strcpy_s(Sgetbookinf, getbookinf);
}
if (result != NULL)
mysql_free_result(result);
}
void mysqldata::find_idbookinf(int id)
{
char ss[256];
sprintf_s(ss, "select * from book where bookid=%d", id);
res = mysql_query(&myCont, ss);
if (!res)
{
result = mysql_store_result(&myCont);
display(result);
}
}
void mysqldata::find_idstu(int id)
{
char ss[256];
int row_num = 0;
sprintf_s(ss, "select * from students where stu_id=%d", id);
res = mysql_query(&myCont, ss);//查询
if (!res)
{
result = mysql_store_result(&myCont);
row_num = mysql_num_rows(result);
if (result)
{
if (row_num == 0)
{
cout << "sql学号验证失败" << endl;
}
else
{
Afindstu = 1;
}
}
else
{
cout << "find error" << endl;
}
}
}
void mysqldata::Update(int Stu_id, int Book_id, int bortime)
{
char ss[256];
sprintf_s(ss, "update book set state=1,brodate=curdate(),redate=timestampadd(day,%d,curdate()),stu_id=%d where bookid=%d", bortime, Stu_id, Book_id);
mysql_query(&myCont, ss);
}
void mysqldata::Updatereturn(int book_id)
{
char ss[256];
sprintf_s(ss, "update book set state=0,stu_id=0,brodate=default,ReTime=TO_DAYS(redate),redate=default,BackTime=TO_DAYS(curdate()) where bookid=%d", book_id);
mysql_query(&myCont, ss);
}
void mysqldata::find_idbookgettime(int id)
{
char ss[256];
sprintf_s(ss, "select * from book where bookid=%d", id);
res = mysql_query(&myCont, ss);//查询
if (!res)
{
result = mysql_store_result(&myCont);
displaygettime(result);
}
}
void mysqldata::displaygettime(MYSQL_RES* result)
{
ZeroMemory(getretime, sizeof(getretime));
ZeroMemory(getbacktime, sizeof(getbacktime));
ZeroMemory(Agetretime, sizeof(Agetretime));
ZeroMemory(Agetbacktime, sizeof(Agetbacktime));
int row_num = 0;
row_num = mysql_num_rows(result);
if (result)
{
if (row_num != 0)
{
while (sql_row = mysql_fetch_row(result))//获取结果集中的内容
{
strcpy_s(getretime, sql_row[7]);
strcpy_s(Agetretime, getretime);
strcpy_s(getbacktime, sql_row[8]);
strcpy_s(Agetbacktime, getbacktime);
cout << "正在计算是否按期归还......" << endl;
}
}
else
{
cout << "o(╥﹏╥)o 未能找到该书!" << endl;
}
}
else
{
cout << "o(╥﹏╥)o 查询失败!" << endl;
}
if (result != NULL)
mysql_free_result(result);
}
void mysqldata::Whetherovertime(int book_id)
{
if (borrow)
{
if (strcmp(Agetretime, Agetbacktime) >= 0)
{
cout << "该同学已按期完成还书。" << endl;
strcpy_s(Sgetbookinf, "您已按期完成还书,谢谢。\n");
cout << endl;
}
else
{
int min, money;
min = atoi(Agetbacktime) - atoi(Agetretime);
money = min*0.5;
cout << endl;
cout << "o(╥﹏╥)o "<