MultiByteToWideChar(
2008年05月21日 星期三 09:59 A.M.
这个是我们需要转化的多字节字符串: char sText[20] = {"多字节字符串!OK!"}; 我们需要知道转化后的宽字符需要多少个数组空间.虽然在这个里程里面,我们可以直接定义一个20*2宽字符的数组,并且事实上将运行得非常轻松愉快.但假 如多字节字符串更多,达到上千个乃至上万个,我们将会发现其中浪费的内存将会越来越多.所以以多字节字符的个数的两倍作为宽字符数组下标的声明绝对不是一 个好主意. 所幸,我们能够确知所需要的数组空间. 我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数: DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0); 接下来,我们只需要分配响应的数组空间: wchar_t *pwText; pwText = new wchar_t[dwNum]; if(!pwText) { delete []pwText; } 接着,我们就可以着手进行转换了.在这里以转换成ASCII码做为例子: MultiByteToWideChar (CP_ACP, 0, psText, -1, sText, dwSize); 最后,使用完毕当然要记得释放占用的内存: delete []psText; 同理,宽字符转为多字节字符的代码如下: wchar_t wText[20] = {L"宽字符转换实例!OK!"}; DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE); char *psText; psText = new char[dwNum]; if(!psText) { delete []psText; } WideCharToMultiByte (CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE); delete []psText; 如果之前我们已经分配好空间,并且由于字符串较短,可以不理会浪费的空间,仅仅只是想简单地将短字符和宽字符相互转换,那有没有什么简便的方法呢? WIN32 API里没有符合这种要求的函数,但我们可以自己进行封装: //------------------------------------------------------------------------------------- //Description: // This function maps a character string to a wide-character (Unicode) string // //Parameters: // lpcszStr: [in] Pointer to the character string to be converted // lpwszStr: [out] Pointer to a buffer that receives the translated string. // dwSize: [in] Size of the buffer // //Return Values: // TRUE: Succeed // FALSE: Failed // //Example: // MByteToWChar(szA,szW,sizeof(szW)/sizeof(szW[0])); //--------------------------------------------------------------------------------------- BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize) { // Get the required size of the buffer that receives the Unicode // string. DWORD dwMinSize; dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0); if(dwSize < dwMinSize) { return FALSE; } // Convert headers from ASCII to Unicode. MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize); return TRUE; } //------------------------------------------------------------------------------------- //Description: // This function maps a wide-character string to a new character string // //Parameters: // lpcwszStr: [in] Pointer to the character string to be converted // lpszStr: [out] Pointer to a buffer that receives the translated string. // dwSize: [in] Size of the buffer // //Return Values: // TRUE: Succeed // FALSE: Failed // //Example: // MByteToWChar(szW,szA,sizeof(szA)/sizeof(szA[0])); //--------------------------------------------------------------------------------------- BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize) { DWORD dwMinSize; dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE); if(dwSize < dwMinSize) { return FALSE; } WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE); return TRUE; } 使用方法也很简单,示例如下: wchar_t wText[10] = {L"函数示例"}; char sText[20]= {0}; WCharToMByte(wText,sText,sizeof(sText)/sizeof(sText[0])); MByteToWChar(sText,wText,sizeof(wText)/sizeof(wText[0])); 这两个函数的缺点在于无法动态分配内存,在转换很长的字符串时可能会浪费较多内存空间;优点是,在不考虑浪费空间的情况下转换较短字符串非常方便. 在软件的使用过程中,经常碰到乱码的情况,那么乱码的原因是什么呢?其实很多情况下,就是字符集的不同,也就是说同一个数字代表不同意思。在Windows里,目前主要有ANSI和UNICODE的方式。如果在UNICODE的方式里直接显示ANSI的字符串是出现乱码的,同样在ANSI函数里也不能显示UNICODE的字符串,而是要进行相互转换才能显示正确的字符串。在NT以后的操作系统里,Windows底层函数已经全部改为UNICODE的方式,如果还是使用ANSI的话,要比UNICODE函数慢一些,系统底层会从ANSI的方式转换为UNICODE方式,然后再显示出来。从ANSI转换为UNICODE的字符串,就可以使用函数MultiByteToWideChar来实现。
函数MultiByteToWideChar声明如下:
WINBASEAPI
int
WINAPI
MultiByteToWideChar(
__in UINT CodePage,
__in DWORD dwFlags,
__in LPCSTR lpMultiByteStr,
__in int cbMultiByte,
__out_ecount_opt(cchWideChar) LPWSTR lpWideCharStr,
__in int cchWideChar);
CodePage是代码表。
dwFlags是转换标志。
lpMultiByteStr是输入ANSI字符串。
cbMultiByte是输入ANSI的字符串长度。
lpWideCharStr是输出UNICODE字符串。
cchWideChar是输出UNICODE字符串的缓冲区大小。
调用函数的例子如下:
#001 //
#002 //字符串转换。
#003 //蔡军生 2007/11/28 QQ:9073204 深圳
#004 void MultiToWide(void)
#005 {
#006 //ANSI的字符串。
#007 std::string strANSI("测试字符串转换/r/n");
#008
#009 //
#010 const int nBufSize = 512;
#011 TCHAR chBuf[nBufSize];
#012 ZeroMemory(chBuf,nBufSize);
#013
#014 //转换为UNICODE的字符串。
#015 if (MultiByteToWideChar(CP_ACP,0,strANSI.c_str(),strANSI.length(),
#016 chBuf,nBufSize) > 0)
#017 {
#018 //
#019 OutputDebugString(chBuf);
#020 }
#021 |