返回> 网站首页
C++调用sqlite中文乱码问题
yoours2026-04-18 12:39:43
简介一边听听音乐,一边写写文章。
一、字符串转换时需要先将ANSI转换成UTF8
// UTF-8 转 GB2312/GBK (CP936)
string CUtil::Utf8ToGbk(const string utf8Str)
{
return utf8Str;
if (utf8Str.empty())
return "";
// 1. UTF-8 转 Unicode (UTF-16)
int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
if (unicodeLen == 0)
return "";
wstring wstr(unicodeLen, L'\0');
MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wstr[0], unicodeLen);
// 2. Unicode 转 GB2312 (GBK, 代码页 936)
int gbkLen = WideCharToMultiByte(936, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
if (gbkLen == 0)
return "";
string gbkStr(gbkLen, '\0');
WideCharToMultiByte(936, 0, wstr.c_str(), -1, &gbkStr[0], gbkLen, NULL, NULL);
// 移除末尾的 '\0'(如果存在)
if (!gbkStr.empty() && gbkStr.back() == '\0')
gbkStr.pop_back();
return gbkStr;
}
// GB2312/GBK (CP936) 转 UTF-8
string CUtil::GbkToUtf8(const string gbkStr)
{
return gbkStr;
if (gbkStr.empty())
return "";
// 1. GBK 转 Unicode (UTF-16)
int unicodeLen = MultiByteToWideChar(936, 0, gbkStr.c_str(), -1, NULL, 0);
if (unicodeLen == 0) return "";
wstring wstr(unicodeLen, L'\0');
MultiByteToWideChar(936, 0, gbkStr.c_str(), -1, &wstr[0], unicodeLen);
// 2. Unicode 转 UTF-8
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
if (utf8Len == 0)
return "";
string utf8Str(utf8Len, '\0');
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &utf8Str[0], utf8Len, NULL, NULL);
// 移除末尾的 '\0'
if (!utf8Str.empty() && utf8Str.back() == '\0')
utf8Str.pop_back();
return utf8Str;
}
二、将 SQLITE_STATIC 改为 SQLITE_TRANSIENT
语句执行完成就会将临时变量销毁,导致sqlite3_bind_text传入变成了野指针,这会导致数存入的中文以乱码的形式存在。
SQLITE_STATIC: SQLite 不会复制数据,字符串指针在 SQLite 使用期间不会改变,
SQLITE_TRANSIENT:SQLITE复制数据,因为原始数据可能在 SQLite 使用完之前被释放或修改。
三、示例
sqlite3_bind_text(stmt, iIndex, CUtil::Instance()->GbkToUtf8(name).c_str(), -1, SQLITE_TRANSIENT);
string name = CUtil::Instance()->Utf8ToGbk((const char*)sqlite3_column_text(stmt, 1));