⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unicode.htm

📁 说明了在 POSIX 系统 (Linux,Unix) 上使用 Unicode/UTF-8 所需要的信息. 在将来不远的几年里, Unicode 已经很接近于取代 ASCII 与 Latin-1 编码的
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    两种编码方式下是一样的.</li>
  <li>所有 &gt;U+007F 的 UCS 字符被编码为一个多个字节的串, 
    每个字节都有标记位集. 因此, ASCII 字节 (0x00-0x7F) 
    不可能作为任何其他字符的一部分.</li>
  <li>表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 到 0xFD 
    的范围里, 并指出这个字符包含多少个字节. 
    多字节串的其余字节都在 0x80 到 0xBF 范围里. 
    这使得重新同步非常容易, 并使编码无国界, 
    且很少受丢失字节的影响.</li>
  <li>可以编入所有可能的 2<sup>31</sup>个 UCS 代码</li>
  <li>UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 
    字符最多只用到 3 字节长.</li>
  <li>Bigendian UCS-4 字节串的排列顺序是预定的.</li>
  <li>字节 0xFE 和 0xFF 在 UTF-8 编码中从未用到.</li>
</ul>

<p>下列字节串用来表示一个字符. 用到哪个串取决于该字符在 Unicode 
中的序号.</p>
<div align="center"><center>

<table BORDER="1">
  <tr>
    <td>U-00000000 - U-0000007F: </td>
    <td>0<i>xxxxxxx</i> </td>
  </tr>
  <tr>
    <td>U-00000080 - U-000007FF: </td>
    <td>110<i>xxxxx</i> 10<i>xxxxxx</i> </td>
  </tr>
  <tr>
    <td>U-00000800 - U-0000FFFF: </td>
    <td>1110<i>xxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> </td>
  </tr>
  <tr>
    <td>U-00010000 - U-001FFFFF: </td>
    <td>11110<i>xxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> </td>
  </tr>
  <tr>
    <td>U-00200000 - U-03FFFFFF: </td>
    <td>111110<i>xx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> </td>
  </tr>
  <tr>
    <td>U-04000000 - U-7FFFFFFF: </td>
    <td>1111110<i>x</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 10<i>xxxxxx</i> 
    </td>
  </tr>
</table>
</center></div>

<p>xxx 的位置由字符编码数的二进制表示的位填入. 越靠右的 x 
具有越少的特殊意义. 
只用最短的那个足够表达一个字符编码数的多字节串. 
注意在多字节串中, 第一个字节的开头&quot;1&quot;的数目就是整个串中字节的数目.</p>

<p><strong>例如</strong>: Unicode 字符 U+00A9 = 1010 1001 (版权符号) 在 UTF-8 
里的编码为:</p>

<blockquote>
  <p>11000010 10101001 = 0xC2 0xA9</p>
</blockquote>

<p>而字符 U+2260 = 0010 0010 0110 0000 (不等于) 编码为:</p>

<blockquote>
  <p>11100010 10001001 10100000 = 0xE2 0x89 0xA0</p>
</blockquote>

<p>这种编码的官方名字拼写为 UTF-8, 其中 UTF 代表 <strong>U</strong>CS <strong>T</strong>ransformation 
<strong>F</strong>ormat. 请勿在任何文档中用其他名字 (比如 utf8 或 UTF_8) 
来表示 UTF-8, 当然除非你指的是一个变量名而不是这种编码本身.</p>

<h2>什么编程语言支持 Unicode?</h2>

<p>在大约 1993 
年之后开发的大多数现代编程语言都有一个特别的数据类型, 叫做 
Unicode/ISO 10646-1 字符. 在 Ada95 中叫 Wide_Character, 在 Java 中叫 char.</p>

<p>ISO C 也详细说明了处理多字节编码和宽字符 (wide characters) 的机制, 
1994 年 9 月 <a href="http://www.lysator.liu.se/c/na1.html">Amendment 1 to ISO C</a> 
发表时又加入了更多. 这些机制主要是为各类东亚编码而设计的, 
它们比处理 UCS 所需的要健壮得多. UTF-8 是 ISO C 
标准调用多字节字符串的编码的一个例子, <em>wchar_t</em> 
类型可以用来存放 Unicode 字符.</p>

<h2>在 Linux 下该如何使用 Unicode?</h2>

<p>在 UTF-8 之前, 不同地区的 Linux 用户使用各种各样的 ASCII 扩展. 
最普遍的欧洲编码是 ISO 8859-1 和 ISO 8859-2, 希腊编码 ISO 8859-7, 
俄国编码 KOI-8, 日本编码 EUC 和 Shift-JIS, 等等. 这使得 
文件的交换非常困难, 且应用软件必须特别关心这些编码的不同之处.</p>

<p>最终, Unicode 将取代所有这些编码, 主要通过 UTF-8 的形式. UTF-8 
将应用在 

<ul>
  <li>文本文件 (源代码, HTML 文件, email 消息, 等等)</li>
  <li>文件名</li>
  <li>标准输入与标准输出, 管道</li>
  <li>环境变量</li>
  <li>剪切与粘贴选择缓冲区</li>
  <li>telnet, modem 和到终端模拟器的串口连接</li>
  <li>以及其他地方以前用ASCII来表示的字节串</li>
</ul>

<p>在 UTF-8 模式下, 终端模拟器, 比如 xterm 或 Linux console driver, 
将每次按键转换成相应的 UTF-8 串, 然后发送到前台进程的 stdin 里. 
类似的, 任何进程在 stdout 上的输出都将发送到终端模拟器, 
在那里用一个 UTF-8 解码器进行处理, 之后再用一种 16 
位的字体显示出来.</p>

<p>只有在功能完善的多语言字处理器包里才可能有完全的 Unicode 
功能支持. 而广泛用在 Linux 里用于取代 ASCII 和其他 8 
位字符集的方案则要简单得多. 第一步, Linux 
终端模拟器和命令行工具将只是转变到 UTF-8. 这意味着只用到 级别1 
的 ISO 10646-1 实现 (没有组合字符), 
且只支持那些不需要更多处理的语言象 拉丁, 希腊, 斯拉夫 
和许多科学用符号. 在这个级别上, UCS 支持与 ISO 8859 支持类似, 
唯一显著的区别是现在我们有几千种字符可以用了, 
其中的字符可以用多字节串来表示.</p>

<p>总有一天 Linux 会当然地支持组合字符, 但即便如此, 
对于组合字符串, 预作字符(如何可用的话)仍将是首选的. 更正式地, 
在 Linux 下用 Unicode 对文本编码的首选的方法应该是定义在 <a
href="http://www.unicode.org/unicode/reports/tr15/">Unicode Technical Report #15</a> 
里的 <em>Normalization Form C.</em></p>

<p>在今后的一个阶段, 
人们可以考虑增加在日文和中文里用到的双字节字符的支持 (他们相对比较简单), 
组合字符支持, 甚至也许对从右至左书写的语言如希伯来文 (他们可不是那么简单的) 
的支持. 但对这些高级功能的支持不应该阻碍简单的平板 UTF-8 在 
拉丁, 希腊, 斯拉夫和科学用符号方面的快速应用, 以取代大量的欧洲 
8 位编码, 并提供一个象样的科学用符号集.</p>

<h2>我该怎样修改我的软件?</h2>

<p>有两种途径可以支持 UTF-8, 我称之为软转换与硬转换. 软转换时, 
各处的数据均保存为 UTF-8 形式, 因而需要修改的软件很少. 
在硬转换时, 程序将读入的 UTF-8 数据转换成宽字符数组, 
以在应用程序内部处理. 在输出时, 再把字符串转换回 UTF-8 形式.</p>

<p>大多数应用程序只用软转换就可以工作得很好了. 这使得将 UTF-8 
引入 Unix 成为切实可行的. 例如, 象 cat 和 <samp>echo</samp> 
这样的程序根本不需要修改. 他们仍然可以对输入输出的是 ISO 8859-2 
还是 UTF-8 一无所知, 因为它们只是搬运字节流而没有处理它们. 
它们只能识别 ASCII 字符和象 '\n' 这样的控制码, 而这在 UTF-8 
下也没有任何改变. 因此, 这些应用程序的 UTF-8 
编码与解码将完全在终端模拟器里完成.</p>

<p>而那些通过数字节数来获知字符数量的程序则需要一些小修改. 在 
UTF-8 模式下, 它们必须不数入 0x80 到 0xBF 范围内的字节, 
因为这些只是跟随字节, 它们本身并不是字符. 例如, <samp>ls</samp> 
程序就必须要修改, 
因为它通过数文件名中字符数来排放给用户的目录表格布局. 类似地, 
所有的假定其输出为定宽字体, 并因此而格式化它们的程序, 
必须学会怎样数 UTF-8 文本中的字符数. 编辑器的功能, 
如删除单个字符, 必须要作轻微的修改, 
以删除可能属于该字符的所有字节. 受影响有编辑器 (<samp>vi,emacs</samp>, 
等等)以及使用 <samp>ncurses</samp> 库的程序.</p>

<p>Linux 核心使用软转换也可以工作得很好, 
只需要非常微小的修改以支持 UTF-8. 大多数处理字符串的核心功能 (例如: 
文件名, 环境变量, 等等) 都不受影响. 下列地方也许必须修改: 

<ul>
  <li>控制台显示与键盘驱动程序 (另一个 VT100 模拟器) 
    必须能编码和解码 UTF-8, 必须要起码支持 Unicode 字符集的几个子集. 
    从 Linux 1.2 起这些功能已经有了.</li>
  <li>外部文件系统驱动程序, 例如 VFAT 和 WinNT 必须转换文件名字符编码. 
    UTF-8 已经加入可用的转换选项的列表里了, 因此 <samp>mount</samp> 
    命令必须告诉核心驱动程序用户进程希望看到 UTF-8 文件名. 既然 VFAT 
    和 WinNT 无论如何至少已经用了 Unicode了, 那么 UTF-8 
    在这里就可以发挥其优势, 以保证转换中无信息损失.</li>
  <li>POSIX 系统的 tty 驱动程序支持一种 &quot;cooked&quot; 模式, 
    有一些原始的行编辑功能. 为了让字符删除功能工作正常, <samp>stty</samp> 
    必须在 tty 驱动程序里设置 UTF-8 模式, 因此它就不会把 0x80 到 0xBF 
    范围内的跟随字符也数进去了. <a href="http://clisp.cons.org/~haible/">Bruno 
    Haible</a> 那里已经有了一些 <samp>stty</samp> 和核心 tty 驱动 程序的 <a
    href="ftp://ftp.ilog.fr/pub/Users/haible/utf8/">Linux 补丁 </a>了.</li>
</ul>

<h2>C 对 Unicode 和 UTF-8 的支持</h2>

<p>从 GNU glibc 2.1 开始, <samp>wchar_t</samp> 
类型已经正式定为只存放独立于当前 locale 的, 32位的 ISO 10646 值. glibc 
2.2 开始将完全支持 ISO C 中的多字节转换函数 (wprintf(),mbstowcs(),等等), 
这些函数可以用于在 wchar_t 和包括 UTF-8 在内的任何依赖于 locale 
的多字节编码间进行转换.</p>

<p>例如, 你可以写</p>

<pre>  wprintf(L&quot;Sch鰊e Gr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -