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

来源:互联网 发布:淘宝女生衣服店铺 编辑:程序博客网 时间:2024/05/14 02:44

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

#ifndef _MACtypedef 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 chartypedef unsigned short WCHAR;    // wc,   16-bit UNICODE character#endiftypedef 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。否则函数会自动丢弃非法字符。此选项只能用于UTF8WC_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表示调用失败

原创粉丝点击