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

Day39 SQLite数据库操作与文本数据导入

day39 SQLite数据库操作与文本数据导入

本节内容围绕使用 C 语言结合 SQLite3 库,将一个纯文本词典文件 dict.txt 中的数据导入到 SQLite 数据库中。涵盖了数据库连接、表的创建与删除、SQL 命令执行、文件读取、字符串处理等核心知识点。代码完整,逻辑清晰,适合嵌入式或系统级开发中轻量级数据存储场景的学习与应用。


🧩 知识点概览

  • 使用 sqlite3_open() 打开或创建数据库
  • 使用 sqlite3_exec() 执行 SQL 语句(建表、删表、插入)
  • 错误处理机制:sqlite3_errstr()errmsg
  • 文件操作:fopen()fgets() 逐行读取
  • 字符串分割:strtok() 提取单词与释义
  • 动态生成 SQL 插入语句:sprintf()
  • 内存管理与资源释放:sqlite3_free()fclose()sqlite3_close()

✅ 完整代码(含详细注释)

#include <sqlite3.h>   // 引入SQLite数据库操作库
#include <stdio.h>     // 引入标准输入输出库
#include <stdlib.h>    // 引入标准库(包含内存管理等函数)
#include <string.h>    // 引入字符串处理库int main(int argc, char** argv)
{sqlite3* db = NULL;       // 声明SQLite数据库连接句柄char* errmsg = NULL;      // 声明用于存储SQL操作错误信息的指针// 打开或创建名为aaa.db的数据库文件int ret = sqlite3_open("./aaa.db", &db);// 检查数据库打开是否成功if (SQLITE_OK != ret){// 输出打开数据库失败的错误信息fprintf(stderr, " sqlite3_open %s\n", sqlite3_errstr(ret));sqlite3_close(db);      // 关闭数据库连接return 1;               // 程序异常退出}char sql_cmd[1024] = {0}; // 声明用于存储SQL命令的字符数组并初始化// 删除已存在的dict表(若存在)strcpy(sql_cmd, "drop table dict");sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg);// 注意:即使表不存在,drop也会报错,但可忽略;此处未检查返回值,属于容错性设计// 清空sql_cmd数组,准备创建新表的SQL命令bzero(sql_cmd, sizeof(sql_cmd));// 复制创建dict表的SQL命令到sql_cmd,表包含id(整数)、word(字符)、dict_mean(文本)字段strcpy(sql_cmd, "create table dict(id int ,word char ,dict_mean text);");// 执行创建表的SQL命令ret = sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg);// 检查表是否创建成功if (SQLITE_OK != ret){// 输出创建表失败的错误信息,包含执行的SQL命令和具体错误fprintf(stderr, " sqlite3_exec sql_cmd:[%s] %s\n", sql_cmd, errmsg);sqlite3_free(errmsg);   // 释放错误信息占用的内存sqlite3_close(db);      // 关闭数据库连接return 1;               // 程序异常退出}// 打开指定路径下的dict.txt文件,用于读取数据FILE* fp = fopen("./dict.txt", "r");// 检查文件是否打开成功if (NULL == fp){perror("fopen");        // 输出文件打开失败的错误信息return 1;               // 程序异常退出}int num = 1;              // 声明并初始化记录序号的变量,从1开始// 循环读取文件内容,直到文件结束while (1){char linebuf[1024] = {0}; // 声明用于存储读取到的一行数据的字符数组并初始化// 从文件中读取一行数据到linebuf,若读取失败(如文件结束)则跳出循环if (NULL == fgets(linebuf, sizeof(linebuf), fp)){break;}// 使用空格分割一行数据,获取单词部分(word)char *word = strtok(linebuf, " ");// 继续分割剩余部分,以回车符为分隔符,获取释义部分(mean)char *mean = strtok(NULL, "\r");// 清空sql_cmd数组,准备生成插入数据的SQL命令bzero(sql_cmd, sizeof(sql_cmd));// 生成插入数据的SQL命令,将序号、单词、释义插入到dict表sprintf(sql_cmd, "insert into dict values(%d,\"%s\",\"%s\");", num++, word, mean);// 执行插入数据的SQL命令ret = sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg);// 检查数据是否插入成功if (SQLITE_OK != ret){// 输出插入数据失败的错误信息,包含执行的SQL命令和具体错误fprintf(stderr, " sqlite3_exec sql_cmd:[%s] %s\n", sql_cmd, errmsg);sqlite3_free(errmsg); // 释放错误信息占用的内存sqlite3_close(db);    // 关闭数据库连接fclose(fp);           // 关闭文件指针return 1;             // 程序异常退出}}fclose(fp);               // 关闭文件sqlite3_close(db);        // 关闭数据库连接return 0;                 // 程序正常退出
}

📌 代码说明与关键点解析

步骤说明
1. 数据库连接使用 sqlite3_open("./aaa.db", &db) 打开本地数据库文件,若不存在则自动创建。
2. 表结构清理与重建drop table dict 删除旧表,再 create table dict(...) 创建新表,确保环境干净。
3. 文件读取使用 fopen() 打开 /home/linux/dict.txt,逐行读取词条。每行格式应为:单词 释义(中间用空格分隔)。
4. 字符串解析使用 strtok() 第一次按空格切分出 word,第二次按 \r 切分出 mean(兼容 Windows 换行)。
5. SQL 插入语句构造使用 sprintf()idwordmean 格式化为 INSERT INTO 语句。
6. 错误处理所有 sqlite3_exec() 调用后均判断返回值,出错时打印 SQL 语句及错误信息,并释放资源退出。
7. 资源释放正确关闭文件和数据库连接,避免资源泄漏。

⚠️ 注意:

  • strtok(NULL, "\r") 可能无法正确处理 \n\r\n 换行,建议增强为 "\r\n"
  • dict.txt 中有特殊字符(如引号),可能导致 SQL 语法错误,建议使用参数化查询(但本例未使用)。

🧪 示例输入文件:dict.txt

假设 dict.txt 内容如下:

apple a fruit that grows on trees
book something you read
cat a small domesticated animal
hello greeting used when meeting someone
world the planet Earth

🧱 生成的数据库表结构

字段名类型说明
idint自增序号
wordchar单词
dict_meantext释义

✅ 理想运行结果

  1. 成功编译并运行程序:

    gcc -o dict_import dict_import.c -lsqlite3
    ./dict_import
    
  2. 生成数据库文件 aaa.db

  3. 可通过 SQLite 命令行验证数据:

    sqlite3 aaa.db
    

    在 SQLite 提示符下执行:

    select count(id) from dict;
    

    理想输出:

    5
    

    表示成功插入 5 条记录。

  4. 查看所有数据:

    SELECT * FROM dict LIMIT 5;
    

    理想输出示例:

    1|apple|a fruit that grows on trees
    2|book|something you read
    3|cat|a small domesticated animal
    4|hello|greeting used when meeting someone
    5|world|the planet Earth
    

🔚 总结

本日任务实现了 从文本文件到 SQLite 数据库的完整数据迁移流程,涉及 C 语言与数据库交互的核心技能:

  • 数据库的打开与关闭
  • 表的创建与删除
  • 动态 SQL 语句拼接
  • 文本文件解析
  • 错误处理与资源管理

该程序可用于构建小型离线词典、配置管理、日志存储等场景,是嵌入式开发中非常实用的技术组合。


文章转载自:

http://aaR38NrN.wqtzs.cn
http://jr469sGo.wqtzs.cn
http://uz4cwNmL.wqtzs.cn
http://BqHEBhNs.wqtzs.cn
http://T0BLFSpW.wqtzs.cn
http://4VFJ3EsN.wqtzs.cn
http://Tmzx8Z1s.wqtzs.cn
http://mtjifO3O.wqtzs.cn
http://cp8pHNle.wqtzs.cn
http://vuhJjszE.wqtzs.cn
http://SEz16uQY.wqtzs.cn
http://I3IZ9SWu.wqtzs.cn
http://zozAlyuA.wqtzs.cn
http://c7B6yHeA.wqtzs.cn
http://ZhSb5IGT.wqtzs.cn
http://68Dlasrr.wqtzs.cn
http://RWFGZgCT.wqtzs.cn
http://94F0rPOr.wqtzs.cn
http://6Mj3uAsZ.wqtzs.cn
http://Fbg2mUBC.wqtzs.cn
http://MWtAD0G9.wqtzs.cn
http://FtBXEnyl.wqtzs.cn
http://PefiRfeO.wqtzs.cn
http://mbtf4GLj.wqtzs.cn
http://f5s9BNgk.wqtzs.cn
http://9KuRKoFJ.wqtzs.cn
http://SZaeUijY.wqtzs.cn
http://5sg4A7G1.wqtzs.cn
http://ncOgbrwa.wqtzs.cn
http://TWN7bPkU.wqtzs.cn
http://www.dtcms.com/a/375826.html

相关文章:

  • python常用命令
  • 广东省省考备考(第九十五天9.9)——言语、资料分析、判断推理(强化训练)
  • MySQL问题8
  • 【AI】Jupyterlab中关于TensorFlow版本问题
  • Java 运行时异常与编译时异常以及异常是否会对数据库造成影响?
  • CosyVoice2简介
  • 新机快速搭建java开发环境过程记录
  • std::enable_shared_from_this
  • Spring Boot--Bean的扫描和注册
  • Pytorch基础入门3
  • ARM-指令集全解析:从基础到高阶应用
  • ARM 汇编学习
  • 今天继续昨天的正则表达式进行学习
  • Mysql集群——MHA高可用架构
  • 【一包通刷】晶晨S905L(B)/S905L2(B)/S905L3(B)-原机安卓4升级安卓7/安卓9-通刷包
  • SYSTEM 提权面板:提升文件运行权限的高效工具
  • 【Python】S1 基础篇 P6 用户交互与循环控制:构建动态交互程序
  • Java 数据类型详解
  • java常见SSL bug解决方案
  • JAVA stream().flatMap()
  • 【C++】string类 - 库中的常见使用
  • Go语言基础---数据类型间的故事
  • 金融量化指标--6InformationRatio信息比率
  • GPT Server 文档
  • CDN加速带来的安全隐患及应对方法
  • HCL Unica+:AI驱动的营销自动化与个性化平台
  • spring事务管理之@Transactional
  • golang之go modules
  • 设计UIUC SE 423机电一体化的机器人
  • 《Vuejs设计与实现》第 15 章(编译器核心技术)上