【问题标题】:Why are these Unicode characters not printed although I set my environment to UTF8?尽管我将环境设置为 UTF8,但为什么不打印这些 Unicode 字符?
【发布时间】:2013-03-27 23:33:58
【问题描述】:

如何打印一些 Unicode 字符?虽然我设置了 UTF-8 编码,但我无法打印它。我在连续的字节流中将十六进制的 Unicode 字符作为 (c2 82 c2 81 c2 80 0) 获取。但是当我试图通过在开头指向一个字符指针来打印它的 Unicode 字符时,它并没有打印出来。为什么?

   char s[]={0xc2,0x82,0xc2,0x81,0xc2,0x80,0x00};
   printf("%s",s);

在 Linux 环境中使用 C。

【问题讨论】:

  • 您在此处提供的char s[] 不以零字符 ('\0') 结尾,因此 printf 无法工作:它将打印垃圾,直到找到零字符或将进行核心转储。
  • 我做了,但程序没有打印任何字符
  • 您的终端是否配置为使用 UTF-8?如果不是,它可能会使用 8859-1 或 8859-15 或类似的东西,并将根据该代码集解释字节。
  • 你的终端上locale的输出是什么?对此进行验证并告诉我们。
  • 只能显示图形字符。根据定义。

标签: c linux unicode


【解决方案1】:

即使您的终端配置为使用 UTF-8,您也不会看到太多内容,因为您正在“显示”的字符是:

0xC2 0x82 = U+0082
0xC2 0x81 = U+0081
0xC2 0x80 = U+0080

这些是 C1 集中的控制字符。我有一个数据文件,其中记录:

# C1 Controls (0x80 - 0x9F) are from ISO/IEC 6429:1992
# It does not define names for 80, 81, or 99.

80 U+0080
81 U+0081
82 U+0082 BPH BREAK PERMITTED HERE

所以您看不到任何东西,因为您没有显示任何图形字符。例如,如果您将 0x82 更改为 0xA2(以及 0x81 更改为 0xA1,0x80 更改为 0xA0),那么您将更有可能获得一些可见的输出:

0xC2 0xA2 = U+00A2
0xC2 0xA1 = U+00A1
0xC2 0xA0 = U+00A0

A0 U+00A0 NO-BREAK SPACE
A1 U+00A1 INVERTED EXCLAMATION MARK
A2 U+00A2 CENT SIGN

$ ./x
¢¡ 
$

如果你真的很好,你可以看到倒惊叹号后面的不间断空格…

【讨论】:

  • 它们代表控制字符;它们不代表任何可见的东西,就像换行符代表任何可见的东西一样。 (虽然您可以看到显示换行符的副作用,因为光标将位置更改为换行符的开头,但您看不到字符本身。)并非所有有效字符都是可见的。例如,有一个零宽度的不间断空间;你不能在终端上发现它!
  • 除了常见的空白字符 CR、LF 或制表符之外,控制字符没有任何由 Unicode 标准指定的语义。
  • 基本控制字符是 U+0000..U+001F、U+007F(这些是 ASCII 和 8859-1 控制字符),加上 U+0080..U+009F(C1控制)。如果您想要更精确,您可能需要查找字符的一般类别(参见Unicode 标准的第 4 章);控制字符具有一般类别gc=Cc(其他,控制)。
【解决方案2】:

0xc282c281c280 是一个整数。你想用一个序列初始化数组:char s[] = { 0xc2, 0x82, 0xc2, 0x81, 0xc2, 0x80, 0x00 };

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多