`
wsql
  • 浏览: 11883020 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

MultiByteToWideChar和WideCharToMultiByte用法详解

 
阅读更多
//========================================================================
//TITLE:
// MultiByteToWideChar和WideCharToMultiByte用法详解
//AUTHOR:
// norains
//DATE:
// 第一版:Monday 25-December -2006
// 增补版:Wednesday 27-December -2006
// 修订版:Wednesday 14-March-2007 (修正之前的错误例子)
//Environment:
// EVC4.0 + Standard SDK
//========================================================================

1.使用方法详解

在本文开始之处,先简要地说一下何为短字符和宽字符.
所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:《windows 程序设计》,《windows 核心编程》.这两本书关于这两种字符都有比较详细的解说.

宽字符转换为多个短字符是一个难点,不过我们只要掌握到其中的要领,便可如鱼得水.
好吧,那就让我们开始吧.

这个是我们需要转化的多字节字符串:
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]));

这两个函数的缺点在于无法动态分配内存,在转换很长的字符串时可能会浪费较多内存空间;优点是,在不考虑浪费空间的情况下转换较短字符串非常方便.


2.MultiByteToWideChar()函数乱码的问题

有的朋友可能已经发现,在标准的WinCE4.2或WinCE5.0 SDK模拟器下,这个函数都无法正常工作,其转换之后的字符全是乱码.及时更改MultiByteToWideChar()参数也依然如此.
不过这个不是代码问题,其结症在于所定制的操作系统.如果我们定制的操作系统默认语言不是中文,也会出现这种情况.由于标准的SDK默认语言为英文,所以肯定会出现这个问题.而这个问题的解决,不能在简单地更改控制面板的"区域选项"的"默认语言",而是要在系统定制的时候,选择默认语言为"中文".
系统定制时选择默认语言的位置于:

Platform -> Setting... -> locale -> default language ,选择"中文",然后编译即可.

==================================================================================================================================

**************************************************************************************************************************************************************************************

==================================================================================================================================

WideCharToMultiByte和MultiByteToWideChar函数的用法

为了支持Unicode编码,需要多字节与宽字节之间的相互转换。这两个系统函数在使用时需要指定代码页,在实际应用过程中遇到乱码问题,然后重新阅读《Windows核心编程》,总结出正确的用法。
WideCharToMultiByte的代码页用来标记与新转换的字符串相关的代码页。
MultiByteToWideChar的代码页用来标记与一个多字节字符串相关的代码页。
常用的代码页由CP_ACP和CP_UTF8两个。
使用CP_ACP代码页就实现了ANSI与Unicode之间的转换。
使用CP_UTF8代码页就实现了UTF-8与Unicode之间的转换。
下面是代码实现:
1. ANSI to Unicode
wstring ANSIToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,
0,
str.c_str(),
-1,
NULL,
0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_ACP,
0,
str.c_str(),
-1,
(LPWSTR)pUnicode,
unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;

return rt;
}
2. Unicode to ANSI
string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
NULL,
0,
NULL,
NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
3. UTF-8 to Unicode
wstring UTF8ToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,
0,
str.c_str(),
-1,
NULL,
0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_UTF8,
0,
str.c_str(),
-1,
(LPWSTR)pUnicode,
unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;

return rt;
}
4. Unicode to UTF-8
string UnicodeToUTF8( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,
0,
str.c_str(),
-1,
NULL,
0,
NULL,
NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_UTF8,
0,
str.c_str(),
-1,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}

分享到:
评论

相关推荐

    MultiByteToWideChar和WideCharToMultiByte用法详解.docx

    《MultiByteToWideChar和WideCharToMultiByte函数详解》 在Windows开发中,处理不同编码格式的字符串转换是一项常见的任务。MultiByteToWideChar和WideCharToMultiByte是Windows API提供的两个关键函数,用于在多...

    MultiByteToWideChar和WideCharToMultiByte用法详解.pdf

    【MultiByteToWideChar函数详解】 MultiByteToWideChar是一个Windows API函数,它的主要作用是将一个多字节字符串转换为宽字符(Unicode)字符串。在处理不同编码的字符串时,这个函数非常有用,特别是在需要在多...

    各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar.pdf

    字符编码转换方法:MultiByteToWideChar和WideCharToMultiByte 在计算机科学中,字符编码是一个非常重要的概念,它决定了计算机如何存储和处理文字信息。不同的操作系统和应用程序使用不同的字符编码标准,因此在...

    各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar.docx

    字符编码间的转换方法:MultiByteToWideChar和WideCharToMultiByte 在计算机科学中,字符编码是一种将文本数据转换为二进制数据的方式。不同的编码方式可以将同一个字符表示为不同的二进制码,从而导致不同的计算机...

    GB2312编码和UTF-8互转(c语言实现)

    GB2312编码与utf-8编码的字符串的转换,主要使用windows api函数MultiByteToWideChar和WideCharToMultiByte,代码简洁,经测试可用

    (精品)用VC-编程实现转换文本文件的字符编码.pdf

    设计字符编码转换程序时,通常采用查表映射的方法,Windows操作系统提供了两个关键函数:MultiByteToWideChar和WideCharToMultiByte。MultiByteToWideChar函数能够将多字节字符串转换为宽字节字符串(即Unicode编码...

    易语言空间更新

    易语言空间更新源码,空间更新,图片式压缩包,子程序_更新,处理换行符,取指定内容,Utf8转Ansi,Unicode转Ansi,Utf8转Unicode,MultiByteToWideChar,WideCharToMultiByte,WideCharToMultiByte_utf8,MultiByteToWideChar_...

    易语言GBK-BIG5互转

    易语言GBK-BIG5互转源码,GBK-BIG5互转,BIG5_GBK,GBK_BIG5,MultiByteToWideChar,WideCharToMultiByte

    易语言登陆百度空间

    易语言登陆百度空间源码,登陆百度空间,取Cookie,取中间文本,Utf8转Ansi,加载COM,卸载COM,MultiByteToWideChar,WideCharToMultiByte

    易语言编码转换模块

    易语言编码转换模块源码,编码转换模块,AnsiToUnicode,UnicodeToAnsi,Utf8ToUnicode,UnicodeToUtf8,AnsiToUtf8,Utf8ToAnsi,MultiByteToWideChar,WideCharToMultiByte

    易语言十分钟邮件模块

    易语言十分钟邮件模块源码,十分钟邮件模块,取邮件地址,取邮件内容,Utf8转Ansi,Ansi转Utf8,Unicode转Ansi,Utf8转Unicode,Unicode转Utf8,Ansi转Unicode,MultiByteToWideChar_utf8,WideCharToMultiByte_utf8,...

    易语言取QQ群验证

    易语言取QQ群验证源码,取QQ群验证,获取网页源码,找本本,getACSRFToken,CharCodeat,ToCharArray,Ansi转Unicode,Utf8转Ansi,Utf8转Unicode,Unicode转Ansi,MultiByteToWideChar,WideCharToMultiByte,...

    易语言百度短网址操作模块

    易语言百度短网址操作模块源码,百度短网址操作模块,短网址_生成,短网址_自定义生成,短网址_取原网址,取属性,编码转换_Ucs2转Ansi,HexToInt,MultiByteToWideChar,WideCharToMultiByte1,WideCharToMultiByte_utf8,...

    易语言多语言程序界面

    易语言多语言程序界面源码,多语言程序界面,取得翻译结果,URL编码_utf8,截取文本,Ansi转Unicode,Unicode转Utf8,Ansi转Utf8,MultiByteToWideChar,WideCharToMultiByte_utf8

    易语言恒云雨反全局线程钩子模块

    易语言恒云雨反全局线程钩子模块源码,恒云雨反全局线程钩子模块,azu,uza,开始拦截,停止拦截,是否保护,Getaddr,拦截过程,MultiByteToWideChar,WideCharToMultiByte,取模块句柄_,取库函数地址_

    用C语言完成普遍地三种中文内码转换.doc

    大五码转 GBK 码函数使用 MultiByteToWideChar 函数将大五码字符串转换为宽字符字符串,然后使用 WideCharToMultiByte 函数将宽字符字符串转换为 GBK 码字符串。 GBK 转大五码函数使用 MultiByteToWideChar 函数将 ...

    易语言Punycode编码系统

    易语言Punycode编码系统源码,Punycode编码系统,encode,decode,adapt,isBasic,U2A,A2W,W2A,A2U,codepoint2digit,digit2codepoint,toUnicode,toASCII,MultiByteToWideChar,WideCharToMultiByte

    设置文件版本信息

    更新文件版本资源,从文本转换版本信息,分析BLOCK,获取下一行,获取行类型,MAKEVALUE,十六进制到十进制,MAKEBLOCK,My删首尾空,A2W,BeginUpdateResourceA,UpdateResourceA,EndUpdateResourceA,MultiByteToWideChar,...

    易语言字符串操作

    易语言字符串操作源码,字符串操作,字符串_取长度,字符串_取中间,字符串_取左边,字符串_取右边,字符串_替换,到宽字符,到多字节,取文本数据地址,取字节集数据地址,MultiByteToWideChar,WideCharToMultiByte

Global site tag (gtag.js) - Google Analytics