sqlite3在VS下显示汉字乱码问题解决

来源:互联网 发布:淘宝联盟提现不了 编辑:程序博客网 时间:2024/06/06 04:13

本人学生一枚,遇到问题后,查阅很多资料所写,如有错误请指正。
所用环境:VS2015 sqlite3

问题

window操作系统默认字符集为gbk,sqlite3数据(汉字)是以utf-8的形式保存的所以要进行转化。

概念简介

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。缩写 USC。见《百度百科》
Unicode全称”Universal Multiple-Octet Coded Character Set”,简称为UCS。
UCS只是规定如何编码,然而并没有规定如何传输、保存这个编码。所以就有了UTF-8,UTF-16,UTF-32等方式。
UTF-8就是以8位为单元对UCS进行编码,UTF代表 UCS Transformation Format,即是对UCS的一种实现方式。

“GB2312”是指国家1980年的一个标准《中华人民共和国国家标准信息交换用汉字编码字符集 基本集 GB 2312-80》

解决方案

步骤1

百度查知
wchar_t是C/C++的字符类型,是一种扩展的存储方式,wchar_t类型主要用在国际化程序的实现中,但它不等同于uni编码。uni编码的字符一般以wchar_t类型存储。

字符串是多字符型,unicode要使用宽字符型。
需要用到MultiByteToWideChar,将char* 转换为wchar_t*
函数声明如下

int MultiByteToWideChar(UINT CodePage,DWORD dwFlags,LPCSTR lpMultiByteStr,int cchMultiByte,LPWSTR lpWideCharStr,int cchWideChar);

以下链接详细讲解参数含义
参数详细讲解
CodePage 编码方式
dwFlags 编码时转换选项
lpMultiByteStr 字符串

cchMultiByte:指定由参数lpMultiByteStr指向的字符串中字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1。

LPWSTR缓冲区
cchWideChar 宽字符数

返回值:如果函数运行成功,并且cchWideChar不为零,返回值是由lpWideCharStr指向的缓冲区中写入的宽字符数;如果函数运行成功,并且cchWideChar为零,返回值是接收到待转换字符串的缓冲区所需求的宽字符数大小。

MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);

步骤2

讲宽字符映射回gb
注释,在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码
用到另一个映射函数WideCharToMultiByte
该函数映射一个unicode字符串到一个多字节字符串。
详细内容见下链接
详解

int WideCharToMultiByte(UINT CodePage, //指定执行转换的代码页DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区int cchMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE);
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);

CP_ACP:ANSI代码页

步骤3(改VS配置)

需要调整以下VS项目 属性-项目-常规-字符集属性改为多字节字符集

这里写图片描述

原因见下面链接博客
原因

您也可以不改试一试就知道有什么结果了。

完整代码

#include<string>#include<windows.h>//要转换的字符串string UTF82GB(const char* str){    string result;    WCHAR *strSrc;    TCHAR *strRes;    //获得转换缓冲区的大小    int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);    //转换缓冲区    strSrc = new WCHAR[i + 1];    //转换    MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);    //获得转换缓冲区的大小    i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);    strRes = new TCHAR[i + 1];    WideCharToMultiByte(CP_ACP, 0, strSrc, -1, strRes, i, NULL, NULL);    result = strRes;//转换为string 便于cout输出    delete[]strSrc;    delete[]strRes;    return result;}

其他办法

用printf输出时,也可以在命令行输,chcp 65001,并在属性中修改字体为Lucida Console,但是这种方法只能显示汉字不能输入汉字。。。。

0 0
原创粉丝点击