📄 00000002.htm
字号:
数的字节都是这样的(Bigendian convention). 将一个 ASCII 或 Latin-1 的文件转换 <BR>成 UCS-2 只需简单地在每个 ASCII 字节前插入 0x00. 如果要转换成 UCS-4, 则必须在 <BR>每个 ASCII 字节前插入三个 0x00. <BR>在 Unix 下使用 UCS-2 (或 UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包 <BR>含一些特殊的字符, 比如 '\0' 或 '/', 它们在 文件名和其他 C 库函数参数里都有特 <BR>别的含义. 另外, 大多数使用 ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无 <BR>法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方, UCS- <BR>2 不适合作为 Unicode 的外部编码. <BR>在 ISO 10646-1 Annex R 和 RFC 2279 里定义的 UTF-8 编码没有这些问题. 它是在 U <BR>nix 风格的操作系统下使用 Unicode 的明显的方法. <BR>UTF-8 有一下特性: <BR>UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容). 这 <BR>意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 两种编码方式下是一样的. <BR>所有 >U+007F 的 UCS 字符被编码为一个多个字节的串, 每个字节都有标记位集. 因此 <BR>, ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的一部分. <BR>表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 到 0xFD 的范围里, 并指出这 <BR>个字符包含多少个字节. 多字节串的其余字节都在 0x80 到 0xBF 范围里. 这使得重新 <BR>同步非常容易, 并使编码无国界, 且很少受丢失字节的影响. <BR>可以编入所有可能的 231个 UCS 代码 <BR>UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 字符最多只用到 3 字 <BR>节长. <BR>Bigendian UCS-4 字节串的排列顺序是预定的. <BR>字节 0xFE 和 0xFF 在 UTF-8 编码中从未用到. <BR>下列字节串用来表示一个字符. 用到哪个串取决于该字符在 Unicode 中的序号. <BR>U-00000000 - U-0000007F: 0xxxxxxx <BR>U-00000080 - U-000007FF: 110xxxxx 10xxxxxx <BR>U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx <BR>U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx <BR>U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx <BR>U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxx <BR>xxx <BR>xxx 的位置由字符编码数的二进制表示的位填入. 越靠右的 x 具有越少的特殊意义. 只 <BR>用最短的那个足够表达一个字符编码数的多字节串. 注意在多字节串中, 第一个字节的 <BR>开头"1"的数目就是整个串中字节的数目. <BR>例如: Unicode 字符 U+00A9 = 1010 1001 (版权符号) 在 UTF-8 里的编码为: <BR>11000010 10101001 = 0xC2 0xA9 <BR>而字符 U+2260 = 0010 0010 0110 0000 (不等于) 编码为: <BR>11100010 10001001 10100000 = 0xE2 0x89 0xA0 <BR>这种编码的官方名字拼写为 UTF-8, 其中 UTF 代表 UCS Transformation Format. 请勿 <BR>在任何文档中用其他名字 (比如 utf8 或 UTF_8) 来表示 UTF-8, 当然除非你指的是一 <BR>个变量名而不是这种编码本身. <BR> <BR>什么编程语言支持 Unicode? <BR>在大约 1993 年之后开发的大多数现代编程语言都有一个特别的数据类型, 叫做 Unico <BR>de/ISO 10646-1 字符. 在 Ada95 中叫 Wide_Character, 在 Java 中叫 char. <BR>ISO C 也详细说明了处理多字节编码和宽字符 (wide characters) 的机制, 1994 年 9 <BR> 月 Amendment 1 to ISO C 发表时又加入了更多. 这些机制主要是为各类东亚编码而设 <BR>计的, 它们比处理 UCS 所需的要健壮得多. UTF-8 是 ISO C 标准调用多字节字符串的 <BR>编码的一个例子, wchar_t 类型可以用来存放 Unicode 字符. <BR>在 Linux 下该如何使用 Unicode? <BR>在 UTF-8 之前, 不同地区的 Linux 用户使用各种各样的 ASCII 扩展. 最普遍的欧洲编 <BR>码是 ISO 8859-1 和 ISO 8859-2, 希腊编码 ISO 8859-7, 俄国编码 KOI-8, 日本编码 <BR> EUC 和 Shift-JIS, 等等. 这使得 文件的交换非常困难, 且应用软件必须特别关心这 <BR>些编码的不同之处. <BR>最终, Unicode 将取代所有这些编码, 主要通过 UTF-8 的形式. UTF-8 将应用在 <BR>文本文件 (源代码, HTML 文件, email 消息, 等等) <BR>文件名 <BR>标准输入与标准输出, 管道 <BR>环境变量 <BR>剪切与粘贴选择缓冲区 <BR>telnet, modem 和到终端模拟器的串口连接 <BR>以及其他地方以前用ASCII来表示的字节串 <BR>在 UTF-8 模式下, 终端模拟器, 比如 xterm 或 Linux console driver, 将每次按键转 <BR>换成相应的 UTF-8 串, 然后发送到前台进程的 stdin 里. 类似的, 任何进程在 stdou <BR>t 上的输出都将发送到终端模拟器, 在那里用一个 UTF-8 解码器进行处理, 之后再用一 <BR>种 16 位的字体显示出来. <BR>只有在功能完善的多语言字处理器包里才可能有完全的 Unicode 功能支持. 而广泛用在 <BR> Linux 里用于取代 ASCII 和其他 8 位字符集的方案则要简单得多. 第一步, Linux 终 <BR>端模拟器和命令行工具将只是转变到 UTF-8. 这意味着只用到 级别1 的 ISO 10646-1 <BR>实现 (没有组合字符), 且只支持那些不需要更多处理的语言象 拉丁, 希腊, 斯拉夫 和 <BR>许多科学用符号. 在这个级别上, UCS 支持与 ISO 8859 支持类似, 唯一显著的区别是 <BR>现在我们有几千种字符可以用了, 其中的字符可以用多字节串来表示. <BR>总有一天 Linux 会当然地支持组合字符, 但即便如此, 对于组合字符串, 预作字符(如 <BR>何可用的话)仍将是首选的. 更正式地, 在 Linux 下用 Unicode 对文本编码的首选的方 <BR>法应该是定义在 Unicode Technical Report #15 里的 Normalization Form C. <BR>在今后的一个阶段, 人们可以考虑增加在日文和中文里用到的双字节字符的支持 (他们 <BR>相对比较简单), 组合字符支持, 甚至也许对从右至左书写的语言如希伯来文 (他们可不 <BR>是那么简单的) 的支持. 但对这些高级功能的支持不应该阻碍简单的平板 UTF-8 在 拉 <BR>丁, 希腊, 斯拉夫和科学用符号方面的快速应用, 以取代大量的欧洲 8 位编码, 并提供 <BR>一个象样的科学用符号集. <BR> <BR>我该怎样修改我的软件? <BR>有两种途径可以支持 UTF-8, 我称之为软转换与硬转换. 软转换时, 各处的数据均保存 <BR>为 UTF-8 形式, 因而需要修改的软件很少. 在硬转换时, 程序将读入的 UTF-8 数据转 <BR>换成宽字符数组, 以在应用程序内部处理. 在输出时, 再把字符串转换回 UTF-8 形式. <BR> <BR>大多数应用程序只用软转换就可以工作得很好了. 这使得将 UTF-8 引入 Unix 成为切实 <BR>可行的. 例如, 象 cat 和 echo 这样的程序根本不需要修改. 他们仍然可以对输入输出 <BR>的是 ISO 8859-2 还是 UTF-8 一无所知, 因为它们只是搬运字节流而没有处理它们. 它 <BR>们只能识别 ASCII 字符和象 '\n' 这样的控制码, 而这在 UTF-8 下也没有任何改变. <BR>因此, 这些应用程序的 UTF-8 编码与解码将完全在终端模拟器里完成. <BR>而那些通过数字节数来获知字符数量的程序则需要一些小修改. 在 UTF-8 模式下, 它们 <BR>必须不数入 0x80 到 0xBF 范围内的字节, 因为这些只是跟随字节, 它们本身并不是字 <BR>符. 例如, ls 程序就必须要修改, 因为它通过数文件名中字符数来排放给用户的目录表 <BR>格布局. 类似地, 所有的假定其输出为定宽字体, 并因此而格式化它们的程序, 必须学 <BR>会怎样数 UTF-8 文本中的字符数. 编辑器的功能, 如删除单个字符, 必须要作轻微的修 <BR>改, 以删除可能属于该字符的所有字节. 受影响有编辑器 (vi,emacs, 等等)以及使用 <BR>ncurses 库的程序. <BR>Linux 核心使用软转换也可以工作得很好, 只需要非常微小的修改以支持 UTF-8. 大多 <BR>数处理字符串的核心功能 (例如: 文件名, 环境变量, 等等) 都不受影响. 下列地方也 <BR>许必须修改: <BR>控制台显示与键盘驱动程序 (另一个 VT100 模拟器) 必须能编码和解码 UTF-8, 必须要 <BR>起码支持 Unicode 字符集的几个子集. 从 Linux 1.2 起这些功能已经有了. <BR>外部文件系统驱动程序, 例如 VFAT 和 WinNT 必须转换文件名字符编码. UTF-8 已经加 <BR>入可用的转换选项的列表里了, 因此 mount 命令必须告诉核心驱动程序用户进程希望看 <BR>到 UTF-8 文件名. 既然 VFAT 和 WinNT 无论如何至少已经用了 Unicode了, 那么 UTF <BR>-8 在这里就可以发挥其优势, 以保证转换中无信息损失. <BR>POSIX 系统的 tty 驱动程序支持一种 "cooked" 模式, 有一些原始的行编辑功能. 为了 <BR>让字符删除功能工作正常, stty 必须在 tty 驱动程序里设置 UTF-8 模式, 因此它就不 <BR>会把 0x80 到 0xBF 范围内的跟随字符也数进去了. Bruno Haible 那里已经有了一些 <BR>stty 和核心 tty 驱动 程序的 Linux 补丁 了. <BR>C 对 Unicode 和 UTF-8 的支持 <BR>从 GNU glibc 2.1 开始, wchar_t 类型已经正式定为只存放独立于当前 locale 的, 3 <BR>2位的 ISO 10646 值. glibc 2.2 开始将完全支持 ISO C 中的多字节转换函数 (wprin <BR>tf(),mbstowcs(),等等), 这些函数可以用于在 wchar_t 和包括 UTF-8 在内的任何依赖 <BR>于 locale 的多字节编码间进行转换. <BR>例如, 你可以写 <BR> wprintf(L"Sch鰊e Gr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -