Windows下SQLite3中文乱码问题

在Windows下CodePage使用的是ANSI,简体中文对应的编码就是936,即GB2312。

而Web,Linux,MySQL和SQLite等数据库都是使用UTF-8编码,所以。。。当然需要进行GB2312和UTF-8之间的转换。

执行SQL语句前需要将GB2312转UTF-8:

1、将ANSI转为Unicode

2、将Unicode转为UTF-8

在回调函数中需要将UTF-8转GB2312:

1、UTF-8转Unicode

2、Unicode转ANSI

/*
Description:Convert between ANSI and UTF-8
Usage:
convert UTF-8 to ANSI:
	CodePageConvert(CP_ACP,ansi_str_out,CP_UTF8,utf8_str_in);
Conver ANSI to UTF-8:
	CodePageConvert(CP_UTF8,utf8_str_out,CP_ACP,ansi_str_in);
*/
int CodePageConvert(uint32_t uDestCodePage, void* pDestChar, uint32_t uSrcCodePage, void* pSrcChar)
{
	if (uDestCodePage == uSrcCodePage)
	{
		return -1;
	}
	if ((pDestChar == nullptr) || (pSrcChar == nullptr))
	{
		return -1;
	}
	//ANSI转UTF-8
	if ((uSrcCodePage == CP_ACP) && (uDestCodePage == CP_UTF8))
	{
		//先将ASCII码转换为Unicode编码
		int wcharlen = MultiByteToWideChar(CP_ACP, 0, (PCSTR)pSrcChar, -1, nullptr, 0);
		uint32_t cbWideCharByte = wcharlen * sizeof(wchar_t);
		void* pWideCharBuf = malloc(cbWideCharByte);
		memset(pWideCharBuf, 0x00, cbWideCharByte);
		MultiByteToWideChar(CP_ACP, 0, (PCSTR)pSrcChar, -1, (PWSTR)pWideCharBuf, cbWideCharByte);
		//将Unicode编码转换为UTF-8编码
		int u8Len = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)pWideCharBuf, -1, nullptr, 0, nullptr, FALSE);
		WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)pWideCharBuf, cbWideCharByte, (LPSTR)pDestChar, u8Len, nullptr, FALSE);
		free(pWideCharBuf);
	}
	//UTF-8转ANSI
	if ((uSrcCodePage == CP_UTF8) && (uDestCodePage == CP_ACP))
	{
		//UTF-8转Unicode
		int wcharlen = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pSrcChar, -1, nullptr, 0);
		uint32_t wchar_byte = wcharlen * sizeof(wchar_t);
		void* pUnicodeBuf = malloc(wchar_byte);
		memset(pUnicodeBuf, 0x00, wchar_byte);
		MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pSrcChar, -1, (LPWSTR)pUnicodeBuf, wcharlen);
		int aLen = WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeBuf, -1, nullptr, 0, nullptr, FALSE);
		WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeBuf, -1, (LPSTR)pDestChar, aLen, nullptr, FALSE);
		//Unicode转ANSI
		free(pUnicodeBuf);
	}
}


完整例子:

#include "sqlite3.h"
#include <stdio.h>
#include <string>

#include <Windows.h>

#pragma comment(lib,"sqlite3.lib")

int CodePageConvert(uint32_t uDestCodePage, void* pDestChar, uint32_t uSrcCodePage, void* pSrcChar);
int procresult(void* pvoid, int ncolumn, char** pcolumn_text, char** pcolumn_name);

int main()
{
	//system("chcp 65001");//设置cmd编码方式为UTF-8
	sqlite3* sqldb = nullptr;
	int res = sqlite3_open("school.db", &sqldb);
	if (res == SQLITE_OK)
	{
		char* errmsg = nullptr;
		std::string sql("INSERT INTO main.students VALUES('Camila Cabello', 3234567894, '英语', 'false', '外国语学院', '2018-12', '台湾台北')");
		char* sql8 = new char[1024];
		memset(sql8, 0x00, 1024);
		CodePageConvert(CP_UTF8, (void*)sql8, CP_ACP, (void*)sql.c_str());
		res = sqlite3_exec(sqldb, sql8, nullptr, nullptr, &errmsg);
		if (res != SQLITE_OK)
		{
			printf("Insert error:%s\n", errmsg);
		}
		sql = "select * from main.students";
		memset(sql8, 0x00, 1024);
		CodePageConvert(CP_UTF8, (void*)sql8, CP_ACP, (void*)sql.c_str());
		res = sqlite3_exec(sqldb, sql8, procresult, nullptr, &errmsg);
		if (res != SQLITE_OK)
		{
			printf("Select error:%s\n", errmsg);
		}
		sqlite3_close(sqldb);
		delete[] sql8;
	}
	else
	{
		printf("Can't open\\create database:%s\n", sqlite3_errmsg(sqldb));
	}
	system("pause");
	return 0;
}

//有多少条结果,此回调函数就会被回调多少次
static int nn = 0;
int procresult(void* pvoid, int ncolumn, char** pcolumn_text, char** pcolumn_name)
{
	if (nn == 0)
	{
		for (int i = 0; i < ncolumn; i++)
		{
			std::string utf8_str_in, ansi_str_out;
			utf8_str_in = pcolumn_name[i];
			CodePageConvert(CP_ACP, (void*)ansi_str_out.c_str(), CP_UTF8, (void*)utf8_str_in.c_str());
			//printf("%s\t", pcolumn_name[i]);
			if (i == (ncolumn - 1))
			{
				printf("%s\n", ansi_str_out.c_str());
			}
			else
			{
				printf("%s\t", ansi_str_out.c_str());
			}
		}
		nn++;
	}
	for (int i = 0; i < ncolumn; i++)
	{
		std::string utf8_str_in, ansi_str_out;
		utf8_str_in = pcolumn_text[i];
		CodePageConvert(CP_ACP, (void*)ansi_str_out.c_str(), CP_UTF8, (void*)utf8_str_in.c_str());
		//printf("%s\t", pcolumn_text[i]);
		if (i == (ncolumn - 1))
		{
			printf("%s\n", ansi_str_out.c_str());
		}
		else
		{
			printf("%s\t", ansi_str_out.c_str());
		}
	}
	//printf("\n");
	return 0;
}

/*
Description:Convert between ANSI and UTF-8
Usage:
convert UTF-8 to ANSI:
	CodePageConvert(CP_ACP,ansi_str_out,CP_UTF8,utf8_str_in);
Conver ANSI to UTF-8:
	CodePageConvert(CP_UTF8,utf8_str_out,CP_ACP,ansi_str_in);
*/
int CodePageConvert(uint32_t uDestCodePage, void* pDestChar, uint32_t uSrcCodePage, void* pSrcChar)
{
	if (uDestCodePage == uSrcCodePage)
	{
		return -1;
	}
	if ((pDestChar == nullptr) || (pSrcChar == nullptr))
	{
		return -1;
	}
	//ANSI转UTF-8
	if ((uSrcCodePage == CP_ACP) && (uDestCodePage == CP_UTF8))
	{
		//先将ASCII码转换为Unicode编码
		int wcharlen = MultiByteToWideChar(CP_ACP, 0, (PCSTR)pSrcChar, -1, nullptr, 0);
		uint32_t cbWideCharByte = wcharlen * sizeof(wchar_t);
		void* pWideCharBuf = malloc(cbWideCharByte);
		memset(pWideCharBuf, 0x00, cbWideCharByte);
		MultiByteToWideChar(CP_ACP, 0, (PCSTR)pSrcChar, -1, (PWSTR)pWideCharBuf, cbWideCharByte);
		//将Unicode编码转换为UTF-8编码
		int u8Len = WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)pWideCharBuf, -1, nullptr, 0, nullptr, FALSE);
		WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)pWideCharBuf, cbWideCharByte, (LPSTR)pDestChar, u8Len, nullptr, FALSE);
		free(pWideCharBuf);
	}
	//UTF-8转ANSI
	if ((uSrcCodePage == CP_UTF8) && (uDestCodePage == CP_ACP))
	{
		//UTF-8转Unicode
		int wcharlen = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pSrcChar, -1, nullptr, 0);
		uint32_t wchar_byte = wcharlen * sizeof(wchar_t);
		void* pUnicodeBuf = malloc(wchar_byte);
		memset(pUnicodeBuf, 0x00, wchar_byte);
		MultiByteToWideChar(CP_UTF8, 0, (LPCCH)pSrcChar, -1, (LPWSTR)pUnicodeBuf, wcharlen);
		int aLen = WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeBuf, -1, nullptr, 0, nullptr, FALSE);
		WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeBuf, -1, (LPSTR)pDestChar, aLen, nullptr, FALSE);
		//Unicode转ANSI
		free(pUnicodeBuf);
	}
}


扫描二维码关注公众号,回复: 2611603 查看本文章

猜你喜欢

转载自blog.csdn.net/Namcodream521/article/details/80302849