学习 unicode 也有一段时间了,虽然说没有学得很好,但是却是学到了许多东西啊,所以稍微小结一下,免得忘了,呵呵。很早就接触过 unicode 这个词了。不过以前太天真了,以为 unicode 是一件非常简单的事情,很容易就解决了。只要用 TCHAR 代替 CHAR ,在所有的字符串前面加上 TEXT ,然后在 vc 里面 Preprocessor definitions 加上 _UNICODE , UNICODE 就 OK 了。实际上,仅仅这样,还有很多疑惑不能解决。
1、 Windows XP 完全使用 unicode 开发,那为什么在 xp 下还会有乱码呢?
内码的存在,内码不兼容 unicode 。或者要解释的不是unicode,而当前不支持该编码。
2、 为什么有 UTF-8 、 16 、 32 ?为什么说 UTF-8 是 unicode 的呢? unicode 不都是 16 位的吗?
为了兼容现在的编码。
3、 codepage 是什么东西?为什么存在?
4、 什么是国际化、本地化?为什么国际化、本地化那么困难?
Locale 。举个简单的例子:不同地方的日期的显示格式不同。
5、 DBCS 是什么咚咚?它与 UTF-8 , unicode 有什么联系?
UTF-8 是属于 unicode 规范的,而 DBCS 不是。 UTF-8 是不定字节的(从一字节到六字节),而 DBCS 是双字节的。 DBCS 与 ASCII 同时存在来处理远东的一些字符(结合 codepage 来使用, GBK 与 Big5 的 range 就有交错的),而 UTF-8 是 unicode 规范的实现,它包含了所有的字符。从 Windows2K 开始,从 Windows 系统的底层实现,已经全面基于 Unicode ,同时仍保证完全兼容 ANSI/DBCS 程序。
以下是对我这一阶段学习的小结:
一、 什么是 unicode ?
一、 什么是 unicode ?
Unicode provides a unique number for every character,
no matter what the platform,
no matter what the program,
no matter what the language.
no matter what the platform,
no matter what the program,
no matter what the language.
历史上有两个组织想独立创立单一字符集,一个是国际标准化组织( ISO )的 ISO 10646 ,另一个是由很多大企业( Apple 、 Compaq 、 HP 、 IBM 、 Microsoft 、 Oracle 等)组成的协会组织的 unicode 。 1991 年前后,他们合并了双方的工作,统一了编码表。虽然这两个组织都还独立的存在,但是他们的标准是兼容的。
Unicode 协会公布的 Unicode 标准严密地包含了 ISO 10646-1 实现级别 3 的基本多语言面。在两个标准里所有的字符都在相同的位置并且有相同的名字。
Unicode 标准额外定义了许多与字符有关的语义符号学,一般而言是对于实现高质量的印刷出版系统的更好的参考。 Unicode 详细说明了绘制某些语言 ( 比如阿拉伯语 ) 表达形式的算法,处理双向文字 ( 比如拉丁与希伯来文混合文字 ) 的算法和排序与字符串比较所需的算法,以及其他许多东西。
另一方面 , ISO 10646 标准 , 就象广为人知的 ISO 8859 标准一样 , 只不过是一个简单的字符集表 . 它指定了一些与标准有关的术语 , 定义了一些编码的别名 , 并包括了规范说明 , 指定了怎样使用 UCS 连接其他 ISO 标准的实现 , 比如 ISO 6429 和 ISO 2022. 还有一些与 ISO 紧密相关的 , 比如 ISO 14651 是关于 UCS 字符串排序的 .
考虑到 Unicode 标准有一个易记的名字 , 且在任何好的书店里的 Addison-Wesley 里有 , 只花费 ISO 版本的一小部分 , 且包括更多的辅助信息 , 因而它成为使用广泛得多的参考也就不足为奇了 .
二、 UTF-8 、 16 、 32
UTF : Unicode Transformation Format
首先 UCS ( Unicode Char Set )和 Unicode 只是分配整数给字符的编码表 . 现在存在好几种将一串字符表示为一串字节的方法 . 最显而易见的两种方法是将 Unicode 文本存储为 2 个 或 4 个字节序列的串 . 这两种方法的正式名称分别为 UCS-2 ( UTF-16 )和 UCS-4 ( UTF-32 ) . 除非另外指定 , 否则大多数的字节都是这样的 (Bigendian convention). 将一个 ASCII 或 Latin-1 的文件转换成 UCS-2 只需简单地在每个 ASCII 字节前插入 0x00. 如果要转换成 UCS-4, 则必须在每个 ASCII 字节前插入三个 0x00.
在 Unix 下使用 UCS-2 ( 或 UCS-4) 会导致非常严重的问题 . 用这些编码的字符串会包含一些特殊的字符 , 比如 '/0' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特别的含义 . 另外 , 大多数使用 ASCII 文件的 UNIX 下的工具 , 如果不进行重大修改是无法读取 16 位的字符的 . 基于这些原因 , 在文件名 , 文本文件 , 环境变量等地方 , UCS-2 不适合作为 Unicode 的外部编码 .
在 ISO 10646-1 Annex R 和 RFC 2279 里定义的 UTF-8 编码没有这些问题 . 它是在 Unix 风格的操作系统下使用 Unicode 的明显的方法 .
UTF-8 看起来不像是 unicode ,它只是作为一种过渡形态存在,作为新旧编码之间交互的桥梁。虽然它是遵循 unicode 规范的,但它更像是 DBCS 的改善版,是一种 MBCS ( multi-byte char set )。显然这个世界上不可能很快就完全 unicode , UTF-8 还将会一直存在下去。 Window NT 操作系统的基本文本表示是 UTF-16 , WCHAR 是其基本数据类型。
UTF-8 以字节为编码单元,没有字节序的问题。 UTF-16 以两个字节为编码单元,在解释一个 UTF-16 文本前,首先要弄清楚每个编码单元的字节序。 Unicode 规范使用 BOM ( Byte Order Mark )来标记字节顺序。在 UCS 编码中有一个叫做“ ZERO WIDTH NO-BREAK SPACE ”的字符,它的编码是 FEFF 。而 FFFE 在 UCS 中是不存在的字符。所以,如果接收到 FEFF 就表明这个字节流是 Big-Endian 的;如果是 FFFE 则是 little endian 。 UTF-8 不需要用 BOM 来表明字节序,但可以用 BOM 来表明编码方式。 FEFF 的 UTF-8 编码是 EF BB BF 。
以下就是 UTF-8 的模板
0x0000 - 0x007F 用一个字节表示 0xxxxxxx
0x0080 - 0x07FF 用两个字节表示 110xxxxx 10xxxxxx
0x0800 - 0xFFFF 用三个字节表示 1110xxxx 10xxxxxx 10xxxxxx
举个例子,如果你遇到了 11100110 10110001 10001001 01000001 这样的字节流,首先你看第一个字节以 1110 开头,即读 3 个字节并按模板提取得到 0110 110001 001001( 去除模板标志﹐再四字节四字节读即 0x6c49) ,查 unicode 编码表就是 " 汉 " 字 , 而最后一个以 0 开头就一定是一个字节了, 0x0041 ,也就是 "A" 。
三、 字符集、字符编码、内码
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。像 ASCII 、 GB2312 、 Big5 都是属于字符编码。当然 UTF-8 、 16 也是一种字符编码。而 unicode 则是一种规范。
GB2312 是大陆的字符编码标准,属于国家标准。它是与 ASCII 码兼容的。后来又有 GBK1.0 、 GB18030 等字符编码标准,这些都是向下兼容的,但横向不兼容!比如 GB2312 与 Big5 在很多编码上是重叠的,是不兼容的; Unicode 与 GB 标准码也是不兼容的。中文操作系统的内码是 GBK 编码。
由于现有的大量程序和文档都采用乐某种特定语言的编码,例如 GBK , windows 不可能不支持现有代码,而全部采用 unicode !这就是为什么 windows 使用了内码机制。为了支持更多的地方语言文字, windows 还使用了 code page 机制以使 windows 能够更方便的适应不同地方的语言文字。 GBK 对应的 code page 是 CP936 , windows 代码页只支持单字节和双字节编码的。
GB2312-80 ,是中国大陆使用的国家标准,其中一共编码了 6763 个常用简体汉字。 Big5 ,是台湾使用的编码标准,编码了中国台湾使用的繁体汉字,大概有 8 千多个。 HKSCS ,是中国香港使用的编码标准,字体也是繁体,但跟 Big5 有所不同。
四、 VC 中的 Unicode 编程
这个网上的资料有很多的,最重要的一个概念就是 T , W , _UNICODE 、 UNICODE 等。这个理解起来感觉简单很多,因为只要你在程序中都使用 Unicode 就好了。数据的传输、数据的保存、数据的使用、转化都使用 Unicode (目前基本上都是使用 UTF-8 比较多吧)。当然了,这里肯定还是会有编码格式转化的问题的,比如输入的不是 Unicode ,输出的不能是 Unicode 等。但只要你在程序中都使用 Unicode 就解决问题了。是不是我想得太简单了?
上面这些东西,很多是我从网上摘抄下来的,也有少部分是我自己的理解。如果有什么不对的地方,敬请指教。如果有什么讲的不清楚的、或者需要讲一下的,请提出来。如果有什么希望能够一起讨论讨论的,欢迎给我发邮件或回帖讨论!
Double-byte Character Sets
A double-byte character set (DBCS), also known as an "expanded 8-bit character set", is an extended single-byte character set (SBCS), implemented as a code page. DBCSs were originally developed to extend the SBCS design to handle languages such as Japanese and Chinese. Some characters in a DBCS, including the digits and letters used for writing English, have single-byte code values. Other characters, such as Chinese ideographs or Japanese kanji, have double-byte code values. A DBCS can correspond either to a Windows code page or an OEM code page. A DBCS code page can also include a non-native code page, for example, an EBCDIC code page. For definitions of these code pages, see Code Pages.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_9i79.asp
from MSDN
A double-byte character set (DBCS), also known as an "expanded 8-bit character set", is an extended single-byte character set (SBCS), implemented as a code page. DBCSs were originally developed to extend the SBCS design to handle languages such as Japanese and Chinese. Some characters in a DBCS, including the digits and letters used for writing English, have single-byte code values. Other characters, such as Chinese ideographs or Japanese kanji, have double-byte code values. A DBCS can correspond either to a Windows code page or an OEM code page. A DBCS code page can also include a non-native code page, for example, an EBCDIC code page. For definitions of these code pages, see Code Pages.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_9i79.asp
from MSDN