sqlite中文乱码问题原因分析及解决

在VC++中通过sqlite3.dll接口对sqlite数据库进行操作,包括打开数据库,插入,查询数据库等,如果操作接口输入参数包含中文字符,会导致操作异常。例如调用sqlite3_open打开数据库文件,如果文件路径出现中文,就会导致打开失败。sqlite3_exec执行sql语句,如果包含中文对应字符就会变成乱码。

这是由于sqlite数据库使用的是UTF-8编码方式,而传入的字符串是ASCII编码或Unicode编码,导致字符串格式错误。解决方案是在调用sqlite接口之前,先将字符串转换成UTF-8编码,以下提供各种字符串编码转换函数。


代码如下:

//UTF-8转Unicode
std::wstring Utf82Unicode(const std::string& utf8string)
{
int widesize = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, NULL, 0);
if (widesize == ERROR_NO_UNICODE_TRANSLATION)
{
throw std::exception("Invalid UTF-8 sequence.");
}
if (widesize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<wchar_t> resultstring(widesize);
int convresult = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, &resultstring[0], widesize);
if (convresult != widesize)
{
throw std::exception("La falla!");
}
return std::wstring(&resultstring[0]);
}
//unicode 转为 ascii
string WideByte2Acsi(wstring& wstrcode)
{
int asciisize = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, NULL, 0, NULL, NULL);
if (asciisize == ERROR_NO_UNICODE_TRANSLATION)
{
throw std::exception("Invalid UTF-8 sequence.");
}
if (asciisize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<char> resultstring(asciisize);
int convresult =::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, &resultstring[0], asciisize, NULL, NULL);
if (convresult != asciisize)
{
throw std::exception("La falla!");
}
return std::string(&resultstring[0]);
}
//utf-8 转 ascii
string UTF_82ASCII(string& strUtf8Code)
{
string strRet("");
//先把 utf8 转为 unicode
wstring wstr = Utf82Unicode(strUtf8Code);
//最后把 unicode 转为 ascii
strRet = WideByte2Acsi(wstr);
return strRet;
}
///////////////////////////////////////////////////////////////////////
//ascii 转 Unicode
wstring Acsi2WideByte(string& strascii)
{
int widesize = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);
if (widesize == ERROR_NO_UNICODE_TRANSLATION)
{
throw std::exception("Invalid UTF-8 sequence.");
}
if (widesize == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<wchar_t> resultstring(widesize);
int convresult = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, &resultstring[0], widesize);
if (convresult != widesize)
{
throw std::exception("La falla!");
}
return std::wstring(&resultstring[0]);
}
//Unicode 转 Utf8
std::string Unicode2Utf8(const std::wstring& widestring)
{
int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL);
if (utf8size == 0)
{
throw std::exception("Error in conversion.");
}
std::vector<char> resultstring(utf8size);
int convresult = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, &resultstring[0], utf8size, NULL, NULL);
if (convresult != utf8size)
{
throw std::exception("La falla!");
}
return std::string(&resultstring[0]);
}
//ascii 转 Utf8
string ASCII2UTF_8(string& strAsciiCode)
{
string strRet("");
//先把 ascii 转为 unicode
wstring wstr = Acsi2WideByte(strAsciiCode);
//最后把 unicode 转为 utf8
strRet = Unicode2Utf8(wstr);
return strRet;
}

(0)

相关推荐

  • Android开发之SQLite的使用方法

    前言 SQLite是一种轻量级的小型数据库,虽然比较小,但是功能相对比较完善,一些常见的数据库基本功能也具有,在现在的嵌入式系统中使用该数据库的比较多,因为它占用系统资源很少.Android系统中也不例外,也是采用SQLite,本节中就学习下在andorid中怎样使用该数据库来存放数据,并且对SQLite完成简单的新建,更新,查询,删除等操作. 实验说明: Android中使用SQLite数据库时,需要用adb来辅助调试,如果想在windows下的cmd命令行中使用adb,必须先配置环境变量,我

  • SQLite 错误码整理

    复制代码 代码如下: #define SQLITE_OK           0   /* 成功 | Successful result *//* 错误码开始 */#define SQLITE_ERROR        1   /* SQL错误 或 丢失数据库 | SQL error or missing database */#define SQLITE_INTERNAL     2   /* SQLite 内部逻辑错误 | Internal logic error in SQLite */#

  • SQLite3中的日期时间函数使用小结

    复制代码 代码如下: import sqlite3conn = sqlite3.connect('/tmp/sqlite.db')cur = conn.cursor() 接下来干嘛呢?建一张表吧.这里需要注意的是,SQLite不支持在创建表的同时创建索引,所以要分两步走,先创建表然后再创建索引 复制代码 代码如下: create_table_stmt = '''CREATE TABLE IF NOT EXISTS test_table ( id INTEGER PRIMARY KEY AUTOI

  • SQLite优化方法

    例如:向数据库中插入100万条数据,在默认的情况下如果仅仅是执行 sqlite3_exec(db, "insert into name values 'lxkxf', '24'; ", 0, 0, &zErrMsg); 将会重复的打开关闭数据库文件100万次,所以速度当然会很慢.因此对于这种情况我们应该使用"事务". 具体方法如下:在执行SQL语句之前和SQL语句执行完毕之后加上 rc = sqlite3_exec(db, "BEGIN;"

  • SQLite 中文指南之FAQ第1/6页

    1. 如何创建自增字段? 2. SQLite 支持哪些数据类型? 3. 为什么能向 SQLite 数据库的整型字段中插入字符串? 4. 为什么 SQLite 认为表达式 '0'=='00' 为真? 5. 为什么 SQLite 不允许在同一张表里使用 '0' 和 '0.0' 作为两个不同的行的主键? 6. 为什么不能在 Linux box 中读取在 SparcStation 中创建的 SQLite 数据库? 7. 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 8. SQL

  • Sqlite 常用函数 推荐

    1 .打开数据库: 说明:打开一个数据库,文件名不一定要存在,如果此文件不存在, sqlite 会自动创建.第一个参数指文件名,第二个参数则是定义的 sqlite3 ** 结构体指针(关键数据结构),这个结构底层细节如何,您不用管它. int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); 返回值:表示操所是否正确 (

  • sQlite常用语句以及sQlite developer的使用与注册

    前言 sQlite是开发中比较常用的轻量级数据库.通常只占据几百k的内存空间,所以在ios开发中,苹果将sQlite作为数据库应用在苹果开发中,当然,fmdb就另当别论了.这里主要是为了区分sQlite语句,以及mySql语句,以及Oracle之间的区别. sQlite的常用语句归纳 1.创建表语句 create table create table student( id integer primary key autoincrement, name varchar(20) not null,

  • sqlite3 top的查询及limit语法介绍

    其实,在sqlite3中没有top的语法结构,但在sqlite3中有相关的语法能实现跟top语法相同的功能,sqlite3 sql是用limit这样的语法来实现的: 如: 复制代码 代码如下: select * from table where name='_安静ゝ' order by id limit 0,10; 这个效果就相当于select top 10 * from table where name='_安静ゝ': 如果还有更精确的: 复制代码 代码如下: select * from ta

  • SQLite中的B-Tree实现细节分析

    SQLite在存储在外部的数据库是以B-Tree来组织的.关于B-tree的细节,参考 ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. ** 基本思想是文件包含的每一页都包括N个数据库入口和N+1

  • sqlite中文乱码问题原因分析及解决

    在VC++中通过sqlite3.dll接口对sqlite数据库进行操作,包括打开数据库,插入,查询数据库等,如果操作接口输入参数包含中文字符,会导致操作异常.例如调用sqlite3_open打开数据库文件,如果文件路径出现中文,就会导致打开失败.sqlite3_exec执行sql语句,如果包含中文对应字符就会变成乱码. 这是由于sqlite数据库使用的是UTF-8编码方式,而传入的字符串是ASCII编码或Unicode编码,导致字符串格式错误.解决方案是在调用sqlite接口之前,先将字符串转换

  • 后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法

    1.问题: 后端接收不到AngularJs中$http.post发送的数据,总是显示为null 示例代码: $http.post(/admin/KeyValue/GetListByPage, { pageindex: 1, pagesize: 8 }) .success(function(){ alert("Mr靖"); }); 代码没有错,但是在后台却接收不到数据,这是为什么呢? 用火狐监控:参数是JSON格式 用谷歌监控:传参方式是request payload 可以发现传参方式是

  • C#解析json字符串总是多出双引号的原因分析及解决办法

    json好久没用了,今天在用到json的时候,发现对字符串做解析的时候总是多出双引号. 代码如下: string jsonText = "{'name':'test','phone':'18888888888'}"; JObject jo = (JObject)JsonConvert.DeserializeObject(jsonText); string zone = jo["name"].ToString(); string zone_en = jo["

  • 关于获取DIV内部内容报错的原因分析及解决办法

    1.错误描述 2.错误原因 由于向div中添加元素,利用append(); $("#divStyle").append("<div><label>_data[i].name</label></div>"); append里面是动态数据,当请求数据为空时,获取并判断div中的内容: var divContent = $("#divStyle").html(); if(divContent == nul

  • php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法

    今天遇到GD的resizeimage 函数处理jpg后缀文件的缩略图的时候 提示该图片不是合法的jpg图片并报错 <b>Warning</b>: imagecreatefromjpeg(): gd-jpeg, libjpeg: recoverable error: Invalid SOS parameters for sequential JPEG 国内网上查了很多资料也没找到有效的解决办法,原来只要把 GD的jpeg文件支持打开即可解决 ini_set('gd.jpeg_igno

  • PHP中ID设置自增后不连续的原因分析及解决办法

    PHP中ID设置自增后不连续的原因分析如下所述: alter table tablename drop column id; alter table tablename add id mediumint(8) not null primary key auto_increment first; 每次删除把这两行家伙加上就行了 还有就是这个 使用mysqli对象中的query()方法每次调用只能执行一条SQL命令. 如果需要一次执行多条SQL命令,就必须使用mysqli对象中的 multi_que

  • PHP Header失效的原因分析及解决方法

    在PHP中用header("location:test.php")进行跳转要注意以下几点: 1.location和":"号间不能有空格,否则会出错. 2.在用header前不能有任何的输出,包括include的页面中标签"?>"后不能有空格!! 3.header后的PHP代码还会被执行. 续: 问题:header函数前输入内容 一般来说在header函数前不能输出html内容,类似的还有setcookie() 和 session 函数,这些

  • Android Force Close 出现的异常原因分析及解决方法

    一.原因: forceclose,意为强行关闭,当前应用程序发生了冲突. NullPointExection(空指针),IndexOutOfBoundsException(下标越界),就连Android API使用的顺序错误也可能导致(比如setContentView()之前进行了findViewById()操作)等等一系列未捕获异常 二.如何避免 如何避免弹出Force Close窗口 ,可以实现Thread.UncaughtExceptionHandler接口的uncaughtExcepti

  • MySQL 出现错误1418 的原因分析及解决方法

    MySQL 出现错误1418 的原因分析及解决方法 具体错误: 使用mysql创建.调用存储过程,函数以及触发器的时候会有错误符号为1418错误. ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,or READS SQL DATA in its declaration and binary logging is enabled(you *might* want to use the less safe log

  • Ajax向后台传json格式的数据出现415错误的原因分析及解决方法

    问题描述: ajax往后台传json格式数据报415错误,如下图所示 页面代码 function saveUser(){ var uuId = document.getElementById("uuid").value; var idCard = document.getElementById("idCard").value; alert(uuId+idCard); // var result = new Object(); // result.uuId = uuI

随机推荐