c - Emacs、xterm、鼠标垫、C、Unicode 和 UTF-8 : Trying to make sense of it all

标签 c emacs unicode utf-8 xterm

免责声明:对于下面的所有文字(针对一个简单的问题),我深表歉意,但我真诚地认为每一点信息都与该问题相关。我很乐意学习其他方式。我只能希望,如果成功的话,问题和答案可以帮助其他陷入 Unicode 疯狂的人。开始吧。

我已经阅读了所有关于 utf8 的通常备受推崇的网站,尤其是 this one非常适合我的目的,但我也读过经典,就像 SO 中其他类似问题中提到的那样。但是,我仍然缺乏关于如何将其全部集成到我的虚拟实验室中的知识。我将 Emacs 与

一起使用
;; Internationalization
(prefer-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)

在我的 .emacs 中,xterm 以

开头
 LC_CTYPE=en_US.UTF-8 xterm -geometry 91x58\
-fn '-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO10646-1'

我的语言环境是:

LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

我的问题如下(一些答案可能是应用程序的预期行为,但我仍然需要理解它,所以请耐心等待):

假设有以下 C 程序:

#include <stdio.h>

int main(void) {
  int c;
  while((c=getc(stdin))!=EOF) {
    if(c!='\n') {
      printf("Character: %c, Integer: %d\n", c, c);
    }
  }
  return 0;
}

如果我在我的 xterm 中运行它,我会得到:

€
Character: � Integer: 226
Character: �, Integer: 130
Character: �, Integer: 172

(以防万一我得到的字符是黑色圆圈内的白色问号)。整数是编码 € 所需的 3 个字节的十进制表示,但我不确定为什么 xterm 不能正确显示它们。

相反,鼠标垫,例如,打印

Character: â, Integer: 226
Character: ,, Integer: 130 (a comma, standing forU+0082 <control>, why?!)
Character: ¬, Integer: 172

与此同时,Emacs 显示

Character: \342, Integer: 226
Character: \202, Integer: 130
Character: \254, Integer: 172

问题:我能问的最普遍的问题是:如何让所有内容打印相同的字符?但我确信会有后续行动。

再次感谢,并对所有文字表示歉意。

最佳答案

好的,所以您的问题是由于混合了老式 C 库调用(getc、printf %c)和 UTF-8。您的代码正确读取组成“€”的三个字节 - 十进制的 226、130 和 172 - 但这些值单独不是有效的 UTF-8 编码字形。

如果您查看 UTF-8 encoding , 整数值 0..127 是原始 US-ASCII 字符集的编码。但是 128..255(即所有字节)是多字节 UTF-8 字符的一部分,因此不对应于一个有效的 UTF-8 字符。

换句话说,单个字节“226”本身并不意味着任何东西(因为它是 3 字节字符的前缀 - 正如预期的那样)。 printf 调用将其打印为单个字节,这对于 UTF-8 编码是无效的,因此每个不同的程序以不同的方式处理无效值。

假设您只想“查看”UTF-8 字符由哪些字节组成,我建议您坚持使用已有的整数输出(或者使用十六进制,如果这更明智的话)——因为您的 >127 字节 arn如果没有有效的 unicode,您不太可能在不同的程序中获得一致的结果。

关于c - Emacs、xterm、鼠标垫、C、Unicode 和 UTF-8 : Trying to make sense of it all,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1145889/

相关文章:

c - 输入最后一个数组元素时出现段错误

无法获取 libsodium 预构建库供 mingw windows 工作

emacs - emacs lisp 中符号名和变量名的区别

python - Python 2 如何在内部表示 Unicode?

python - 如何从数据库模型 __repr__ 键入 unicode

计算C中耗时

c - 为什么我除法时会跳过数字?

Emacs:如何编写一个作用于区域的defun,但如果没有区域则作用于点?

emacs - 覆盖主要模式的自动加载

python - Python/Django 中的 Unicode 与 UTF-8 混淆?