项目场景
项目开发中,程序 A 使用的是 Unicode 编码,程序 B 使用 UTF8 编码。A 与 B 进行网络通信,当 B 发送数据给 A,若数据中含有中文,则 A 收到的数据是乱码的。这时 A 需要将接收到的 UTF8 编码的数据转成 Unicode,同理,当 A 发送数据给 B 时,要将 Unicode 编码的数据转成 UTF8 再发送。
解决方法
来看一个例子:
// A 程序代码
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
// wstring转string
std::string WstringToString(const wstring& ws) {
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
// UTF8转Unicode
std::wstring UTF8ToUnicode(const std::string & s) {
std::wstring result;
int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
wchar_t * buffer = new wchar_t[n];
::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, n);
result = buffer;
delete[] buffer;
return result;
}
int main() {
unsigned char ucDevName[64];
// ...省略部分代码
// ucDevName[]数组中放有从 B 接收来的数据,调试看起来是乱码的
// 下面进行转换
std::string strDevName(reinterpret_cast<char*>(ucDevName));
std::wstring wstrDevName = UTF8ToUnicode(strDevName);
strDevName = WstringToString(wstrDevName);
memcpy(ucDevName, strDevName.c_str(), 64); // 这时ucDevName[]数组中数据已经正常了
return 0;
}
其他转换函数
除了上面例子的两个转换函数,下面再提供几个转换相关的函数:
void charToWchar(const char* ch, std::wstring& w_str) {
wchar_t* wchar;
int len = MultiByteToWideChar(CP_ACP, 0, ch, strlen(ch), NULL, 0);
wchar = new wchar_t[len + 1];
MultiByteToWideChar(CP_ACP, 0, ch, strlen(ch), wchar, len);
wchar[len] = '\0';
w_str = wchar;
delete[] wchar;
}
void wcharToString(std::string& szDst, wchar_t *wchar) {
wchar_t * wText = wchar;
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE); // WideCharToMultiByte的运用
char *psText; // psText为char*的临时数组,作为赋值给std::string的中间变量
psText = new char[dwNum];
WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE); // WideCharToMultiByte的再次运用
szDst = psText; // std::string赋值
delete[]psText; // psText的清除
}
// wstring版本的unicode转UTF8
std::string unicodeToUTF8_wstring(LPCWSTR lpszWideStr) {
int nLen = WideCharToMultiByte(CP_UTF8, 0, lpszWideStr, -1, nullptr, 0, nullptr, nullptr);
char *buffer = new char[nLen + 1];
ZeroMemory(buffer, nLen + 1);
WideCharToMultiByte(CP_UTF8, 0, lpszWideStr, -1, buffer, nLen, nullptr, nullptr);
string multStr = buffer;
delete[] buffer;
return multStr;
}
// string版本的unicode转UTF8
std::string unicodeToUTF8_string(const std::string &strSrc) {
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, strSrc.c_str(), -1, NULL, 0);
wchar_t * pwBuf = new wchar_t[nwLen + 1]; // 一定要加1,不然会出现尾巴
ZeroMemory(pwBuf, nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, strSrc.c_str(), strSrc.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 retStr(pBuf);
delete[]pwBuf;
delete[]pBuf;
pwBuf = NULL;
pBuf = NULL;
return retStr;
}
// string转wstring
wstring String2Wstring(const string& s) {
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}