[C++学习]1.字符集的知识(整理版)

ANSI、MBCS、Unicode基本概念

  计算机发明后,为了在计算机中表示字符,人们制定了一种编码,叫ASCII码。ASCII码由一个字节中的7位(bit)表示,范围是0x00 - 0x7F 共128个字符。他们以为这128个数字就足够表示abcd....ABCD....1234 这些字符了。

  咳......后来他们突然发现,如果需要按照表格方式打印这些字符的时候,缺少了“制表符”。于是又扩展了ASCII的定义,使用一个字节的全部8位(bit)来表示字符了,这就叫扩展ASCII码。范围是0x00 - 0xFF 共256个字符。

  咳......说中文的人就是聪明!中国人利用连续2个扩展ASCII码的扩展区域(0xA0以后)来表示一个汉字,该方法的标准叫GB-2312。后来,日文、韩文、阿拉伯文、台湾繁体(BIG-5)......都使用类似的方法扩展了本地字符集的定义,现在统一称为 MBCS 字符集(多字节字符集)。这个方法是有缺陷的,因为各个国家地区定义的字符集有交集,因此使用GB-2312的软件,就不能在BIG-5的环境下运行(显示乱码),反之亦然。

  咳......说英语的人为了把全世界人民所有的所有的文字符号都统一进行编码,于是制定了UNICODE标准字符集。UNICODE 使用2个字节表示一个字符(unsigned shor int、WCHAR、_wchar_t、OLECHAR)。这下终于好啦,全世界任何一个地区的软件,可以不用修改地就能在另一个地区运行了。虽然我用 IE 浏览日本网站,显示出我不认识的日文文字,但至少不会是乱码了。UNICODE 的范围是 0x0000 - 0xFFFF 共6万多个字符,其中光汉字就占用了4万多个。嘿嘿,中国人赚大发了:0)

  在程序中使用各种字符集的方法:

      const char * p = "Hello"; // 使用 ASCII 字符集

      const char * p = "你好"; // 使用 MBCS 字符集,由于 MBCS 完全兼容 ASCII,多数情况下,我们并不严格区分他们

      LPCSTR p = "Hello,你好"; // 意义同上

     

      const WCHAR * p = L"Hello,你好"; // 使用 UNICODE 字符集

      LPCOLESTR p = L"Hello,你好"; // 意义同上

     

      // 如果预定义了_UNICODE,则表示使用UNICODE字符集;如果定义了_MBCS,则表示使用 MBCS

      const TCHAR * p = _T("Hello,你好");

      LPCTSTR p = _T("Hello,你好"); // 意义同上

  在上面的例子中,T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用 MBCS,也不明确表示使用 UNICODE。那到底使用哪种字符集那?嘿嘿......编译的时候决定吧。设置条件编译的方式是:VC6中,"Project\Settings...\C/C++卡片 Preprocessor definitions" 中添加或修改 _MBCS、_UNICODE;VC.NET中,"项目\属性\配置属性\常规\字符集"然后用组合窗进行选择。使用 T 类型,是非常好的习惯,严重推荐!

————————引用VC知识库《COM组件设计与应用》

1.区别char和wchar_t(WCHAR)

  ANSI:即 char,可用字符串处理函数:strcat( ),strcpy( ), strlen( )等以str打头的函数。

  UNICODE:wchar_t是Unicode字符的数据类型

typedef unsigned short wchar_t;

  另外,在头文件中有这样的定义:

typedef wchar_t WCHAR; 

  所以WCHAR实际就是wchar_t

  wchar_t 可用字符串处理函数:wcscat(),wcscpy(),wcslen()等以wcs打头的函数。

  为了让编译器识别Unicode字符串,必须以在前面加一个“L”,例如: wchar_t *szTest=L"This is a Unicode string.";

2.BSTR

  BSTR是一个带长度前缀的字符串,主要由操作系统来管理的,所以要用api。主要用来和VB打交道的(VB里的string就是指它)要操作它的API函数有很多。比如SysAllocString,SysFreeString等等。vc里封装它的类如_bstr_t,及ATL中的CComBSTR等。

  一个 BSTR 由头部和字符串组成,头部包含了字符串的长度信息,字符串中可以包含嵌入的 null 值。

  BSTR 是以指针的形式进行传递的。(指针是一个变量,包含另外一个变量的内存地址,而不是数据。) BSTR 是 Unicode 的,即每个字符需要两个字节。 BSTR 通常以两字节的 null 字符结束。 wstr是宽字符,以双字节表示一个字符 bstr是为了与原先的basic字符兼容,它的最前面的4个字节为其长度,以'\0'结束.

  BSTR是一种Pascal-Style字符串(明确标示字符串长度)和C-Style字符串(以\0结尾)的混合物,一般用于COM中,是Unicode字符串,即标示字符串长度,最后还有一个\0

  BSTR是宽字符指针;_bstr_t是VC++对BSTR的封装;CComBSTR 是ATL对BSTR的封装;

  CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。

3. LPSTR和LPWSTR

  LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。

The LPSTR type and its alias PSTR specify a pointer to an array of 8-bit characters, which MAY be terminated by a null character.(MSDN)  

typedef char* PSTR, *LPSTR;

  LPSTR被定义成是一个指向以NULL(‘\0’)结尾的8位ANSI字符数组指针,

The LPWSTR type is a 32-bit pointer to a string of 16-bit Unicode characters, which MAY be null-terminated. The LPWSTR type specifies a pointer to a sequence of Unicode characters, which MAY be terminated by a null character (usually referred to as "null-terminated Unicode"). 

typedef wchar_t* LPWSTR, *PWSTR;

http://msdn.microsoft.com/en-us/library/cc230355(v=prot.20).aspx

  LPWSTR是一个指向以NULL结尾的32位Unicode双字节字符数组指针。

  'L'代表Long,'P'代表了pointer(即为指针的意思),'STR'意为String的意思。更正:'L'代表Local,'P'代表Pointer(指针),'STR'表示String的意思。

4.LPCSTR和LPCWSTR

An LPCSTR is a 32-bit pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.

This type is declared as follows:

typedef const char* LPCSTR;

An LPCWSTR is a 32-bit pointer to a constant string of 16-bit Unicode characters, which MAY be null-terminated.

This type is declared as follows:

typedef const wchar_t* LPCWSTR; 

5.LMSTR和LMCSTR

A LMSTR is a 32-bit pointer to a null-terminated string of 16-bit Unicode characters.

This type is declared as follows:

typedef WCHAR* LMSTR;

A LMCSTR is a 32-bit pointer to a constant null-terminated string of 16-bit Unicode characters.

This type is declared as follows:

typedef const wchar_t* LMCSTR; 

6. TCHAR和LPTSTR

  在C语言里面提供了 _UNICODE宏(有下划线),在Windows里面提供了UNICODE宏(无下划线),只要定了_UNICODE宏和UNICODE宏,系统就会自动切换到UNICODE版本,否则,系统按照ANSI的方式进行编译和运行。只定义了宏并不能实现自动的转换,他还需要一系列的字符定义支持。

  1. TCHAR

   如果定义了UNICODE宏则TCHAR被定义为wchar_t。

  typedef wchar_t TCHAR;
  否则TCHAR被定义为char typedef char TCHAR;

  2. LPTSTR

   如果定义了UNICODE宏则LPTSTR被定义为LPWSTR。

  typedef LPTSTR LPWSTR;
  否则LPTSTR被定义为
  typedef LPTSTR LPSTR;

  说明:在使用字符串常量的时候需要使用_TEXT(“MyStr”)或者_T("")来支持系统的自动转换。

7.string

 

8.CString

  CString 基于 TCHAR 数据类型。

  如果符号 _UNICODE 为您的程序生成定义,TCHAR 定义为类型 wchar_t,16位字符编码类型。

  否则,TCHAR 定义为 char,常规8位字符编码。 因此,在Unicode下,CString 用16位字符组成。 不支持Unicode,它由类型组成 char字符。

参考文献:

http://blog.csdn.net/hotsoftg/article/details/3928683 BSTR 与wchar_t 的区别

http://hi.baidu.com/zysoft827/item/8d52130b900d2837a2332a01 BSTR、_bstr_t 与 CComBSTR

http://msdn.microsoft.com/zh-cn/library/vstudio/ey142t48.aspx#_core_mfc_support_for_unicode_strings

posted @ 2012-12-02 11:57  太一吾鱼水  阅读(334)  评论(0编辑  收藏  举报