上一篇我把安卓应用的db文件导出来了。再试一下PC端操作这个数据库。
下载sqlite3.h , 链接 SQLite Download Page

下载下来解压,有如下文件:

我之前有个demo工程叫CppTest的,就用这个工程测试下,把sqlite3头文件和源文件分别放到include目录和src目录,db文件放入工程根目录,如下:

修改CMakeLists.txt,配置支持c语言, 如下:
bash
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10)
# 项目名 + 语言
project(MyCppTestProject LANGUAGES CXX C)
# 设置C++标准 C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 头文件目录(让编译器能找到include里的.h)
include_directories(include)
file(GLOB SRC_FILES
*.cpp
src/*.cpp
src/*.c
)
# 过滤掉 CMake 编译器检测文件
list(FILTER SRC_FILES EXCLUDE REGEX "CMakeCXXCompilerId.cpp")
# 生成可执行文件,名字叫 main
add_executable(main ${SRC_FILES})
# 编译输出到 output 文件夹
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/output)
修改main.cpp, 测试下数据库:
cpp
#include <iostream>
#include "MyVec.h"
extern "C" {
#include "sqlite3.h"
}
using namespace std;
void testYunsuanfuChongZai();
/**
* 查询回调函数:每查到一行数据就会触发
*/
extern "C" int selectCallback(void* arg, int colCount, char** colValue, char** colName)
{
std::cout << "进入回调函数" << std::endl;
std::cout << "-------- 单条数据 --------" << std::endl;
for (int i = 0; i < colCount; ++i)
{
std::cout << colName[i] << " : " << (colValue[i] ? colValue[i] : "null") << std::endl;
}
return 0;
}
int testDB(void) {
sqlite3* db = nullptr;
// 使用绝对路径,确保文件存在
const char* dbName = "E:/cpp/projects/CppTest/todo_database.db";
int ret = sqlite3_open(dbName, &db);
if (ret != SQLITE_OK) {
std::cerr << "打开数据库失败:" << sqlite3_errmsg(db) << std::endl;
return -1;
}
std::cout << "数据库打开成功" << std::endl;
// 插入数据
char* errMsg = nullptr;
const char* insertSql = R"(
INSERT INTO account (accountName, password, nickName, note, address)
VALUES ('test001', '666888', '测试用户', 'C++写入', '测试地址');
)";
ret = sqlite3_exec(db, insertSql, nullptr, nullptr, &errMsg);
if (ret != SQLITE_OK) {
std::cerr << "插入失败:" << errMsg << std::endl;
sqlite3_free(errMsg);
sqlite3_close(db);
return -1;
}
std::cout << "数据插入成功" << std::endl;
/*
const char* selectSql = "SELECT * FROM account;";
std::cout << "===== 查询所有数据 =====" << std::endl;
ret = sqlite3_exec(db, selectSql, selectCallback, nullptr, &errMsg);
if (ret != SQLITE_OK)
{
std::cerr << "查询数据失败:" << errMsg << std::endl;
if (errMsg != nullptr)
{
sqlite3_free(errMsg);
}
}
*/
// 查询所有数据(使用 prepare + step,最安全)
sqlite3_stmt* stmt = nullptr;
const char* selectSql = "SELECT id, accountName, password, nickName, note, address FROM account;";
ret = sqlite3_prepare_v2(db, selectSql, -1, &stmt, nullptr);
if (ret != SQLITE_OK) {
std::cerr << "准备查询语句失败:" << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return -1;
}
std::cout << "\n===== 查询结果 =====" << std::endl;
int rowCount = 0;
while (sqlite3_step(stmt) == SQLITE_ROW) {
rowCount++;
std::cout << "-------- 第 " << rowCount << " 条 --------" << std::endl;
int id = sqlite3_column_int(stmt, 0);
const unsigned char* accountName = sqlite3_column_text(stmt, 1);
const unsigned char* password = sqlite3_column_text(stmt, 2);
const unsigned char* nickName = sqlite3_column_text(stmt, 3);
const unsigned char* note = sqlite3_column_text(stmt, 4);
const unsigned char* address = sqlite3_column_text(stmt, 5);
std::cout << "id: " << id << std::endl;
std::cout << "accountName: " << (accountName ? (const char*)accountName : "NULL") << std::endl;
std::cout << "password: " << (password ? (const char*)password : "NULL") << std::endl;
std::cout << "nickName: " << (nickName ? (const char*)nickName : "NULL") << std::endl;
std::cout << "note: " << (note ? (const char*)note : "NULL") << std::endl;
std::cout << "address: " << (address ? (const char*)address : "NULL") << std::endl;
std::cout.flush(); // 强制输出
}
sqlite3_finalize(stmt);
if (rowCount == 0) {
std::cout << "表中没有数据" << std::endl;
}
sqlite3_close(db);
std::cout << "数据库已关闭" << std::endl;
return 0;
}
int main()
{
setvbuf(stdout, nullptr, _IONBF, 0); // 完全禁用输出缓冲
system("chcp 65001"); // 控制台输出用UTF-8
cout << "VSCode C++ 环境正常. ok" << endl;
// 打印 C++ 标准版本
cout << "当前 C++ 标准版本: " << __cplusplus << endl;
// 显示名称
if (__cplusplus == 201103L) cout << "=> C++11\n";
else if (__cplusplus == 201402L) cout << "=> C++14\n";
else if (__cplusplus == 201703L) cout << "=> C++17\n";
else if (__cplusplus == 202002L) cout << "=> C++20\n";
else if (__cplusplus == 202302L) cout << "=> C++23\n";
testYunsuanfuChongZai();
cout << "ok ........................." << endl;
testDB();
return 0;
}
void testYunsuanfuChongZai() { // 测试运算符重载
MyVec v1(1,2);
MyVec v2(4); // 第二个参数有默认值0,可以不传
MyVec v3 = v1 + v2;
cout << v3 << endl;
cout << "v3.x: " << v3[0] << ", v3.y: " << v3[1] << endl;
}
编译之前,先执行下面命令生成Makefile:
cmake -G "MinGW Makefiles" .
再执行 mingw32-make 编译所有文件。
然后运行,打印如下:

看着有些日志没打印,重试好多次都是。 用DB Browser for SQLite工具打开这个db文件,查看下account表:

ok. 看着数据已经插入成功了。不知道为啥日志打印不全。 之前是在VS Code的控制台执行的,改为新开一个cmd窗口执行,输出如下:


ok. 说明程序是没问题的。只是日志打印有问题。先不管了。提交下代码。先看下状态:

其中有些是不用提交的。在工程根目录新建 .gitignore 文件,内容如下:
bash
# CMake 缓存 & 构建文件
CMakeCache.txt
CMakeFiles/
Makefile
*.cmake
*.rsp
*.marks
# 编译产物
output/
*.exe
*.obj
*.o
*.a
*.lib
*.dll
# 日志、系统垃圾文件
*.log
.DS_Store
Thumbs.db
再执行:
git add .gitignore CMakeLists.txt main.cpp include/ src/ todo_database.db

提交,推送到gitee:

ok. 查看下gitee页面:

ok. 但是远程仓库有不需要的文件,即本地编译产物(CMakeCache.txt、CMakeFiles、Makefile、output/ 等)。
先把这些 "编译垃圾" 从 Git 跟踪里删掉(本地保留)

其中:
--cached:只删 Git 记录,本地文件还在,不影响你编译
-r:递归删文件夹
提交删除操作:

推送:

再看下 gitee该仓库:

ok. 现在不需要提交的文件删除了。