当前位置: 首页 > news >正文

0821 sqlite3_get_table函数(数据库函数的补充)

Part 1.电子词典代码

一.功能

客户端可以注册登录退出(一级导航栏),查词查找自己查询的记录和返回上一级导航栏(二级导航栏)

服务器端需创建用户数据库(信息表和记录表)和单词数据库,并完成与客户端的反馈和完成其功能。

二.服务器端

#include<myhead.h>#define SER_PORT 8888
#define SER_IP "192.168.109.31"//创建单词数据库和数据表
sqlite3 * create_cindb()
{sqlite3 * dicp = NULL;if(sqlite3_open("./dic.db",&dicp) != SQLITE_OK){    printf("dic.db sqlite3_open error, errcode = %d,errmsg = %s\n",sqlite3_errcode(dicp),sqlite3_errmsg(dicp));return NULL;}printf("单词数据库创建完成\n");char *sql = "create table if not exists DICTABLE(dic char,dir char);";char *errmsg = NULL;if(sqlite3_exec(dicp,sql,NULL,NULL,&errmsg) != SQLITE_OK){printf("dic.db.DICTABLE create table error:%s\n",errmsg);sqlite3_free(errmsg);return NULL;}return dicp;
}//创建用户数据库和数据表
sqlite3 * create_usrdb()
{sqlite3 * usrp = NULL;if(sqlite3_open("./usr.db",&usrp) != SQLITE_OK){printf("usr.db sqlite3_open error, errcode = %d,errmsg = %s\n",sqlite3_errcode(usrp),sqlite3_errmsg(usrp));return NULL;}printf("用户数据表创建成功\n");//用户信息表char *msgsql = "create table if not exists USRMSG(usrname char,usrpwd char,usrtext int);";char *msgerrmsg = NULL;if(sqlite3_exec(usrp,msgsql,NULL,NULL,&msgerrmsg) != SQLITE_OK){printf("usr.db.USRMSG create table error\n");sqlite3_free(msgerrmsg);return NULL;}//用户记录表char *mrysql = "create table if not exists USRMRY(usrname char,memory char,time char);";char *mryerrmsg = NULL;if(sqlite3_exec(usrp,mrysql,NULL,NULL,&mryerrmsg) != SQLITE_OK){printf("usr.db.USRMSG create table error\n");sqlite3_free(mryerrmsg);return NULL;}return usrp;
}//读取文件录入单词和注释
int dicin(FILE * fp,sqlite3 * dicp)
{char str[128] = "";    char dic[128] = "";char dir[128] = "";while(fgets(str, sizeof(str), fp) != NULL) {// 去除换行符str[strcspn(str, "\n")] = '\0';// 重置变量dic[0] = '\0';dir[0] = '\0';int word_len = 0;// 找到第一个空格的位置for(int i = 0; i < strlen(str); i++) {if(str[i] == ' ') {word_len = i;break;}}// 将单词复制到dic内if(word_len > 0) {strncpy(dic, str, word_len);dic[word_len] = '\0';} else strcpy(dic, str);//将注释复制到dir内if(word_len > 0 && word_len < strlen(str)) {int comment_start = word_len + 1;strcpy(dir, str + comment_start);}char sql[128] = "";sprintf(sql,"insert into DICTABLE values(\"%s\",\"%s\");",dic,dir);char * errmsg = NULL;if(sqlite3_exec(dicp,sql,NULL,NULL,&errmsg) != SQLITE_OK){printf("insert error :%s\n",errmsg);sqlite3_free(errmsg);return -1;}}printf("单词录入完成\n");return 0;
}//登录函数
int login(sqlite3 * usrp, int num, char *name, char *pwd, int new_fd)
{        char createsql[128] = "";        char * createerrmsg = NULL;        char loginsql[128] = "";        char * loginerrmsg = NULL;    char **resPtr = NULL;    int rows = 0;int clos = 0;char response[2] = "";switch(num){case 1: // 注册sprintf(createsql,"insert into USRMSG values(\"%s\",\"%s\",%d);",name,pwd,0);if(sqlite3_exec(usrp,createsql,NULL,NULL,&createerrmsg) != SQLITE_OK){printf("create error :%s\n",createerrmsg);sqlite3_free(createerrmsg);strcpy(response, "0"); // 注册失败send(new_fd, response, strlen(response), 0);return -1;}strcpy(response, "1"); // 注册成功send(new_fd, response, strlen(response), 0);break;case 2: // 登录sprintf(loginsql,"select * from USRMSG where usrname = \"%s\";",name);if(sqlite3_get_table(usrp,loginsql,&resPtr,&rows,&clos,&loginerrmsg) != SQLITE_OK){printf("login select error:%s\n",loginerrmsg);sqlite3_free(loginerrmsg);strcpy(response, "0"); // 登录失败send(new_fd, response, strlen(response), 0);return -1;}// 检查是否找到用户if(rows == 0){strcpy(response, "0"); // 用户不存在send(new_fd, response, strlen(response), 0);sqlite3_free_table(resPtr);return 0;}char *db_pwd = resPtr[clos + 1]; // 密码列char *db_status = resPtr[clos + 2]; // 状态列if(strcmp(db_status, "0") == 0) // 检查是否为已登录状态{if(strcmp(db_pwd, pwd) == 0) // 检查密码是否正确{char updsql[128] = "";sprintf(updsql,"update USRMSG set usrtext = 1 where usrname = \"%s\";",name);char * upderrmsg = NULL;if(sqlite3_exec(usrp,updsql,NULL,NULL,&upderrmsg) != SQLITE_OK){printf("update error :%s\n",upderrmsg);sqlite3_free(upderrmsg);strcpy(response, "0"); // 更新状态失败send(new_fd, response, strlen(response), 0);sqlite3_free_table(resPtr);return -1;}strcpy(response, "1"); // 登录成功send(new_fd, response, strlen(response), 0);sqlite3_free_table(resPtr);return 1;}else{strcpy(response, "0"); // 密码错误send(new_fd, response, strlen(response), 0);sqlite3_free_table(resPtr);return 0;}}else if(strcmp(db_status, "1") == 0){strcpy(response, "2"); // 已有账号在线send(new_fd, response, strlen(response), 0);sqlite3_free_table(resPtr);return 2;}sqlite3_free_table(resPtr);return 0;}return 0;
}//时间函数
char* mymktime()
{time_t a = time(NULL);struct tm *p = localtime(&a);static char str[128] = "";sprintf(str,"%d.%d.%d %02d:%02d:%02d",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);return str;
}//查询单词和查询数据函数
int dic_select(int num,sqlite3 * dicp,sqlite3 * usrp,char * str,char * name,int new_fd)
{char dicslg[128] = "";char imeyslg[128] = "";char smeyslg[128] = "";char *errmsg = NULL;char *mrymsg = NULL;char **resPtr = NULL;int rows = 0;int clos = 0;char rbuf[128] = "\0";switch(num){case 1:sprintf(dicslg,"select * from DICTABLE where dic = \"%s\";",str);if(sqlite3_get_table(dicp,dicslg,&resPtr,&rows,&clos,&errmsg) != SQLITE_OK)//查询单词注释{printf("dic select error:%s\n",errmsg);sqlite3_free(errmsg);return -1;}if(rows > 0){char *time =  mymktime();//时间函数sprintf(imeyslg,"insert into USRMRY values(\"%s\",\"%s\",\"%s\");",name,str,time);//记录插入到数据库(usrp.USRMRY),格式:用户名 单词 时间if(sqlite3_exec(usrp,imeyslg,NULL,NULL,&mrymsg) != SQLITE_OK){printf("memory insert error :%s\n",mrymsg);sqlite3_free(mrymsg);}sprintf(rbuf,"%s\t%s",resPtr[clos], resPtr[clos+1]); // 使用动态索引send(new_fd,rbuf,strlen(rbuf),0);}else{sprintf(rbuf, "未找到单词: %s", str);send(new_fd, rbuf, strlen(rbuf), 0);}sqlite3_free_table(resPtr);break;case 2:sprintf(smeyslg,"select * from USRMRY where usrname = \"%s\";",name);//查询数据if(sqlite3_get_table(usrp,smeyslg,&resPtr,&rows,&clos,&errmsg) != SQLITE_OK){printf("memory select error:%s\n",errmsg);sqlite3_free(errmsg);return -1;}for(int i = 1; i <= rows; i++) // 从1开始,跳过列名{memset(rbuf,0,sizeof(rbuf));for(int j = 0; j < clos; j++){strcat(rbuf,resPtr[i*clos+j]);if(j < clos -1)strcat(rbuf,"\t");}strcat(rbuf,"\n");send(new_fd,rbuf,strlen(rbuf),0);}sqlite3_free_table(resPtr);break;}return 0;
}// 更新用户登录状态为离线
void update_user_offline(sqlite3 *usrp, char *username)
{if(username[0] != '\0'){char updsql[128] = "";sprintf(updsql,"update USRMSG set usrtext = 0 where usrname = \"%s\";",username);char * upderrmsg = NULL;if(sqlite3_exec(usrp,updsql,NULL,NULL,&upderrmsg) != SQLITE_OK){printf("update offline error :%s\n",upderrmsg);sqlite3_free(upderrmsg);}elseprintf("用户 %s 已离线\n", username);}
}int main(int argc, const char *argv[])
{// 删除旧的数据库文件if(access("./dic.db", F_OK) == 0){system("rm dic.db");printf("单词数据库删除完成\n");}if(access("./usr.db", F_OK) == 0){system("rm usr.db");printf("用户数据库删除完成\n");}//创建单词数据库和数据表sqlite3 * dicp = create_cindb();if(dicp == NULL){printf("创建单词数据库失败\n");return -1;}//创建用户数据库和数据表sqlite3 * usrp = create_usrdb();if(usrp == NULL){printf("创建用户数据库失败\n");sqlite3_close(dicp);return -1;}FILE* fp = fopen("./dict.txt", "r");if (fp == NULL){ERR_MSG("open error");sqlite3_close(dicp);sqlite3_close(usrp);return -1;}dicin(fp,dicp);fclose(fp);int sfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == sfd){ERR_MSG("socket error");sqlite3_close(dicp);sqlite3_close(usrp);return -1;}struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);if(-1 == bind(sfd,(struct sockaddr *)&sin,sizeof(sin))){ERR_MSG("bind error");close(sfd);sqlite3_close(dicp);sqlite3_close(usrp);return -1;}if(-1 == listen(sfd,128)){ERR_MSG("listen error");close(sfd);sqlite3_close(dicp);sqlite3_close(usrp);return -1;}struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);while(1){int new_fd = accept(sfd,(struct sockaddr *)&cin,&addrlen);if(-1 == new_fd){ERR_MSG("accept error");continue;}pid_t pid = fork();if(pid > 0)close(new_fd);else if(pid == 0){    close(sfd);int flag = 0;char logname[128] = ""; // 存储登录的用户名while(1)//用户可以注册或者登录或者退出{char rbuf[128] = "";int res = recv(new_fd,rbuf,sizeof(rbuf)-1,0);if(res <= 0){if(res == 0)printf("客户端断开连接\n");else{perror("recv error");}// 更新用户状态为离线update_user_offline(usrp, logname);close(new_fd);exit(0);}rbuf[res] = '\0'; // 确保字符串结束if(rbuf[0] == '1')//注册{int createnum = 1;char crename[128] = "";char crepwd[128] = "";if(sscanf(rbuf + 2,"%s %s",crename,crepwd) == 2) login(usrp,createnum,crename,crepwd,new_fd);}else if(rbuf[0] == '2')//登录{int loginnum = 2;char logpwd[128] = "";if(sscanf(rbuf + 2,"%s %s",logname,logpwd) == 2) {flag = login(usrp,loginnum,logname,logpwd,new_fd);if(flag == 1)printf("%s登录成功\n",logname);}if(flag == 1)//如果成功登录,则可以进行查词或者查记录或者退出{while(1){char newrbuf[128] = "";int res = recv(new_fd,newrbuf,sizeof(newrbuf)-1,0);if(res <= 0){if(res == 0)printf("客户端断开连接\n");elseperror("recv error");// 更新用户状态为离线update_user_offline(usrp, logname);close(new_fd);exit(0);}newrbuf[res] = '\0'; // 确保字符串结束if(newrbuf[0] == '1') // 查单词{int dicnum2 = 1;char dicstr[128] = "";strcpy(dicstr,newrbuf+2);dic_select(dicnum2,dicp,usrp,dicstr,logname,new_fd);}else if(newrbuf[0] == '2') // 查记录{int mrynum2 = 2;char mrystr[128] = "";strcpy(mrystr,newrbuf+2);dic_select(mrynum2,dicp,usrp,mrystr,logname,new_fd);}else if(newrbuf[0] == '3') // 返回主菜单{// 更新用户状态为离线update_user_offline(usrp, logname);flag = 0;break;}}}}}        }elseERR_MSG("fork error");}sqlite3_close(dicp);sqlite3_close(usrp);close(sfd);return 0;
}

三.客户端

#define SER_PORT 8888
#define SER_IP "192.168.109.31"#include<myhead.h>// 连接服务器
int connect_server() 
{int sfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sfd){ERR_MSG("socket error");}struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);if (-1 == connect(sfd, (struct sockaddr*)&sin, sizeof(sin))) ERR_MSG("connect error");return sfd;
}// 主菜单
int main_menu() {printf("\n========== 电子词典 ==========\n");printf("1. 注册\n");printf("2. 登录\n");printf("3. 退出\n");printf("请选择操作: ");int choice;scanf("%d", &choice);while (getchar() != '\n'); return choice;
}// 二级菜单
int second_menu() 
{printf("\n========== 功能菜单 ==========\n");printf("1. 查单词\n");printf("2. 查记录\n");printf("3. 返回主菜单\n");printf("请选择操作: ");int choice;scanf("%d", &choice);while (getchar() != '\n'); return choice;
}// 注册功能
int register_user(int sfd) 
{char username[128] = "";char password[128] = "";char send_buf[256] = "";printf("\n========== 用户注册 ==========\n");printf("请输入用户名: ");scanf("%s", username);printf("请输入密码: ");scanf("%s", password);snprintf(send_buf, sizeof(send_buf), "1 %s %s", username, password);if (send(sfd, send_buf, strlen(send_buf), 0) < 0)ERR_MSG("send error");printf("注册请求已发送,等待服务器响应...\n");
}// 登录功能
int login_user(int sfd, char *username) 
{char password[128] = "";char send_buf[256] = "";char recv_buf[128] = "";printf("\n========== 用户登录 ==========\n");printf("请输入用户名: ");scanf("%s", username);printf("请输入密码: ");scanf("%s", password);// 格式化发送数据: "2 用户名 密码"snprintf(send_buf, sizeof(send_buf), "2 %s %s", username, password);// 发送登录请求if (send(sfd, send_buf, strlen(send_buf), 0) < 0) ERR_MSG("send error");// 接收服务器响应int res = recv(sfd, recv_buf, sizeof(recv_buf) - 1, 0);if (res < 0) ERR_MSG("recv error");recv_buf[res] = '\0';// 解析服务器响应if (strcmp(recv_buf, "1") == 0) {printf("登录成功!\n");return 1;} else if (strcmp(recv_buf, "2") == 0) {printf("该用户已在线!\n");return 0;} else {printf("用户名或密码错误!\n");return 0;}
}// 查询单词功能
int query_word(int sfd, const char *username) 
{char word[128] = "";char send_buf[256] = "";char recv_buf[512] = "";printf("\n========== 查询单词 ==========\n");printf("请输入要查询的单词: ");scanf("%s", word);snprintf(send_buf, sizeof(send_buf), "1 %s", word);// 发送查询请求if (send(sfd, send_buf, strlen(send_buf), 0) < 0) ERR_MSG("send error");int res = recv(sfd, recv_buf, sizeof(recv_buf) - 1, 0);if (res < 0) ERR_MSG("recv error");recv_buf[res] = '\0';printf("查询结果: %s\n", recv_buf);
}// 查询记录功能
int query_history(int sfd, const char *username) 
{char send_buf[256] = "";char recv_buf[1024] = "";printf("\n========== 查询记录 ==========\n");// 格式化发送数据: "2 用户名"snprintf(send_buf, sizeof(send_buf), "2 %s", username);// 发送查询请求if (send(sfd, send_buf, strlen(send_buf), 0) < 0) ERR_MSG("send error");// 接收服务器响应printf("查询记录:\n");while (1) {int res = recv(sfd, recv_buf, sizeof(recv_buf) - 1, 0);if (res < 0)ERR_MSG("recv error");if (res == 0) break;         recv_buf[res] = '\0';if (strstr(recv_buf, "END") != NULL) {char *end_pos = strstr(recv_buf, "END");*end_pos = '\0';printf("%s", recv_buf);break;}printf("%s", recv_buf);}
}int main() 
{int sfd;int logged_in = 0;char username[128] = "";while (1) {if (!logged_in) {int choice = main_menu();sfd = connect_server();switch (choice) {case 1: register_user(sfd);close(sfd);break;case 2: if (login_user(sfd, username)){logged_in = 1;} else {close(sfd);}break;case 3: exit(0);default:printf("无效选择,请重新输入!\n");close(sfd);break;}} else {int choice = second_menu();switch (choice) {case 1: query_word(sfd, username);break;case 2: query_history(sfd, username);break;case 3: printf("返回主菜单...\n");close(sfd);logged_in = 0;break;default:printf("无效选择,请重新输入!\n");break;}}}return 0;
}

Part 2.sqlite3_get_table函数

一.功能

功能:通过执行sql语句,得到结果集中的内容

二.函数原型

int sqlite3_get_table( sqlite3 *db,

const char *zSql,

char ***pazResult, 

int *pnRow, 

int *pnColumn,

char **pzErrmsg 

); 

三.参数

sqlite3 *db:数据库句柄

const char *zSql:要执行的sql语句

char ***pazResult:查询结果的起始地址,需要定义一个二级指针变量,将地址进行传递

int *pnRow: 查询结果的行数(不包括表头)

int *pnColumn:查询结果的列数

char **pzErrmsg :错误信息 

http://www.dtcms.com/a/342928.html

相关文章:

  • Nacos-9--认识Nacos中的Distro协议(Nacos高可用的实现原理)
  • visual studio编译的软件查找所依赖的运行库方法
  • 基于单片机智能路灯控制
  • 学习嵌入式第三十四天
  • 杂记 07
  • BGP高级特性
  • AI论文速读 | 多模态能否助力时间序列预测?时序预测中融合文本的边界与条件
  • Oracle CLOB类型转换
  • 数据分析三剑客
  • 如何解读京东按图搜索(拍立淘)API(jd.item_search_img)的返回值
  • AI大模型支持下的:CMIP6数据分析与可视化、降尺度技术与气候变化的区域影响、极端气候分析
  • JVM-(7)堆内存逻辑分区
  • 3个脱节,5大特征,1套方法:破解AI落地难题
  • 37、需求预测与库存优化 (快消品) - /供应链管理组件/fmcg-inventory-optimization
  • 【互动屏幕】大屏拼接在数字展厅展示上有哪些优势?
  • (CVPR-2025)通过频率分解实现身份保持的文本到视频生成
  • 【音视频】闭合GOP和开放GOP
  • 旅游小程序开发指南
  • 第三阶段数据库-5:数据库的主键,索引,约束,表间关系的图形化操作
  • 8.Shell脚本修炼手册---sed工具的基本使用
  • HarmonyOS 实战:6 种实现实时数据更新的方案全解析(含完整 Demo)
  • JavaScript中的深浅拷贝
  • Llama-Factory微调 Qwen2.5-VL-3B 模型
  • 人工智能未来趋势如何?
  • 【秋招笔试】2025.08.19百度秋招机考第一套
  • 算法训练营day57 图论⑦ prim算法精讲、kruskal算法精讲
  • 前端无感刷新 Token 的 Axios 封装方案
  • Github 下载加速--2025-08-21 亲测好用
  • 神经网络(Neural Network, NN)
  • gemini cli 用命令行玩转 AI 多模态开发