《Windows程序设计》读书笔记------------->>关于Unicode<<

来源:互联网 发布:rcnn tensorflow 编辑:程序博客网 时间:2024/05/20 08:41

这节内容主要是介绍一下Unicode的背景知识,由于或计划的趋势本书作者是大力推荐使用Unicode进行编成的。但是我这种连VC++都不会使用,还考虑什么国际化编程呀。不过还是小结一下吧,不然我就白看了......................

一、字符集的历史

由于字符表示的需要,各个不同的人或组织根据自己的需要建立了不同的字符集系统。下面一个标表示了不同的字符集的建立时间和创立者:

字符集名称 创立者 时间 初始目的 特点 莫斯电码 Samuel F. B. Morse 1838年到1854年间 电报 字母表中的每个字符对应于一系列短的和长的脉冲(点和破折号),没有大小写区分,有数字 Braille代码 Louis Braille 1821年到1824年之间 盲人阅读 种6位代码,它把字符、常用字母组合、常用单字和标点进行编码。用特殊的符号标示大写和数字的开始 Hollerith卡片 Herman Hollerith     首次在1890年的美国人口普查中使用 ASCII 美国国家标准协会 完成于1967年 计算机 7bit ANSI/ISO 8859-1-1987 Microsoft 1985年11月发行   纯Windows字符集,首次在Windows 1.0中出现 双字节字符集(DBCS)     象形文字 Windows支持四个不同的双字节字符集:代码页932(日文)、936(简体中文)、949(韩语)和950(繁体汉字)。只有为这些国家(地区)生产的Windows版本才支持DBCS。 Unicode 多家公司合作 1996 计算机 每个字符都是16位宽,表示65,536个字符

二、Windows和C对Unicode的支持

可以说现在的Windows和C都是对Unicode支持的。其中Windows95/98是通过转换成ANSI的方式小范围的进行支持,而之后的软件都是从底层支持了,这一点可以从XP的兼容模式上得到印证。


而在VC++中使用Unicode编程还是比较麻烦的,这是由于很多已有的C标准函数还是使用旧有的字符集。强行使用会导致程序报错,得不到应有的结果。所以,作者介绍了很多专门针对Unicode的编程函数。

不过这些都很没有用啦。最关键的部分是:

本书中的程序写作时被限制成既可使用也可不使用定义的UNICODE标识符来编译。这包括对所有字符和字符串定义使用TCHAR,对字符串文字使用TEXT宏,以及注意不要混淆字节和字符。

所以,为了看都后面的文章,了解一下UNICODE编成的方法,和特征还是很重要的。对于这一部分,作者是说要用TCHAR的方式,经过查询MSDN发现上面比作者所得还要有条理,我就COPY上面的好了:

ms-help://MS.MSDNQTR.2003FEB.2052/vccore/html/_core_generic.2d.text_mappings_in_tchar..h.htm

Visual C++ 概念:添加功能  

TCHAR.H 中的一般文本映射

为简化代码传输以方便国际使用,Microsoft 运行时库为许多数据类型、例程和其他对象提供 Microsoft 特定的“一般文本”映射。您可以使用 TCHAR.H 中定义的这些代码,根据使用 #define 语句定义的清单常数,编写可以为单字节、多字节或 Unicode 编译的一般代码。一般文本映射是与 ANSI 不兼容的 Microsoft 扩展。

使用头文件 TCHAR.H 可以从同一个源中生成单字节、MBCS 和 Unicode 应用程序。TCHAR.H 定义以 _tcs 为前缀的宏,这些宏根据正确的预处理器定义映射到适当的 str_mbswcs 函数。若要生成 MBCS,请定义 _MBCS 符号。若要生成 Unicode,请定义 _UNICODE 符号。若要生成单字节应用程序,请不进行任何定义(默认)。默认情况下,为 MFC 应用程序定义的是 _MBCS

在 TCHAR.H 中根据条件定义 _TCHAR 数据类型。如果为您的版本定义了 _UNICODE 符号,则 _TCHAR 被定义为 wchar_t;否则,对于单字节和 MBCS 版本,_TCHAR 被定义为 char。(wchar_t 是基本的 Unicode 宽字符数据类型,它是与 8 位有符号 char 对应的 16 位有符号 char。)对于国际应用程序,使用以 _TCHAR(而非字节)为单位进行操作的 _tcs 函数族。例如,_tcsncpy 复制 n_TCHAR,而不是 n 个字节。

由于 SBCS 字符串处理函数采用(有符号的)char* 参数,因此定义 _MBCS 时将产生类型不匹配的编译器警告。有三种方法避免此警告,按效率高低的顺序依次为:

  1. 在 TCHAR.H 中使用“类型安全”内联函数 thunk。这是默认行为。
  2. 通过在命令行上定义 _MB_MAP_DIRECT,在 TCHAR.H 中使用“直接”宏。如果这样做,必须手动匹配类型。这是最快的方法,但不是类型安全的方法。
  3. 在 TCHAR.H 中使用“类型安全”静态链接库函数 thunk。若要这样做,请在命令行上定义 _NO_INLINING 常数。这是最慢的方法,但却是类型安全性最高的方法。

一般文本映射的预处理器指令

# define 编译版本 示例 _UNICODE Unicode(宽字符) _tcsrev 映射到 _wcsrev _MBCS 多字节字符 _tcsrev 映射到 _mbsrev 无(默认:既未定义 _UNICODE 也未定义 _MBCS) SBCS (ASCII) _tcsrev 映射到 strrev

例如,如果在程序中定义了 _MBCS,则 TCHAR.H 中定义的一般文本函数 _tcsrev 映射到 _mbsrev。或者如果在程序中定义了 _UNICODE,则 _tcsrev 映射到 _wcsrev。否则 _tcsrev 映射到 strrev。在 TCHAR.H 中还提供了其他数据类型映射以方便编程,但 _TCHAR 是最有用的。

一般文本数据类型映射

一般文本数据类型名 未定义 _UNICODE 或 _MBCS 已定义
_MBCS 已定义 _UNICODE
_TCHAR char char wchar_t _TINT int int wint_t _TSCHAR signed char signed char wchar_t _TUCHAR unsigned char unsigned char wchar_t _TXCHAR char unsigned char wchar_t _T_TEXT 无效(由预处理器移除) 无效(由预处理器移除) L(将后面的字符或字符串转换成相应的 Unicode 形式)

有关例程、变量和其他对象的一般文本映射的完整列表,请参见“运行时库参考”中的一般文本映射

注意     Unicode 字符串有可能包含嵌入空字节,所以不要在 Unicode 字符串中使用 str 函数族。同样道理,不要在 MBCS(或 SBCS)字符串中使用 wcs 函数族。

下列代码片段阐释了有关映射到 MBCS、Unicode 和 SBCS 模型的 _TCHAR_tcsrev 的用法。

_TCHAR *RetVal, *szString;RetVal = _tcsrev(szString);

如果已定义 _MBCS,则预处理器将此片段映射到下列代码:

char *RetVal, *szString;RetVal = _mbsrev(szString);

如果已定义 _UNICODE,则预处理器将此片段映射到下列代码:

wchar_t *RetVal, *szString;RetVal = _wcsrev(szString);

如果既未定义 _MBCS 也未定义 _UNICODE,则预处理器将此片段映射到单字节 ASCII 代码:

char *RetVal, *szString;RetVal = strrev(szString);

因此可以编写、维护和编译与三种字符集中任何一种的特定例程一起运行的单个源代码文件。

请参见

国际编程 | 在 _MBCS 代码中使用 TCHAR.H 数据类型

 

 

---------------------------

书中说到“格式字符串”,一开始还不太理解,其实不是我一开始理解的是用来定义字符串的格式。可能是翻译的问题吧,它的意思应该是包含了格式字符的字符串(比如说%d,/n都是格式字符)。BTW:这是我猜的:)

 
原创粉丝点击