每一个软件开发人员绝对必须掌握的关于 Unicode 和字符集的最基础的知识[2]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

而且你还要搞清楚是高位在前的,还是高位在后的 UCS-2.

还有一种就是新的 UTF-8. 如果你的程序只使用英文的话,它仍然会工作正常。

实际上还有一堆的其他办法对 Unicode 进行编码:
有 UTF-7,这种编码方式大部分和 UTF-8 相同,但保证高位一定为 0.
所以如果你必须通过某种 Email 系统传送 Unicode,这些系统认为 7 位足够了,那使用 UTF-7 会正常。
还有 UCS-4, 储存每一个 code point 为 4 个字节。它的优点是每一个字符都保存为同样长的。但很明显,缺点是浪费太多存储空间了。

所以,现在你思考问题要把每一个字符想象成抽象的一个 unicode code point. 而它们同样可以使用任何旧的方式编码。
举例来说,你可以把 Unicode 字符串 Hello (U+0048 U+0065 U+006C U+006C U+006F) 编码(encode)为
ASCII, 或者古老的 OEM 希腊语编码,或者希柏莱 ANSI 编码,等等。而有些字符串不能显示!
也就是说,假如你要表示一个在某个编码中没有对应的 Unicode code point, 通常会显示为一个 ? 或者一个白色的小方框。

英文常用的一些编码有, Windows-1252(Windows 9x 标准 for 西欧语言)
以及 ISO-8859-1, aka Latin-1(对任何西欧语言也有效)
如果用这些编码来尝试存储俄文字符,你会得到一堆的 ?

UTF 7, 8, 16 以及 32 都有一个优点,能够正确的存储任何的 code point.

最简单,也是最重要的几个概念
====================================================================
一个字符串不指定它使用什么编码是没有意义的。
再也不要假定, “纯”文本(plain text) 是 ASCII.
没有 “纯文本” 这个东西。

如果你有一个字符串,在内存中,在文件中,或者在 Email 消息里,你必须知道它的编码是什么。否则你无法正确的解释或者显示给用户。
所有的诸如 “我的网页不能正常显示了”,或者 ”Email 消息不能正常显示了“ 之类的愚蠢问题, 都是因为, 没有告诉你到底是使用的那种编码,
UTF-8 还是 ASCII 还是 ISO 8859-1 或者 Windows 1252 ?? 那么自然无法正常的解释和显示,甚至不知道字符串该在哪里结束。

那么如何保留这样的编码标志,来表示字符串的编码? 有一些基本的办法。
比如对于 Email 来说,在表单的 header 中加上:

Content-Type:text/plain;charset="UTF-8"

对于 Web 页面来说,原来的做法是, Web 服务器随着 web 页面本身一起,发送一个类似于 Content-Type 的 http header.
(不是在 HTML 里面,而是作为一个 response header 在 HTML 页之前发送)

这样做有一个问题。如果你的 Web 服务器同时有多个站点,站点由多个不同的人用不同的语言开发的程序混在一起。那么 Web 服务器将无从得知,
每一个文件是用什么编码方式写的。这样也就无法发送正确的 Content-Type header.
如果你能够在每一个 HTML 文件中记录 Content-Type 信息,那么就很方便了。可这念头似乎也很疯狂,因为你还没有知道用什么编码方式去
读取这个文件,又怎么能读出编码信息呢?
幸好,几乎每一种编码中,对 32~127 的字符都解释的相同。所以你可以在每一个 html 文件中这么写:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

但是要注意, 这个 meta 标签必须放在 head 中靠前面的位置才能保证不会出问题。 因为 Web 服务器读到这里的时候,就会停止解析,
然后用读到的这个编码方式重新解析页面。

那么,作为 Web 浏览器来说,如果没有在 meta 标签中或者 http headers 中发现 Content-Type, 会怎么样呢?
IE 是这么做的:
先尝试去猜,根据特定的字节出现在各种语言的典型的编码中的频率。
如果编码设定不正常,用户可以通过 View|Encoding 菜单来尝试不同的编码方式。(当然,不是每个人都知道该这样做)

在 VB, COM, Windows NT/2000/XP 中,默认的字符串类型是 UCS-2(2字节)的。
在 C++ 代码中, 我们可以定义字符串为 wchar_t(wide char),同时用 wcs 系列的函数代替 str 系列的函数。
如 wcscat, wcslen, 而不是 strcat, strlen.

本文关键:每一个软件开发人员绝对必须掌握的关于 Unicode 和字符集的最基础的知识
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top