当前位置:Linux教程 - Linux - 怎样在程序中使用 Unicode

怎样在程序中使用 Unicode



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

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

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

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


    文本文件 (源代码, HTML 文件, email 消息, 等等)
    文件名
    标准输入与标准输出, 管道
    环境变量
    剪切与粘贴选择缓冲区
    telnet, modem 和到终端模拟器的串口连接
    以及其他地方以前用ASCII来表示的字节串
    在 UTF-8 模式下, 终端模拟器, 比如 xterm 或 Linux console driver, 将每次按键转换成相应的 UTF-8 串, 然后发送到前台进程的 stdin 里. 类似的, 任何进程在 stdout 上的输出都将发送到终端模拟器, 在那里用一个 UTF-8 解码器进行处理, 之后再用一种 16 位的字体显示出来.

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

    总有一天 Linux 会当然地支持组合字符, 但即便如此, 对于组合字符串, 预作字符(如何可用的话)仍将是首选的. 更正式地, 在 Linux 下用 Unicode 对文本编码的首选的方法应该是定义在 Bruno Haible 那里已经有了一些 stty 和核心 tty 驱动 程序的 Linux 补丁 了.

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

    例如, 你可以写

    wprintf(L\"Sch鰊e Gre!\\n\");
    然后, 你的软件将按照你的用户在环境变量 LC_CTYPE (例如, en_US.UTF-8 或 de_DE.ISO_8859-1) 中选择的 locale 所指定的编码来打印这段文字. 你的编译器必须运行在与该 C 源文件所用编码相应的 locale 中, 在目标文件中以上的宽字符串将改为 wchar_t 字符串存储. 在输出时, 运行时库将把 wchar_t 字符串转换回与程序执行时的 locale 相应的编码.

    注意, 类似这样的操作:

    char c = L\"a\";
    只允许从 U+0000 到 U+007F (7 位 ASCII) 范围里的字符. 对于非 ASCII 字符, 不能直接从 wchar_t 到 char 转换.

    现在, 象 readline() 这样的函数在 UTF-8 locale 下也能工作了.

    怎样激活 UTF-8 模式?
    如果你的应用程序既支持 8 位字符集 (ISO 8859-*,KOI-8,等等), 也支持 UTF-8, 那么它必须通过某种方法以得知是否应使用 UTF-8 模式. 幸运的是, 在未来的几年里, 人们将只使用 UTF-8, 因此你可以将它作为默认, 但即使如此, 你还是得既支持传统 8 位字符集, 也支持 UTF-8.

    当前的应用程序使用许许多多的不同的命令行开关来激活它们各自的 UTF-8 模式, 例如:


    xterm 命令行选项 \"-u8\" 和 X resource \"XTerm*utf8:1\"
    gnat/gcc 命令行选项 \"-gnatW8\"
    stty 命令行选项 \"iutf8\"
    mined 命令行选项 \"-U\"
    xemacs elisp 包裹 以在 UTF-8 和内部使用的 MULE 编码间转换
    vim \fileencoding\ 选项
    less 环境变量 LESSCHARSET=utf-8
    记住每一个应用程序的命令行选项或其他配置方法是非常单调乏味的, 因此急需某种标准方法.

    如果你在你的应用程序里使用硬转换, 并使用某种特定的 C 库函数来处理外部字符编码和内部使用的 wchar_t 编码的转换工作, 那么 C 库会帮你处理模式切换的问题. 你只需将环境变量 LC_CTYPE 设为正确的 locale, 例如, 如果你使用 UTF-8, 那就是en.UTF-8, 而如果是 Latin-1, 并需要英语的转换, 则设为 en.ISO_8859-1.

    然而, 大多数现存软件的维护者选择用软转换来代替, 而不使用 libc 的宽字符函数, 不仅因为它们还未得到广泛应用, 还因为这会使得软件进行大规模修改. 在这种情况下, 你的应用程序必须自己来获知何时使用 UTF-8 模式. 一种方式是做以下工作:

    按照环境变量 LC_ALL, LC_CTYPE, LANG 的顺序, 寻找第一个有值的变量. 如果该值包含 UTF-8 子串 (也许是小写或没有\"-\") 则默认为 UTF-8 模式 (仍然可以用命令行开关来重设), 因为这个值可靠又恰当地指示了 C 库应该使用一种 UTF-8 locale.

    提供一个命令行选项 (或者如果是 X 客户程序则用 X resource 的值) 将仍然是有用的, 可以用来重设由 LC_CTYPE 等环境变量指定的默认值.
    发布人:netbull 来自:it365