Windows下提供了两个编码转换函数:WideCharToMultiByte和MultiByteToWideChar。
用它们可实现Unicode(UCS2),UTF8,GBK(GB2312)互转。这两个函数的原型是:
int WINAPI MultiByteToWideChar( __in UINT CodePage, __in DWORD dwFlags, __in_bcount(cbMultiByte) LPCSTR lpMultiByteStr, __in int cbMultiByte, __out_ecount_opt(cchWideChar) __transfer(lpMultiByteStr) LPWSTR lpWideCharStr, __in int cchWideChar); int WINAPI WideCharToMultiByte( __in UINT CodePage, __in DWORD dwFlags, __in_ecount(cchWideChar) LPCWSTR lpWideCharStr, __in int cchWideChar, __out_bcount_opt(cbMultiByte) __transfer(lpWideCharStr) LPSTR lpMultiByteStr, __in int cbMultiByte, __in_opt LPCSTR lpDefaultChar, __out_opt LPBOOL lpUsedDefaultChar);
第一个参数,CodePage,通常取两个值:
1、CP_UTF8,将Unicode与UTF8相互转换的时使用。
2、CP_ACP,Ansi Code Page,也就是计算机本地的代码页,中国大陆为936(简体中文),也就是GetACP()的返回值。Unicode与GBK相互转换时使用。
其他一些常用的代码页有:
874 | 泰语 | 932 | 日语 |
936 | 中文(简体) | 949 | 朝鲜语 |
950 | 中文(台湾和香港繁体) | 1200 | Unicode |
1250 | 东欧语言 | 1251 | 西里尔语 |
1252 | 美国和西欧语言 | 1253 | 希腊语 |
1254 | 土耳其语 | 1255 | 希伯来语 |
1256 | 阿拉伯语 | 1257 | 波罗的语 |
第二个参数,dwFlags,通常置0。
第三个参数,lpMultiByteStr或lpWideCharStr,是传入字符串的地址。
第四个参数,cbMultiByte或cchWideChar,是第三个参数的长度(cb是Count of Byte,即字节数;cch是Count of Char,即字符数)。若此值为1,字符串将被认为是以NULL结束的字符串,并且自动计算长度。
第五个参数,lpWideCharStr或lpMultiByteStr,是传出字符串的地址。
第六个参数,cchWideChar或cbMultiByte,是第五个参数的长度(cb是Count of Byte,即字节数;cch是Count of Char,即字符数)。若此值为0,函数返回目标缓冲区所必需的字符数。
后两个参数,lpDefaultChar和lpUsedDefaultChar,通常置0。只有当WideCharToMultiByte函数遇到一个宽字节字符,而该字符在uCodePage参数标识的代码页中并没有它的表示法时,WideCharToMultiByte函数才使用这两个参数。如果宽字节字符不能被转换,该函数便使用lpDefaultChar参数指向的字符。如果该参数是NULL(这是大多数情况下的参数值),那么该函数使用系统的默认字符。该默认字符通常是个问号。这对于文件名来说是危险的,因为问号是个通配符。pfUsedDefaultChar参数指向一个布尔变量,如果Unicode字符串中至少有一个字符不能转换成等价多字节字符,那么函数就将该变量置为TRUE。如果所有字符均被成功地转换,那么该函数就将该变量置为FALSE。当函数返回以便检查宽字节字符串是否被成功地转换后,可以测试该变量。
返回值,如果第五个参数为0,函数返回目标缓冲区所必须的字符数;否则,函数转换成功转换的字符数,函数失败时,返回0。
测试代码如下:
#include <windows.h> int main() { wchar_t wStr[] = L"abc高金山"; int nCodePage = CP_ACP; char *pStr = NULL; int nWCount = 0; int nCount = 0; //nCodePage = GetACP(); nCodePage = CP_UTF8; nCount = WideCharToMultiByte(nCodePage, 0, wStr, -1, NULL, 0, NULL, NULL); pStr = new char[nCount]; nCount = WideCharToMultiByte(nCodePage, 0, wStr, -1, pStr, nCount, NULL, NULL); memset(wStr, 0, sizeof(wStr)); nWCount = MultiByteToWideChar(nCodePage, 0, pStr, nCount, wStr, 0); nWCount = MultiByteToWideChar(nCodePage, 0, pStr, nCount, wStr, nWCount); }