1. ANSI字符与UNICODE字符对比
Windows中ANSI字符和Unicode字符对比:
字符集 | 标识 | 长度 | 示例 |
ANSI | char | 1byte | 'A' |
UNICODE | wchar_t | 2byte | L'A' |
Windows中的字符串用法:
字符集 | 字符串 | 字符串长度 | 字符串比较 | 字符串比较 |
ANSI | "ansistring" | strlen | strcmp/strncmp | strcpy |
UNICODE | L"unicodestring" | wcslen | wcscmp/_wcsicmp | _tcscpy |
Visual Studio中切换ANSI和UNICODE:
ANSI: 使用多字节字符集 #define UNICODE 0
UNICODE: 使用UNICODE字符集 #define UNICODE 1
定义有下面:
#ifdef UNICODE // r_winnt
#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPWCH LPTCH, PTCH;
typedef LPCWCH LPCTCH, PCTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPUWSTR PUTSTR, LPUTSTR;
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
typedef LPWSTR LP;
typedef PZZWSTR PZZTSTR;
typedef PCZZWSTR PCZZTSTR;
typedef PUZZWSTR PUZZTSTR;
typedef PCUZZWSTR PCUZZTSTR;
typedef PNZWCH PNZTCH;
typedef PCNZWCH PCNZTCH;
typedef PUNZWCH PUNZTCH;
typedef PCUNZWCH PCUNZTCH;
#define __TEXT(quote) L##quote // r_winnt
#else /* UNICODE */ // r_winnt
#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPCH LPTCH, PTCH;
typedef LPCCH LPCTCH, PCTCH;
typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
typedef PZZSTR PZZTSTR, PUZZTSTR;
typedef PCZZSTR PCZZTSTR, PCUZZTSTR;
typedef PNZCH PNZTCH, PUNZTCH;
typedef PCNZCH PCNZTCH, PCUNZTCH;
#define __TEXT(quote) quote // r_winnt
#endif /* UNICODE */ // r_winnt
#define TEXT(quote) __TEXT(quote) // r_winnt
兼容Unicode和Ansi我们可以用:
TCHAR buffer[126] = {TEXT("MyBuffer")};
HANDLE hFile = CreateFile(TEXT("MyFile")...);
的方式。
2. Windows中Ansi和Unicode的字符串之间的转换
WideCharToMultiByte:
该函数映射一个字符串到一个宽字符(unicode)的字符串
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);
codePage: 指定要转换成的字符集代码页常用的如下:
CP_ACP: 实现了ANSI与Unicode之间的转换。
CP_UTF8:实现了UTF-8与Unicode之间的转换。
dwFlags: 一般设置为0
lpWideCharStr: 待转换的UNICODE字符串
cchWideChar: 待转换的字符串的长度, -1表示转换到字符串结尾。
lpMultiByteStr: 转换后的字符缓冲区
cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。
lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字 符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。
lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为 NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。
返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串 结尾的null);cbMultiByte为0,则返回转换所需 字节数。函数失败,返回0。
为了避免内存泄漏,宜先使cbMultiByte置为0,获取所需的字节数,再依据字节数申请适当的内存字节数,再调用函数进行转换。
如以下:
//
// 使用完成之后, 记得释放内存
char * UnicodeToAnsi()
{
wstring unicodeStr = L"UnicodeString字符串";
int nLen = WideCharToMultiByte(CP_ACP, 0, unicodeStr.data(), -1, NULL, 0, NULL, NULL);
char *pAnsiStr = new char[nLen + 1];
memset(pAnsiStr, 0, nLen+1);
WideCharToMultiByte(CP_ACP, 0, unicodeStr.data(), -1, pAnsiStr, nLen, NULL, NULL);
wcout.imbue(locale("chs"));
wcout << L"Unicode String: " << unicodeStr << endl;
cout << "Ansi String: " << pAnsiStr << endl;
return pAnsiStr;
}
详细参考: 百度文库相关文档
MultiByteToWideChar:
字符串映射到一个宽字符(Unicode)字符串
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cbMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar
);
lpMultiByteStr: 待转换的多字节字符串
cbMutliByte: 多字节字符串的长度,如果此参数为-1,函数处理整个输入字符串,包括'\0'终止符
lpWidCharStr: 转换的宽字符指向的缓冲区
cchWidChar: 宽字符缓冲区的大小,以宽字符为单位
返回值:如果函数调用成功,cchWideChar非零,返回值是由lpWideCharStr指向的缓冲区写入宽字符数。
如果函数调用成功,并cchWideChar为零,返回值是所需的大小,在宽字符,一个缓冲区,可以接收翻译的字符串。
以下为示例:
//
// 使用完成之后, 记得释放内存
wchar_t * AnsiToUnicode()
{
char *pAnsiStr = "ansi字符串";
int nLen = MultiByteToWideChar(CP_ACP, 0, pAnsiStr, -1, NULL, 0);
wchar_t *pUnicodeStr = new wchar_t[nLen + 1];
memset(pUnicodeStr, 0, (nLen + 1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, pAnsiStr, -1, pUnicodeStr, nLen);
cout << "Ansi: " << pAnsiStr << endl;
wcout.imbue(locale("chs"));
wcout << L"Unicode: " << pUnicodeStr << endl;
return pUnicodeStr;
}
详细参考:
百度文库文档
UTF-8字符串与Ansi和Unicode的转换,只需将CP_ACP换成CP_UTF8即可。