关闭

[收集]ANSI字符与Unicode字符的互相转换

1769人阅读 评论(0) 收藏 举报

字符的问题真是令人头痛。。
ANSI字符是单字节的,Unicode字符是双字节的,VC6.0默认是用ANSI字符的,而后来的7、8默认都是用Unicode字符。。导致字符的问题经常遇到,最好又不要强制类型转换(有时候结果不正确不说,这种转换会导致很多漏洞。。)。这次真是被逼急了,就上网找了点资料总结一下。。
单字节字符或者字符串比如说有char*、string、LPCSTR(实际上就是char*)等,双字节的类型就比较多了,其实不是多,而是别名比较多,实际上就是一种:wchar_t *,再看一些别名:

#ifndef _MAC
typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR;    // wc,   16-bit UNICODE character
#endif

typedef WCHAR *PWCHAR, *LPWCH, *PWCH;
typedef CONST WCHAR *LPCWCH, *PCWCH;
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef __nullterminated PWSTR *PZPWSTR;
typedef __nullterminated CONST PWSTR *PCZPWSTR;
typedef __nullterminated WCHAR UNALIGNED *LPUWSTR, *PUWSTR;
typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;
typedef __nullterminated PCWSTR *PZPCWSTR;
typedef __nullterminated CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR;
看见比较多的比如WCHAR*,TCHAR*,LPCTSTR,LPWSTR ,尤其是LPWSTR ,很多函数的参数都是这种类型。


一、单字节字符串转双字节字符串(比如char*转LPWSTR
LPWSTR ConvertCharToLPWSTR(const char * szString)
{
       int dwLen = strlen(szString) + 1;
       int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度
       LPWSTR lpszPath = new WCHAR[dwLen];
       MultiByteToWideChar(CP_ACP, 0, szString, dwLen, lpszPath, nwLen);
       return lpszPath;
}
这里要注意的就是返回的双字节字符串不用时记得delete掉。

二、双字节字符串转单字节字符串(比如LPWSTR转char*、wstring|wchar_t*转换为string|char*)
//wstring转换为string:
string ConverWStringToString(wstring wstr)
{
      int size=WideCharToMultiByte(CP_ACP,0,wstr.c_str(),-1,NULL,0,NULL,NULL);
      char *ch=new char[size+1];
      if(!WideCharToMultiByte(CP_ACP,0,wstr.c_str(),-1,ch,size,NULL,NULL))
      {
            return false;
      }
      string str=ch;
      delete []ch;
      return str;
}

//wchar_t*转换为char*:
char* ConverPWCharToPChar(wchar_t *wch)
{
      int size=WideCharToMultiByte(CP_ACP,0,wch,-1,NULL,0,NULL,NULL);
      char *ch=new char[size+1];
      if(!WideCharToMultiByte(CP_ACP,0,wch,-1,ch,size,NULL,NULL))
      {
            return false;
      }
      return ch;
}


附MultiByteToWideChar函数与WideCharToMultiByte函数参数说明:
(1) MultiByteToWideChar
函数原型:
int MultiByteToWideChar(
  UINT CodePage,
  DWORD dwFlags,
  LPCSTR lpMultiByteStr,
  int cchMultiByte,
  LPWSTR lpWideCharStr,
  int cchWideChar
  );

参数说明:
1:CodePage
指定执行转换的字符集,这个参数可以为系统已安装或有效的任何字符集所给定的值。你也可以指定其为下面的任意一值:
CP_ACP:ANSI字符集;CP_MACCP:Macintosh代码页;CP_OEMCP:OEM代码页;
CP_SYMBOL:符号字符集(42);CP_THREAD_ACP:当前线程ANSI代码页;
CP_UTF7:使用UTF-7转换;CP_UTF8:使用UTF-8转换。

2:dwFlags
一组位标记用以指出是否未转换成预作或宽字符(若组合形式存在),是否使用象形文字替代控制字符,以及如何处理无效字符。你可以指定下面是标记常量的组合,含义如下:
    MB_PRECOMPOSED:通常使用预作字符——就是说,由一个基本字符和一个非空字符组成的字符只有一个单一的字符值。这是缺省的转换选择。不能与
    MB_COMPOSITE值一起使用。
  MB_COMPOSITE:通常使用组合字符——就是说,由一个基本字符和一个非空字符组成的字符分别有不同的字符值。不能与MB_PRECOMPOSED值一起使用。
  MB_ERR_INVALID_CHARS:如果函数遇到无效的输入字符,它将运行失败,且GetLastErro返回ERROR_NO_UNICODE_TRANSLATION值。
  MB_USEGLYPHCHARS:使用象形文字替代控制字符。
组合字符由一个基础字符和一个非空字符构成,每一个都有不同的字符值。每个预作字符都有单一的字符值给基础/非空字符的组成。在字符è中,e就是基础字符,而重音符标记就是非空字符。
  函数的缺省动作是转换成预作的形式。如果预作的形式不存在,函数将尝试转换成组合形式。
  标记MB_PRECOMPOSED和MB_COMPOSITE是互斥的,而标记MB_USEGLYPHCHARS和MB_ERR_INVALID_CHARS则不管其它标记如何都可以设置。

3:lpMultiByteStr
指向将被转换字符串的字符。

4:cchMultiByte
指定由参数lpMultiByteStr指向的字符串中字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1(如果字符串不是以空字符中止,设置为-1可能失败,可能成功),此参数设置为0函数将失败。

5:lpWideCharStr
指向接收被转换字符串的缓冲区

6:cchWideChar
指定由参数lpWideCharStr指向的缓冲区的字节数。若此值为零,函数返回缓冲区所必需的宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。

返回值
如果函数运行成功,并且cchWideChar不为零,返回值是由lpWideCharStr指向的缓冲区中写入的宽字符数;如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所需求的宽字符数大小。如果函数运行失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。它可以返回下面所列错误代码:
ERROR_INSUFFICIENT_BUFFER;ERROR_INVALID_FLAGS;
ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION

(2) WideCharToMultiByte
函数原型:
int WideCharToMultiByte(
    UINT CodePage, 
    DWORD dwFlags, 
    LPCWSTR lpWideCharStr,
    int cchWideChar, 
    LPSTR lpMultiByteStr, 
    int cbMultiByte,
    LPCSTR lpDefaultChar,    
    LPBOOL lpUsedDefaultChar
);

参数说明:
1、CodePage
指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,可以选择以下的代码页:
CP_ACP         //当前系统ANSI代码页 
CP_MACCP       //当前系统Macintosh代码页 
CP_OEMCP       //当前系统OEM代码页,一种原始设备制造商硬件扫描码 
CP_SYMBOL      //Symbol代码页,用于Windows 2000及以后版本
CP_THREAD_ACP //当前线程ANSI代码页,用于Windows 2000及以后版本
CP_UTF7 //UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL 
CP_UTF8 //UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL

2、dwFlags
指定如何处理没有转换的字符,一般情况下设为0
WC_NO_BEST_FIT_CHARS //把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。
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一起使用

3、lpWideCharStr //要转换的宽字符串
4、cchWideChar    //要转换宽字符串的长度,-1表示转换到字符串结尾
5、lpMultiByteStr //接收转换后输出的字符串的缓冲区
6、cbMultiByte    //输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。
7、lpDefaultChar //指向字符的指针,在指定编码里找不到相应字符时使用此字符作为默认字符代替,如果为NULL则使用系统默认字符
8、lpUsedDefaultChar //开关变量的指针,用以表明是否使用过默认字符,可设为NULL

返回值:为0表示调用失败

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:732767次
    • 积分:7319
    • 等级:
    • 排名:第2990名
    • 原创:67篇
    • 转载:183篇
    • 译文:2篇
    • 评论:52条
    文章分类
    最新评论