MultiByteToWideChar和MultiByteToWideChar对各种字符编码间的转换
函数原型:
int WideCharToMultiByte(
UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar );
此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:
CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。 参数说明:
1、CodePage——指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,可选择以下代码页: CP_ACP //当前系统ANSI代码页
CP_MACCP //当前系统Macintosh代码页
CP_OEMCP //当前系统OEM代码页,一种原始设备制造商硬件扫描码 CP_SYMBOL //Symbol代码页,用于Windows 2000及以后版本 CP_THREAD_ACP //当前线程ANSI代码页,用于Windows 2000及以后版本
CP_UTF7 //UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL
CP_UTF8 //UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL
用 GetLocaleInfo 函数获取当前系统的代码页,936: 简体中文, 950: 繁
体中文,949:韩文
2、dwFlags—— 一般用 0 就可以了
指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符:
MB_PRECOMPOSED //总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和
MB_COMPOSITE合用MB_COMPOSITE //总是使用分解字符,即总是使用基字符+不占空间字符的方式
MB_ERR_INVALID_CHARS //设置此选项,函数遇到非法字符就失败并返回错误码
ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符 MB_USEGLYPHCHARS //使用像形字符代替控制字符 3、lpMultiByteStr //要转换的字符串
4、cbMultiByte //要转换字符串的长度,-1表示转换到字符串结尾。返回原字符串长度。0 作为结束符的字符串
5、lpWideCharStr//接收转换后输出的宽字符串的缓冲,如果为 NULL, 就是代表计算生成的字符串的长度。
6、cchWideChar//输出缓冲区大小,转化生成的 unicode 字符串缓存的容量。如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不同 为0表示调用失败;当cchWideChar为0时,函数将返回所需缓冲区大小 int BufSize = MultiByteToWideChar(936,0,s,-1,NULL,0); //计算简体中文字符串 s 转成 widestring 之后占用的内存字节数…… //在此处为 wsbuf 分配内存 BufSize 个字节
MultiByteToWideChar(936,0,s,-1,wsbuf,BufSize); //把简体中文字符串 s 转化为 unicode 的 WideString
最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。
例一:Unicode转换到GBK #include
#define CODE_PAGE_GB18030 54936
int Unicode2GBK( wchar_t *pUnicode, char** ppDest) { // get the size of the dest string
const int size = ::WideCharToMultiByte( CODE_PAGE_GB18030, 0/* you can do more for it*/,
pUnicode, -1, 0, 0, 0, 0 ); if ( size == 0 ) { return -1; }
char* pDestString = new char[size + 2]; ::memset( pDestString, 0, sizeof(pDestString) ); // transform
int ret = ::WideCharToMultiByte( CODE_PAGE_GB18030, 0, pUnicode, -1, pDestString, size, 0, 0 );
if( ret == 0 ) { delete pDestString; return -1; } else { *ppDest = pDestString; return 0; } } 例二:字串转换
wchar_t* pwszUnicode = \你好,中国! \int iSize;
char* pszMultiByte;
iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL);
pszMultiByte = (char*)malloc((iSize+1)/**sizeof(char)*/);
WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);
注意事项:
dwFlags: 指定如何处理没有转换的字符, 但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示:
WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。 WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选
项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。
WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。
WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK一起使用
WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,与WC_COMPOSITECHECK一起使用
WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如’?’),与WC_COMPOSITECHECK一起使用。
当指定WC_COMPOSITECHECK时,函数会将合成字符转换成预制字符。合成字符由一个基字符和一个不占空间的字符(如欧洲国家及汉语拼音的音标)组成,每一个都有不同的字符值。预制字符有一个用于表示基字符和不占空间字符的合成体的单一的字符值。
当指定WC_COMPOSITECHECK选项时,也可以使用上表列出的最后3个选项来定制预制字符的转换规则。这些选项决定了函数在遇到宽字符串的合成字符没有对应的预制字符时的行为,他们与WC_COMPOSITECHECK一起使用,如果都没有指定,函数默认WC_SEPCHARS。
对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。
50220 5022150222 50225 50227 50229 52936 54936 57002到5701165000(UTF7) 42(Symbol)
对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。
lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags
而使用此参数,函数将失败返回并设置错误码
ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设
为NULL,函数会更快一些。
第二个是多字节字符到宽字符转换函数,函数原型如下: > int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte,
LPWSTR lpWideCharStr, int cchWideChar );
此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。
此函数的参数,返回值及注意事项参见上面函数WideCharToMultiByte的说明,这里只对dwFlags做简单解释。
dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。
MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用
MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式
MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码 ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符 MB_USEGLYPHCHARS 使用像形字符代替控制字符
对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。
50220 5022150222 50225 50227 50229 52936 54936 57002到5701165000(UTF7) 42(Symbol)
对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。