在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 查看本文章