摘自:http://blog.csdn.net/yockie/article/details/7381896

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表示调用失败

ANSI字符与Unicode字符的互相转换相关推荐

  1. 所有中文字符的Unicode字符范围——charCodeAt()方法

    [9968到40869] 提示:以下是本篇文章正文内容,下面思路可供参考 我们知道中文的正则范围为:[\u4e00-\u9fa5],即从"\u4e00"到"\u9fa5& ...

  2. 【字符串操作之】返回指定位置的字符和Unicode 字符代码 根据unicode返回字符→→charAt、charCodeAt和fromCharCode...

    //charAt和charCodeAt分别返回指定位置处的字符和字符对应的unicode码 var str:String="abcdefg"; var str2=str.charA ...

  3. C# dotnet 获取某个字符所在 Unicode 字符平面映射

    在 dotnet 里面可以通过安装 System.Text.Encodings.Web 库拿到 UnicodeRanges 这个包含了 Unicode 标准的平面映射.但是我还没有找到如何判断一个字符 ...

  4. 通过编写串口助手工具学习MFC过程——(三)Unicode字符集的宽字符和多字节字符转换...

    通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...

  5. Windows核心思想-宽字符与窄字符(Unicode和ASCII)

    目录 基本概念 演示 基本概念 宽字符:Unicode字符,双字节 窄字符:ASCII字符,单字节 Windows中所有的底层函数都是Unicode编码 COM组件必须使用Unicode编码(COM组 ...

  6. 大容量导入或导出的数据格式 -- Unicode字符格式

    应用场景 使用包含扩展/DBCS 字符的数据文件在多个 SQL Server 实例之间大容量传输数据时,建议使用 Unicode 字符格式. 从服务器导出数据时,Unicode 字符数据格式允许使用与 ...

  7. 宽字符与Unicode

    在C言语中,我们运用char来界说字符,占用一个字节,最多只能表现128个字符,也就是ASCII码中的字符.盘算机来源于美国,char 可以表现一切的英文字符,在以英语为母语的国度完整没有成绩. 然则 ...

  8. 《Modern Python Cookbook》(Python经典实例)笔记 1.10 使用键盘上没有的Unicode字符

    案例背景: Python默认支持Unicode.可用的独立Unicode字符有几百万个,这些字符中绝大多数我们使用键盘无法直接输入. 很多计算机中的字体可能在设计时就没有考虑提供这些字符,特别是Win ...

  9. 关于0宽度unicode字符 “zero-width-space“ “M-bM-^@M-^K“ <U+200B>

    最近线上出现一个很有意思的问题,同一个账号登录系统,同样的条件,别人都可以查询到数据,当事人电脑就是查不到,起初怀疑过特殊字符但是在后台日志查看时(tail/grep)没发现有问题. 最终发现还是因为 ...

最新文章

  1. Android Vector笔记
  2. Android开发之”再按一次退出程序“的实现
  3. java 中的finally 语句块执行顺序
  4. 当try,catch,finally中均有return语句时,会返回哪一个?---finally中的return
  5. 围观一下tp的游戏保护 一
  6. prometheus 发送恢复 值_Prometheus基础知识介绍
  7. 公司计算机 统一购买 补贴,全国农机购置补贴计算机管理系统开始全面启用
  8. mysql_day02创建数据表
  9. 16QAM调制解调步骤
  10. html怎么实现年月日的选择,利用select实现年月日三级联动的日期选择效果【推荐】...
  11. python手机号码替换代码_手机号码中间部分替换成星号
  12. 阿里云、腾讯云、Testin云测共获“中国云计算创新企业50强”
  13. Windows渗透与提权:技巧总结篇
  14. php转html为pdf后部分图片无法显示
  15. Open Street Map—2022年道路数据
  16. 揭开Java上传下载功能的神秘面纱
  17. 【JavaEE基础与高级 第42章】C3P0连接数据库操作顺序
  18. 学以致用——Java源码——抛硬币(Coin Tossing)
  19. 电脑浏览android,直接在电脑上浏览操作安卓手机
  20. 关于python爬取网页

热门文章

  1. 33 关 Python 游戏,测试你的爬虫能力到底及格不?
  2. 专访 Unity 高管:深耕游戏、VR/AR,致力为开发者提供极致体验
  3. GitHub 日收 12,000 星,微软新命令行工具引爆程序员圈!
  4. @程序员,你准备好推出自己的移动应用了吗?
  5. 程序员的大恩人永远地离开了
  6. 如何在 10 亿数中找出前 1000 大的数?
  7. 谷歌中国 AI 中心要凉?李飞飞否认将离职
  8. TensorFlow.js 来了!浏览器上线机器学习功能
  9. Java实战视频bilibili
  10. python游戏设计教程视频_零基础python教程-用Python设计你的第一个小游戏