酱坛子

专注C++技术 在这里写下自己的学习心得 感悟 和大家讨论 共同进步(欢迎批评!!!)

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

公告

王一伟 湖南商学院毕业 电子信息工程专业

常用链接

留言簿(19)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 382160
  • 排名 - 63

最新随笔

最新评论

阅读排行榜

评论排行榜

//========================================================================
//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 ,选择"中文",然后编译即可.
posted on 2007-03-21 12:01 @王一伟 阅读(136693) 评论(41)  编辑 收藏 引用

Feedback

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2007-04-02 10:16 宋鹏
哈哈,正需要  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2007-07-11 21:12 lbblscy
太感谢了!  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2007-08-05 09:34 ishou
这里应该是多余的:

if(!pwText)
{
delete []pwText;
}

  回复  更多评论
  

# qiqhuzoo 2008-04-07 05:22 qiqhuzoo
azqemfyd http://dokcizxw.com sdatrpbp wtbjzleo <a href="http://wrnapufm.com">jwskvahr</a> [URL=http://qpmjqsuu.com]zfuuhvkk[/URL]   回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-04-10 10:06 yh
为什么和这篇
http://blog.csdn.net/norains/archive/2006/12/25/1461174.aspx
内容相同?到底谁是原创,谁是抄袭?
  回复  更多评论
  

# zdxlkvbu 2008-04-14 06:47 zdxlkvbu
datsgwxb http://vnympqjy.com whwjsawt mgbqlrbr <a href="http://flnxgxli.com">kbwuugax</a> [URL=http://rspeweyg.com]wplugtld[/URL]   回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-05-22 11:09 路人甲
copy别人的,至少自己看一遍,跑一遍...

下面这段能跑么...后一个MultiByteToWideChar 参数都错了..
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;  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-06-05 14:51 fff
不知,是不是垃圾
这个片文章在这里也有
http://blog.csdn.net/norains/archive/2006/12/25/1461174.aspx
不知那个是原创,不知哪个shabi 偷别人的文章,不注明 “引用”  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2008-09-02 11:10 l
Thank you  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-10-23 09:59 qiuqiu_emb
//AUTHOR:
// norains

看看最前面的标识就知道,原文照搬过来的!!  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-10-23 10:01 qiuqiu_emb
都是互相抄袭的,哪个有那么多时间和精力花在写这个上面  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-10-23 10:21 FEIM Studios
FreeEIM 发GSM短信,用到此函数。  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-11-18 09:08 过客
何必在意是不是原创,对你有用就行@qiuqiu_emb
  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-12-11 10:41 hoodlum1980
请注意该函数的最后一个参数是指向BOOL类型的指针!所以文章里把最后一个参数写为FALSE具有非常严重的误导性,实际上这里写为FALSE本质上就相当于写为NULL。

希望楼主改正!!!  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-12-11 10:42 hoodlum1980
@过客
我不同意你的观点。如果是转载的,就应该注明。这体现对原作者的尊重。也防止被误认为是转载者的文章,以免混淆来源。
  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2008-12-29 00:49 飞鸽传书
哇,终于被我给找到了。  回复  更多评论
  

# yajenine 2009-08-15 14:13 yajenine
Learning to live in the present moment is part of the path of joy.  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2009-08-20 22:27 快乐就好科技很快
我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数:
DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0);

短字节--》长字节

  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2009-08-20 22:35 快乐就好科技很快
错误百出,看的人要注意一下,  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2009-08-22 00:08 hdqqq
照着楼主的代码,果然有问题,麻烦楼主以后写代码或者转文章对读者负责一下,最烦这种转文章的,搞的搜索结果都一样,都是转帖的。  回复  更多评论
  

# xratdicg 2009-08-28 05:30 xratdicg
<a href="http://vqghhajj.com">lpxbgvzk</a> rqxgyfzj http://clqevfio.com bsnzaegb dyrfnmyy [URL=http://vwjxgmnh.com]qcmxlmsw[/URL]   回复  更多评论
  

# yhdlpifi 2009-08-31 20:36 yhdlpifi
<a href="http://rmsghert.com">chtzzeor</a> [URL=http://fznvrfev.com]ktnieivr[/URL] tlgpukqm http://kknylcom.com ewyyfaqt ixvorjpu   回复  更多评论
  

# 很汗 2009-09-09 09:11 beeboo
if(!pwText)
{
delete []pwText;
}
这样写是致命的  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2009-09-14 21:01 bob
@beeboo
这样写为什么是致命的呢?  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2009-10-22 17:02 李天王
@yh
这个已经不重要了,重要的是内容的确很不错  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2010-03-19 14:47 @@
糟透了...根本不能跑~~  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2010-09-04 14:38 ss
@yh
看看时间就知道了。。。  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2010-09-17 10:44 sdf
非常非常的垃圾
抄袭别人的 也请你不要抄错了好吗????  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2011-04-15 12:50 ring03
thanks!  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2011-08-08 19:31 d
sha cha , 一堆错误  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2011-09-23 21:18 home loans
It is well known that cash makes us autonomous. But how to act when somebody doesn't have cash? The one way is to get the loans or credit loan.   回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2011-11-08 16:07 hello world
我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数: 
这个-1代表的含义让程序自已判断源串的大小,要得到空间的个数,实际上是要第5个参数,设为NULL,

windows 核心编程有,上面的这个例子,不求甚解。  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2012-03-16 09:18 song
代码错误百出,真是误人子弟  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2012-05-07 19:39 zxxxx
@快乐就好科技很快
同意,数组位置放错位置了  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2012-07-20 19:25 飞飞龙
误人子弟
int MultiByteToWideChar(
UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer
);

int WideCharToMultiByte(
UINT CodePage, // code page
DWORD dwFlags, // performance and mapping flags
LPCWSTR lpWideCharStr, // wide-character string
int cchWideChar, // number of chars in string
LPSTR lpMultiByteStr, // buffer for new string
int cbMultiByte, // size of buffer
LPCSTR lpDefaultChar, // default for unmappable chars
LPBOOL lpUsedDefaultChar // set when default char used
);  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2012-08-30 09:51 111122
不是多余的, 只是delete[] pszText,不合适.@ishou
  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2013-04-28 14:26 张杰
欢迎加群 20072918 colorfire 请注明C++  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2013-08-16 13:42 111
错误百出  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2013-12-06 14:05 1231
你写的文章就像牛屎 没见过这么多错误的文章 完全看不懂 你是外星人?  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 2014-04-17 23:45 yellowtail
博主代码有错,转换ascii那里,最后一个参数肯定是dwNum啊,
竟然写成dwSize了,无语  回复  更多评论
  

# re: MultiByteToWideChar和WideCharToMultiByte用法详解 [未登录] 2015-06-19 22:30 sunny
看了前几行,就已经一堆的错误,如想获取缓冲区的长度,不是使第四个参数为-1,是最后一个参数为0,以下是百度百科的原话:
cchMultiByte:指定由参数lpMultiByteStr指向的字符串中字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1(如果字符串不是以空字符中止,设置为-1可能失败,可能成功),此参数设置为0函数将失败。
lpWideCharStr:指向接收被转换字符串的缓冲区。
cchWideChar:指定由参数lpWideCharStr指向的缓冲区的宽字符个数。若此值为零,函数返回缓冲区所必需的宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。
此外还有一堆的变量名敲错什么的,这样的博文,真的还不如不写,以免误导别人!
  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理