0%

vs中的字符串转码:Unicode与UTF-8相互转换

  1. 前言
  2. 实现代码
  3. 使用示例

前言

由于boost默认使用utf-8编码,一个中文使用三个字符表示,使用其提供的read_json方法根本无法从带有中文的字符串解析出json,要迁移到jsoncpp又面临着修改老代码的风险,因此寻求到一条出路,就是将unicode编码的字符串std::string转为utf-8编码,取的时候再进行解码,就能解决中文问题。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// UTF8转std:string
// 转换过程:先将utf8转双字节Unicode编码,再通过WideCharToMultiByte将宽字符转换为多字节。
std::string u8_(const std::string& str)
{
int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[nwLen + 1]; //一定要加1,不然会出现尾巴
memset(pwBuf, 0, nwLen * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[nLen + 1];
memset(pBuf, 0, nLen + 1);
WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

std::string strRet = pBuf;

delete[]pBuf;
delete[]pwBuf;
pBuf = NULL;
pwBuf = NULL;

return strRet;
}

// std:string转UTF8
std::string _u8(const std::string& str)
{
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[nwLen + 1]; //一定要加1,不然会出现尾巴
ZeroMemory(pwBuf, nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

std::string strRet(pBuf);

delete[]pwBuf;
delete[]pBuf;
pwBuf = NULL;
pBuf = NULL;

return strRet;
}

使用示例

1
2
3
4
5
6
7
8
// 中文字符串,Unicode编码:-42 -48 -50 -60
std::string s = "中文";

// utf8编码:-28 -72 -83 -26 -106 -121
std::string us = _u8(s);

// 转回中文编码
s = u8_(us);