当前位置:主页 > 软件编程 > C代码 >

C++ WideCharToMultiByte()函数案例详解

时间:2022-08-13 12:18:19 | 栏目:C代码 | 点击:

函数WideCharToMultiByte() 详解

函数原型:

int WideCharToMultiByte( 

UINT CodePage,  

DWORD dwFlags,  

LPWSTR lpWideCharStr,  

int cchWideChar,  

LPCSTR lpMultiByteStr,  

int cchMultiByte,  

LPCSTR lpDefaultChar,  

PBOOL pfUsedDefaultChar 

);

函数功能:

此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。
(―Unicode 转 ANSI(GB2312),UTF8)

参数:

CP_ACP 当前系统ANSI代码页
CP_MACCP 当前系统Macintosh代码页
CP_OEMCP 当前系统OEM代码页,一种原始设备制造商硬件扫描码
CP_SYMBOL 符号代码页(42)
CP_THREAD_ACP 当前线程ANSI代码页

可设的值如下表所示:

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一起使用。
  1. lpWideCharStr: 待转换的宽字符串。
  2. cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。
  3. lpMultiByteStr: 接收转换后输出新串的缓冲区。
  4. cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。
  5. lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。
  6. lpUsedDefaultChar: 开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。
  7. 返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需字节数。函数失败,返回0。

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

demo1

wchar_t* pwszUnicode = L"Holle, word! 你好,中国! ";
int iSize;
char* pszMultiByte;

iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL);
pszMultiByte = (char*)malloc(iSize*sizeof(char));
WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);

demo2

int n;
CString noUser = _T("我是demo2");
//获得所需缓冲区大小n,为缓冲区分配空间
n = WideCharToMultiByte(CP_OEMCP, 0, noUser, -1, NULL, 0, 0, FALSE);
//m_strNoUser:接收转换后输出新串的缓冲区。
m_strNoUser = new char[n];

memset(m_strNoUser, 0, n*sizeof(char));
WideCharToMultiByte(CP_OEMCP, 0, noUser.GetBuffer(0), n, m_strNoUser, n , 0, FALSE);

您可能感兴趣的文章:

相关文章