ANIS与UNICODE字符格式转换:MultiByteToWideChar() 和WideCharToMultiByte() 函数

时间:2022-07-11 09:08:26

资料来自:

http://blog.****.net/holamirai/article/details/47948745

http://www.cnblogs.com/wanghao111/archive/2009/05/25/1489021.html

----------------------------------------------------------------------------------------------------------------

使用MultiByteToWideChar() 和 WideCharToMultiByte() 函数进行ANSI和UNICODE转换时,微软推荐通过执行同一函数两次,以确保转换成功,第一次执行获取保存转换结果所需内存大小,根据其返回值申请一片内存,第二次才真正执行转换。

MultiByteToWideChar() 返回值是确保转换成功的宽字符数,因此申请空间时需要乘以sizeof(wchar_t)。

WideCharToMultiByte() 返回值直接是确保转换成功所需的字节数,无需执行乘以sizeof操作;

具体实现可见示例代码。

宽字符到多字节字符转换函数

int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);
CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。
CP_ACP 当前系统ANSI代码页
CP_MACCP 当前系统Macintosh代码页
CP_OEMCP 当前系统OEM代码页,一种原始设备制造商硬件扫描码
CP_SYMBOL Symbol代码页,用于Windows 2000及以后版本,我不明白是什么
CP_THREAD_ACP 当前线程ANSI代码页,用于Windows 2000及以后版本,我不明白是什么
CP_UTF7 UTF-,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL
CP_UTF8 UTF-,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL

注意:函数WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。我的方法是先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区,详见下面的代码。另外,从Unicode UTF16向非Unicode字符集转换可能会导致数据丢失,因为该字符集可能无法找到表示特定Unicode数据的字符。

多字节字符到宽字符转换函数

int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCSTR lpMultiByteStr,
int cbMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar
);
dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。
MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用
MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式
MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符
MB_USEGLYPHCHARS 使用像形字符代替控制字符

示例代码

#include "iostream"
#include "windows.h"
using namespace std; void main()
{
// UINCONDE to ANSI
wchar_t* pwszUnicode = L"Holle, word! 你好,中国! ";
int iSize;
char* pszMultiByte;
iSize = WideCharToMultiByte(CP_ACP, , pwszUnicode, -, NULL, , NULL, NULL);
pszMultiByte = (char*)malloc((iSize)/**sizeof(char)*/);
WideCharToMultiByte(CP_ACP, , pwszUnicode, -, pszMultiByte, iSize, NULL, NULL);
cout<<"UINCONDE to ANSI:"<<pszMultiByte<<endl; // ANSI to UNICODE
locale loc( "chs" ); // 定义“区域设置”为中文方式
wcout.imbue( loc ); // 载入中文字符输入方式
char *pByteStr = "hello world! 你好,中国! ";
int iSize1;
wchar_t *pWideStr ;
iSize1 = MultiByteToWideChar(CP_ACP,,pByteStr,-,NULL,);
pWideStr = (wchar_t*)malloc(iSize1*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP,,pByteStr,-,pWideStr,iSize1*sizeof(wchar_t));
wcout<<"ANSI to UNICODE:"<<pWideStr<<endl;
system("pause"); }