接口
CStringA UTF8AndMB_Convert(const CStringA &strSource, UINT nSourceCodePage, UINT nTargetCodePage); // UTF8与多字节(MultiByte)互转
CStringA UTF8ToMB(const CStringA& utf8Str);
CStringA MBToUTF8(const CStringA& MBStr);
CStringA UnicodeToUTF8(const CStringW& unicodeStr);
CStringW UTF8ToUnicode(const CStringA& utf8Str);
bool IsTextUTF8(const char* str, ULONGLONG length);
实现
// UTF8与多字节(MultiByte)互转
CStringA UTF8AndMB_Convert(const CStringA &strSource, UINT nSourceCodePage, UINT nTargetCodePage)
{
int nSourceLen = strSource.GetLength();
int nWideBufLen = MultiByteToWideChar(nSourceCodePage, 0, strSource, -1, NULL, 0);
wchar_t* pWideBuf = new wchar_t[nWideBufLen + 1];
memset(pWideBuf, 0, (nWideBufLen + 1) * sizeof(wchar_t));
MultiByteToWideChar(nSourceCodePage, 0, strSource, -1, (LPWSTR)pWideBuf, nWideBufLen);
char* pMultiBuf = NULL;
int nMiltiBufLen = WideCharToMultiByte(nTargetCodePage, 0, (LPWSTR)pWideBuf, -1, (char *)pMultiBuf, 0, NULL, NULL);
pMultiBuf = new char[nMiltiBufLen + 1];
memset(pMultiBuf, 0, nMiltiBufLen + 1);
WideCharToMultiByte(nTargetCodePage, 0, (LPWSTR)pWideBuf, -1, (char *)pMultiBuf, nMiltiBufLen, NULL, NULL);
CStringA strTarget(pMultiBuf);
delete[] pWideBuf;
delete[] pMultiBuf;
return strTarget;
}
CStringA UTF8ToMB(const CStringA& utf8Str)
{
if (IsTextUTF8(utf8Str, utf8Str.GetLength()))
{
return UTF8AndMB_Convert(utf8Str, CP_UTF8, CP_ACP);
}
return utf8Str;
}
CStringA MBToUTF8(const CStringA& MBStr)
{
return UTF8AndMB_Convert(MBStr, CP_ACP, CP_UTF8);
}
CStringA UnicodeToUTF8(const CStringW& unicodeStr)
{
char* pMultiBuf = NULL;
int nMiltiBufLen = WideCharToMultiByte(CP_UTF8, 0, unicodeStr, -1, pMultiBuf, 0, NULL, NULL);
pMultiBuf = new char[nMiltiBufLen + 1];
memset(pMultiBuf, 0, nMiltiBufLen + 1);
WideCharToMultiByte(CP_UTF8, 0, unicodeStr, -1, (char *)pMultiBuf, nMiltiBufLen, NULL, NULL);
CStringA strTarget(pMultiBuf);
delete[] pMultiBuf;
return strTarget;
}
CStringW UTF8ToUnicode(const CStringA& utf8Str)
{
UINT codepage = CP_UTF8;
if (!IsTextUTF8(utf8Str, utf8Str.GetLength()))
{
codepage = CP_ACP;
}
int nSourceLen = utf8Str.GetLength();
int nWideBufLen = MultiByteToWideChar(codepage, 0, utf8Str, -1, NULL, 0);
wchar_t* pWideBuf = new wchar_t[nWideBufLen + 1];
memset(pWideBuf, 0, (nWideBufLen + 1) * sizeof(wchar_t));
MultiByteToWideChar(codepage, 0, utf8Str, -1, (LPWSTR)pWideBuf, nWideBufLen);
CStringW strTarget(pWideBuf);
delete[] pWideBuf;
return strTarget;
}
bool IsTextUTF8(const char* str, ULONGLONG length)
{
DWORD nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节
UCHAR chr;
bool bAllAscii = true; //如果全部都是ASCII, 说明不是UTF-8
for (int i = 0; i < length; i++)
{
chr = *(str + i);
if ((chr & 0x80) != 0) // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码,但用一个字节存,最高位标记为0,o0xxxxxxx
bAllAscii = false;
if (nBytes == 0) //如果不是ASCII码,应该是多字节符,计算字节数
{
if (chr >= 0x80)
{
if (chr >= 0xFC && chr <= 0xFD)
nBytes = 6;
else if (chr >= 0xF8)
nBytes = 5;
else if (chr >= 0xF0)
nBytes = 4;
else if (chr >= 0xE0)
nBytes = 3;
else if (chr >= 0xC0)
nBytes = 2;
else
{
return false;
}
nBytes--;
}
}
else //多字节符的非首字节,应为 10xxxxxx
{
if ((chr & 0xC0) != 0x80)
{
return false;
}
nBytes--;
}
}
if (nBytes > 0) //违返规则
{
return false;
}
if (bAllAscii) //如果全部都是ASCII, 说明不是UTF-8
{
return false;
}
return true;
}
测试代码
CStringW str("中文");
CStringA utf8Str = UnicodeToUTF8(str);
CStringW unicodeStr = UTF8ToUnicode(utf8Str);
CStringA mbStr = UTF8ToMB(utf8Str);
CStringW unicodeStr2 = UTF8ToUnicode(mbStr);
CStringA utr8Str2 = MBToUTF8(mbStr);
CStringW unicodeStr3 = UTF8ToUnicode(utr8Str2);
阅读数: 650