很多时候,我们的程序需要支持两种字符集,Multi-Byte与Unicode。
这时就需要进行字符串转换,以及两套API之间的切换。
对两种字符集的统一支持,本文做了一些简单总结。
1、常用转换函数
以下四个函数为Multibyte/Unicode转化基本函数,已处理内存泄露问题。
其他转换可以在这四个基本函数基础上操作。1.1. Ansi转化为Unicode
static wstring AnsiToUnicode(const string& str)
{
int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
if (unicodeLen <= 0)
{
return L"";
}
wchar_t* pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode, 0, (unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
wstring rt = pUnicode;
delete[] pUnicode;
pUnicode = NULL;
return rt;
}
1.2. Unicode转化为Ansi
static string UnicodeToAnsi(const wstring& str)
{
int iTextLen = WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
if (iTextLen <= 0)
{
return "";
}
char* pElementText = new char[iTextLen + 1];
memset(pElementText, 0, sizeof(char)*(iTextLen + 1));
::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
string strText = pElementText;
delete[] pElementText;
pElementText = NULL;
return strText;
}
1.3. UTF-8 to Unicode
static wstring UTF8ToUnicode(const string& str)
{
int unicodeLen = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
if (unicodeLen <= 0)
{
return L"";
}
wchar_t* pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode, 0, (unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
wstring rt = pUnicode;
delete[] pUnicode;
pUnicode = NULL;
return rt;
}
1.4. Unicode to UTF-8
static string UnicodeToUTF8(const wstring& str )
{
int iTextLen = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
if (iTextLen <= 0)
{
return "";
}
char* pElementText = new char[iTextLen + 1];
memset(pElementText, 0, sizeof(char) * (iTextLen + 1));
::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
string strText = pElementText;
delete[] pElementText;
pElementText = NULL;
return strText;
}
2、通用宏使用
MultiByte/Unicode两套字符集下使用API不同,目前已有通用宏来解决此问题。
具体相关宏如下表所示。
通用宏定义 | MultiByte API | Unicode API | 功能说明 |
TCHAR | char | wchar_t | 字符定义 |
_ttoi | atoi | _wtoi | 字符串转int |
_tstof | atof | _wtof | 字符串转float |
_ttoi64 | _atoi64 | _wtoi64 | 字符串转64位整型 |
_itot | itoa | _itow | int转字符串 |
_tstof | gcvt | _wtof | float转字符串 |
_tcslen | strlen | wcslen | 获取字符串长度 |
_tcsstr | strstr | wcsstr | 子字符串截取 |
_tcscpy | strcpy | wcscpy | 字符串复制 建议使用_tcscpy_s |
_stprintf_s | sprintf_s | swprintf_s | 字符串赋值 |
例如,把字符串“123”转换为int型,直接调用_ttoi(_T(“123”))即可,在Multibtye/Unicode字符集下都能正常运行。
3、控制台字符串输出
CString strTest = _T(“测试”);
#ifdef UNICODE
wcout <<(const wchar_t*)strTest <<endl;
#else
cout <<(const char*)strTest <<endl;
#endif