C/C++中的字节转换

宽字节转单字节 :size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
单字节转宽字节 :size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );
上面这两个是标准C++的,下面两个好像是微软的函数。不过上面两个函数只能一个一个的转换,也就是说一次只能转换一个字符。下面两个方法就是 宽字符串与单字节字符串之间的转换。
宽字节转多字节 :WideCharToMultiByte //其实这里的多字节就是我们说的char
多字节转宽字节 :MultiByteToWideChar //多字节也就是ASCII单字节

  

1.使用方法详解

  在本文开始之处,先简要地说一下何为短字符和宽字符.
所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:《windows 程序设计》,《windows 核心编程》.这两本书关于这两种字符都有比较详细的解说. 宽字符转换为多个短字符是一个难点,不过我们只要掌握到其中的要领,便可如鱼得水.
好吧,那就让我们开始吧. 这个是我们需要转化的多字节字符串:
char sText[20] = {"多字节字符串!OK!"}; 我们需要知道转化后的宽字符需要多少个数组空间.虽然在这个里程里面,我们可以直接定义一个20个宽字符的数组(如果全部是中文,则宽字符数组需要10个;反之,如果是英文字符,则需要20个。这里选取的是最大值),并且事实上将运行得非常轻松愉快.但假如多字节字符串更多,达到上千个乃至上万个,我们将会发现其中浪费的内存将会越来越多.所以以多字节字符的个数的两倍作为宽字符数组下标的声明绝对不是一个好主意.
所幸,我们能够确知所需要的数组空间.
我们只需要将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, sText, -1, pwText, dwNum); 最后,使用完毕当然要记得释放占用的内存:
delete []pwText; 同理,宽字符转为多字节字符的代码如下:
wchar_t wText[20] = {L"宽字符转换实例!OK!"};
DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,wText,-1,NULL,0,NULL,FALSE);
char *psText;
psText = new char[dwNum];
if(!psText)
{
delete []psText;
}
WideCharToMultiByte (CP_OEMCP,NULL,wText,-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 ,选择"中文",然后编译即可.
//---------------------------------------------------------------------------
// 大五码转GBK码:
void __fastcall BIG52GBK(char *szBuf)
{
  if(!strcmp(szBuf, ""))
   return;
  int nStrLen = strlen(szBuf);
  wchar_t *pws = new wchar_t[nStrLen + 1];
  try
  {
   int nReturn = MultiByteToWideChar(950, 0, szBuf, nStrLen, pws, nStrLen + 1);
   BOOL bValue = false;
   nReturn = WideCharToMultiByte(936, 0, pws, nReturn, szBuf, nStrLen + 1, "?", &bValue);
   szBuf[nReturn] = 0;
  }
  __finally
  {
   delete[] pws;
  }
}
//---------------------------------------------------------------------------
// GBK转大五码
void __fastcall GBK2BIG5(char *szBuf)
{
  if(!strcmp(szBuf, ""))
   return ;
  int nStrLen = strlen(szBuf);
  wchar_t *pws = new wchar_t[nStrLen + 1];
  try
  {
   MultiByteToWideChar(936, 0, szBuf, nStrLen, pws, nStrLen + 1);
   BOOL bValue = false;
   WideCharToMultiByte(950, 0, pws, nStrLen, szBuf, nStrLen + 1, "?", &bValue);
   szBuf[nStrLen] = 0;
  }
  __finally
  {
   delete[] pws;
  }
}
//----------------------------------------------------------------------------
// GB2312码转GBK码
void __fastcall GB2GBK(char *szBuf)
{
  if(!strcmp(szBuf, ""))
   return;
  int nStrLen = strlen(szBuf);
  WORD wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);
  int nReturn = LCMapString(wLCID, LCMAP_TRADITIONAL_CHINESE, szBuf, nStrLen, NULL, 0);
  if(!nReturn)
   return;
  char *pcBuf = new char[nReturn + 1];
  try
  {
   wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);
   LCMapString(wLCID, LCMAP_TRADITIONAL_CHINESE, szBuf, nReturn, pcBuf, nReturn + 1);
   strncpy(szBuf, pcBuf, nReturn);
  }
  __finally
  {
   delete[] pcBuf;
  }
}
//---------------------------------------------------------------------------
// GBK码转GB2312码
void __fastcall GBK2GB(char *szBuf)
{
  if(!strcmp(szBuf, ""))
   return;
  int nStrLen = strlen(szBuf);
  WORD wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_BIG5);
  int nReturn = LCMapString(wLCID, LCMAP_SIMPLIFIED_CHINESE, szBuf, nStrLen, NULL, 0);
  if(!nReturn)
   return;
  char *pcBuf = new char[nReturn + 1];
  try
  {
   wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_BIG5);
   LCMapString(wLCID, LCMAP_SIMPLIFIED_CHINESE, szBuf, nReturn, pcBuf, nReturn + 1);
   strncpy(szBuf, pcBuf, nReturn);
  }
  __finally
  {
   delete []pcBuf;
  }
}
//---------------------------------------------------------------------------
// 测试代码
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char szBuf[255];
  // 从GB2312转到GBK
  strcpy(szBuf, Edit1->Text.c_str());
  GB2GBK(szBuf);
  Edit2->Text = String(szBuf);
  // 从GB2312转到BIG5,通过GBK中转
  strcpy(szBuf, Edit1->Text.c_str());
  GB2GBK(szBuf);
  GBK2BIG5(szBuf);
  Edit3->Text = String(szBuf);
}  

  

  

字节转换/编码转换全为转载GBK,BIG5,utf8,unicode的更多相关文章

  1. iPhone将NSString转换编码集为gb2312或者gbk的方法

    很多时候软件读取的中文网页编码集是gb2312,所以显示出来的是乱码.这时需要将NSString文字编码转换.你可以试试以下代码 NSURL *url = [NSURL URLWithString:u ...

  2. MYSQL转换编码的解决方法

    MYSQL转换编码的解决方法 一.在utf8的mysql下 得到中文‘游客’的gbk下的16进制编码 mysql> SELECT hex(CONVERT( '游客' USING gbk )); ...

  3. 【CodeBase】PHP转换编码,读写文件/网页内容的防乱码方法

    核心代码: //检查字符串的编码 $charset=mb_detect_encoding($doc,['ASCII','GB2312','GBK','BIG5','UTF8'],TRUE); //字符 ...

  4. 转载一篇关于unicode字符编码的文章

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们认为8个开关状态作为原子单位很好,于是他们把这称为"字节". 再后来,他们又做了一 ...

  5. 【VS开发】字符,字节和编码

    字符,字节和编码 [原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/encoding.htm] 级别:中级 摘要:本文介绍了字符与编码的发展过程,相关概念的正确理 ...

  6. eclipse 解决编译出现GBK或UTF8 编码错误的方法

    eclipse由于开源所以支持了比较杂的编码方式,而这些一个工程导入时添加了不少的外来程序,由于不是同一工程一次编码带来了其中含有GBK和 UTF8   UTF16  ASCII等文件编译时就会出现错 ...

  7. GB2312,GBK,GB18030,UTF8四种汉字编码标准有什么差别和联系

     从GB2312.GBK 到 GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有同样的编码,后面的标准支持很多其它的字符.在这些编码中,英文和中文能够统一地处理. 区分中文编 ...

  8. 编码与乱码(05)---GBK与UTF-8之间的转换--转载

    原文地址:http://www.blogjava.net/pengpenglin/archive/2010/02/22/313669.html [GBK转UTF-8] 在很多论坛.网上经常有网友问“  ...

  9. python 全栈开发,Day6(is,小数据池,编码转换)

    一.is a = 100 b = 100 print(a == b) print(a is b) 执行输出: TrueTrue 查看内存地址,使用id函数 print(id(a)) print(id( ...

随机推荐

  1. python字符串转义与正则表达式特殊字符转义

    最近在自学python,字符串和正则表达式的特殊字符转义有点混淆,做个笔记简单总结一下. 1.普通字符串转义 在字符串中使用特殊字符时,要用反斜杠(\)转义字符.例如:'Let\'s go!',这里对 ...

  2. C#时间格式之GMT时间的格式

    GMT:格林尼标准时间  北京时间=GMT时间+8小时 DataTime nowDate = DataTime.Now; nowDate.toString("r");    效果为 ...

  3. NPOI 辅助类

    using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using S ...

  4. 引入css ,使用@import和link的方式

    我们也经常听到有人说要使用link来引入CSS更好,但是你知道为什么吗? 继续往下看 linklink就是把外部CSS与网页连接起来. @importimport文字上与link的区别就是它可以把在一 ...

  5. windows平台下杀死指定端口的进程(转载)

    在windows命令行窗口下执行: 1.查看所有的端口占用情况 C:\>netstat -ano 协议    本地地址                     外部地址              ...

  6. English - refer to...和refer to...as

    refer to...和refer to...as...本来就是refer的两个固定搭配,这个只能讲讲后两者用法,剩下的就是单独的refer的用法了. 1. refer to sb/sth 指的是/提 ...

  7. $.ajax传递字符串到后台,后台返回json对象

    var mall = { MallID: $("#createId").val().trim(), MallName: $("#createName").val ...

  8. MySQL 5.7 重置root默认密码

    http://www.cnblogs.com/jym-sunshine/p/5314101.html mysql5.7.11修改root默认密码   知道 MySQL 出了5.7了,并且网上说性能提高 ...

  9. 根据不同需求跳转不同Activity的另外一种写法

    代码如下: /* Android Asynchronous Http Client Sample Copyright (c) 2014 Marek Sebera <marek.sebera@gm ...

  10. ListView 条目加载上滑下滑首尾缩放动画实现

    要实现这个效果,只需要再适配器getView之前,给每个条目的view设置相应的动画即可. 首先需要2个动画的xml文件. 在res下新建anim文件夹:(res/anim) 第一个动画xml文件: ...