
MultiByteToWideChar和WideCharToMultiByte的详细说明
编程专栏2009-11-06 13:02阅读211条评论0字体大小: 大中中小首先是从宽字符到多字节字符的转换函数,函数原型如下:
int WideCharToMultiByte(
UINT代码页
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);
此函数将宽字符串转换为指定的新字符串,例如ANSI,UTF8等. 新字符串不必是多字节字符集. 参数:
CodePage: 指定要转换的字符集的代码页. 它可以是系统已安装或随附的任何字符集. 您还可以使用下面显示的代码页之一.

CP_ACP当前系统ANSI代码页
CP_MACCP当前系统Macintosh代码页
CP_OEMCP当前系统的OEM代码页面,OEM硬件扫描代码
用于Windows 2000及更高版本的CP_SYMBOL符号代码页,我不知道它是什么
用于Windows 2000及更高版本的CP_THREAD_ACP当前线程ANSI代码页,我不知道它是什么
CP_UTF7 UTF-7,设置此值时,lpDefaultChar和lpUsedDefaultChar必须都为NULL
CP_UTF8 UTF-8,设置此值时,lpDefaultChar和lpUsedDefaultChar都必须为NULL
我认为最常用的是CP_ACP和CP_UTF8,前者将宽字符转换为ANSI,后者转换为UTF8.
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 50221 50222 50225 50227 50229 52936 54936 57002至57011 65000(UTF7)42(符号)
对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则该函数将无法返回并设置错误代码ERROR_INVALID_FLAGS,您可以调用GetLastError来获取.
lpWideCharStr: 要转换的宽字符串.
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);否则,返回0. 如果cbMultiByte为0,则返回所需的转换

字节数. 该函数失败并返回0.
注意: WideCharToMultiByte函数使用不当会影响程序的安全性. 调用此函数将很容易导致内存泄漏,因为lpWideCharStr所指向的输入缓冲区大小为多个字符,而lpMultiByteStr所指向的输出缓冲区大小为字节数. 为避免内存泄漏,请确保为输出缓冲区指定适当的大小. 我的方法是使用cbMultiByte 0一次调用WideCharToMultiByte以获取所需的缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区. 有关详细信息,请参见下面的代码. 另外,从Unicode UTF16转换为非Unicode字符集可能会导致数据丢失,因为该字符集可能无法找到代表特定Unicode数据的字符.
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);
第二个是多字节字符到宽字符的转换功能,该函数的原型如下:
> int MultiByteToWideChar(
UINT代码页
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 50221 50222 50225 50227 50229 52936 54936 57002至57011 65000(UTF7)42(符号)
对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数将失败并返回错误代码ERROR_INVALID_FLAGS.
我还没有使用以下功能,我只简单介绍一下.
int GetTextCharset(HDC hdc);
此函数获取当前所选设备描述表的字符集,该字符集等效于GetTextCharsetInfo(hdc,NULL,0).
返回值: 成功返回字符集ID,失败则返回DEFAULT_CHARSET.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-264877-1.html
6000万