首页 > 数据库 >从数据库中查找单词

从数据库中查找单词

时间:2024-08-24 11:51:35浏览次数:6  
标签:return temp 数据库 ret 单词 查找 sqlite3 NULL errmsg

我们知道,从文件中查找是一行一行的查找匹配,但是数据库就可以快速查找,节约时间;

我们先来讲一下大概思路(所有都为C语言);

首先使用access函数判断数据库字典有没有被创建,如果创建了就跳过创建这个步骤,要不然每次加载都会耗费很多时间(几乎1-2分钟)(等待的过程蛮漫长的);

这是使用到的头文件;

#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/*********************定义的全局变量函数***************/
sqlite3 *pdb;
char temp[4096] = {0};
char *errmsg = NULL;

这是主函数的逻辑;

int main(void)
{
    int ret = 0;
    int ok = 0;

    ok = access("/home/linux/Desktop/2024/20240822/dict.db",F_OK); //这个路径是我自己的,可以替换
    if(0 == ok)  //access函数的特性,F_OK是用于查看该文件是否存在,成功返回0
    {
        ret = Open();  //打开数据库
        if(ret == -1)  //错误处理
        {
            fprintf(stderr,"fail to sqlite_open:%s\n",sqlite3_errmsg(pdb));
            return -1;
        }
        ret = word_put();  //传入想要查询的单词
        if(ret == -1)        //错误处理
        {
            fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);
            sqlite3_free(errmsg);   //释放掉错误码的空间
            sqlite3_close(pdb);    //关闭数据库
            return -1;
        }
        return 0;
    }

    if(-1 == ok)
    {
        printf("不存在,开始创建\n");
        ret = Open();
        if(ret == -1)
        {
            fprintf(stderr,"fail to sqlite_open:%s\n",sqlite3_errmsg(pdb));
            return -1;
        }
        ret = word_creat();
        if(ret == -1)
        {
            return -1;
        }
        ret = word_put();
        if(ret == -1)
        {
            fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);
            sqlite3_free(errmsg);
            sqlite3_close(pdb);
            return -1;
        }
    }
    sqlite3_close(pdb);
    return 0;
}

打开数据库的函数;

/****************************************************/
int Open(void)
{
    int ret = 0;
    ret = sqlite3_open("dict.db",&pdb);
    if(ret != SQLITE_OK)
    {
        return -1;
    }
    return 0;
}
/*****************************************************/

创建dict 数据库,并将字典加载到数据库中;

/*************************************************/
int word_creat()
{
    int ret = 0;
    FILE *fp = NULL;;
    char *nsize = NULL;
    char *pword = NULL;
    char *pmean = NULL;
    char tempword[1024] = {0};
    sprintf(temp,"create table dict(id integer primary key asc, word text, mean text)");
    ret = sqlite3_exec(pdb,temp,NULL,NULL,&errmsg); //使用sqlite3_exec函数执行语句
    if(ret != SQLITE_OK)  //错误处理
    {
        fprintf(stderr,"fail to sqlite_exec:%s\n",errmsg);
        sqlite3_free(errmsg);
        sqlite3_close(pdb);
        return -1;
    }
    fp = fopen("dict.txt","r");  //打开字典文件
    if(NULL == fp)
    {
        perror("fail to fopen dict.txt");
        sqlite3_close(pdb);
        return -1;
    }

    while(1)
    {
        memset(temp,0,sizeof(temp));   //对temp清零
        nsize = fgets(temp,sizeof(temp),fp);  //读取一行字符串
        temp[strlen(temp)-1] = '\0';
        if(nsize == NULL)
        {
            break;
        }
        pword = strtok(temp," ");   //进行分割
        pmean = strtok(NULL,"\r\n");
        sprintf(tempword,"insert into dict values (NULL,\"%s\",\"%s\")",pword,pmean);
        ret = sqlite3_exec(pdb,tempword,NULL,NULL,&errmsg);  //插入单词和含义
        if(ret != SQLITE_OK)
        {
            fprintf(stderr,"fail to sqlite_exec11:%s\n",errmsg);
            sqlite3_free(errmsg);
            sqlite3_close(pdb);
            return -1;
        }
    }
    fclose(fp);  
    return 0;
}
/*****************************************************/

查询单词;

/*****************************************************/
int word_put(void)
{
    int ret = 0;
    char input[1024] = {0};
    printf("录入完成!\n");
    memset(temp,0,sizeof(temp));
    fgets(temp,sizeof(temp),stdin);
    temp[strlen(temp)-1] = '\0';
    sprintf(input,"select word ,mean from dict where word = \"%s\"",temp);
    ret = sqlite3_exec(pdb,input,callback,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
        return -1;
    }
    return 0;
}
/*************************************************/

回调函数;

/**************************************************/
int callback(void * arg, int column, char **pcontet, char **ptitle)
{
    printf("%s : %s\n",pcontet[0],pcontet[1]);  //打印查到的单词和意思
    return 0;
}
/****************************************************/

这里面有几个有意思的点:

1.字符串的分割;

        因为原字典里的单词长这样:a                indef art one \r\n,

        用strtok分割,第一次分割空格之前的单词,第二次分割到\r\n;

2.在加载过程中显示加载进度;

        由于加载过程中太无聊,想要一点动态显示加载进度可以这样做,

//加载单词文件时,fseek将光标偏移到最末尾      

    fseek(fp, 0, SEEK_END);

//ftell获得光表的偏移量

    tlen = ftell(fp);

//再将光标定义回开头

    rewind(fp);

这样就获得了整个文件的大小;

//读取一行信息

        pret = fgets(tmpbuff, sizeof(tmpbuff), fp);

//获得这一行的大小

        clen = ftell(fp);

//转换成double型打印

        printf("已加载: %.2lf\r", (double)clen / (double)tlen * 100);

//刷新

        fflush(fp);

加上循环,这样就可以动态显示加载进度了;

3.显示加载用时;

想要显示整个文件加载到数据库需要多长时间可以这样做;

在加载文件之前使用gettimeofday; 

gettimeofday(&start, NULL);

在加载文件完成后使用;

 gettimeofday(&end, NULL);


打印;
printf("加载数据库文件成功! 耗时: %.2lf s  CPU耗时:%.2lf s\n", ((double)(end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) / 1000000,((double)(cpuend - cpustart)) / CLOCKS_PER_SEC);

4.使用makefile

因为这个程序调用了sqlite3库,所以在编译时需要加上 -lsqlite3,要是每次都加可能比较麻烦,所以我们创建makefile文件;

.PHONY:是一个伪指令,

a.out:select_world.c
	gcc $^ -o $@ -lsqlite3
.PHONY:
clean:
	rm a.out

5.如何将加载时间压缩到极致;

第一种方法:关闭磁盘写同步

        PRAGMA synchronous = NORMAL;

第二种方法:开启事务

        begin 和 commit;

第三种办法:使用预处理SQL语句机制实现提升数据库效率

今天就到这里啦!

标签:return,temp,数据库,ret,单词,查找,sqlite3,NULL,errmsg
From: https://blog.csdn.net/2401_85258690/article/details/141474703

相关文章

  • windows系统蓝屏怎么办_Windows系统蓝屏原因查找及解决方法
    电脑蓝屏怎么办?windows蓝屏是十分常见的故障,也是十分难以解决的问题,例如软件冲突兼容性问题、系统补丁bug、超频不当、系统文件损坏、硬件驱动兼容性、虚拟内存设置不当、电脑硬件温度过高、内存硬盘等硬件损坏、内存松动等均可能造成电脑蓝屏,正因为可能性太多了,只有对症下药......
  • java 查询数据库并生成多层children
    首先,定义一个表示组织结构的简单类:publicclassOrganization{privateintid;privateintparentId;privateStringname;privateList<Organization>children;//省略构造函数、getter和setter}然后,编写一个方法来查询数据库并构建多层嵌套的......
  • SQL Server 数据库 优化 性能瓶颈
    优化sql查询,分库分表,读写分离。建立索引,分页,时间段不要太长(限制数量)。升级电脑:固态硬盘,多个cpu,万兆网口。超级大表等优化。一查询,磁盘100% lockselect*fromxx(nolock)预防为主,测试为重。建立模拟环境(测试环境),一模一样的应用环境,提前测试sql性能。真正生产中,没有时......
  • PHP与MySQL数据库是如何结合使用的?
    PHP与MySQL数据库的结合使用主要通过PHP脚本与MySQL数据库进行交互,实现数据的存储、查询、更新和删除等操作。以下是结合使用的详细步骤和方法:1:准备工作:确保PHP和MySQL环境可用。创建MySQL数据库和表,以存储数据。2:连接数据库:使用mysqli连接MySQL数据库,代码示例为:$mys......
  • 向量数据库Faiss的搭建与使用|Faiss|向量数据库|高效检索|机器学习|大规模数据
    目录1.Faiss概述1.1Faiss的背景与重要性1.2Faiss的基本概念与特点2.Faiss的安装与环境配置2.1环境要求2.2Faiss的安装2.3验证安装3.Faiss的基本使用3.1创建索引与添加向量3.2执行查询3.3向量的压缩与内存优化4.Faiss的高级功能与优化4.1GPU加速与多G......
  • 挂号信息管理系统设计(Access数据库开发的系统)
    目录摘要IAbstractII第一章绪论11.1研究工作的背景与意义11.1.1背景11.1.2意义11.2国内外研究历史与现状21.2.1国内外研究历史21.2.2国内外研究现状31.3本文的主要贡献与创新31.4本论文的结构安排4第二章系统分析与设计52.1系统概述52......
  • 【SSM系统开发】——103基于SSM的宠物领养系统设计与实现(文末附源码)源码+万字LW+说明
    ......
  • 织梦cms数据库配置文件在哪
    织梦CMS的数据库配置文件通常位于 /data/common.inc.php 文件中。在这个文件里,你可以找到与数据库连接相关的配置信息。具体的配置项包括:$cfg_dbhost:数据库地址,默认为 'localhost'。$cfg_dbname:数据库名称。$cfg_dbuser:数据库用户名。$cfg_dbpwd:数据库密码。当你需要修......
  • jmeter操作数据库
    jmeter操作数据库一、jmeter操作数据的前期工作jmeter是java语言编写的1、在操作数据库之前要安装jdbc,数据库驱动,如上图就是驱动下载驱动2、将驱动存放在指定路径下(jmeter和java的lib与lib\ext目录下)3、在jmeter的测试计划中导入驱动(浏览完成即可)4、新建一个线程:操......
  • 使用ODBC连接Sybase ASE数据库
    使用ODBC连接SybaseASE数据库1.本地连接1.1下载驱动管理器1.1.1下载驱动管理器yuminstallunixODBC.x86_64-y下载相关的包,解决pyodbc无法使用的问题:https://github.com/mkleehammer/pyodbc/wiki/Install#installing-on-linuxsudoyuminstallepel-release-ysudo......