【问题标题】:UTF-8 symbol written to the terminal output写入终端输出的 UTF-8 符号
【发布时间】:2014-12-12 05:32:34
【问题描述】:

我一直在尝试理解C++中operator<<的工作原理std::cout。我发现它可以打印 UTF-8 符号,例如: 简单的程序是:

#include <iostream>

unsigned char t[] = "ي";
unsigned char m0 = t[0];
unsigned char m1 = t[1];

int main()
{
    std::cout << t << std::endl;           // Prints ي
    std::cout << (int)t[0] << std::endl;   // Prints 217
    std::cout << (int)t[1] << std::endl;   // Prints 138
    std::cout << m0 << std::endl;          // Prints �
    std::cout << m1 << std::endl;          // Prints �
}

DEMO

产生输出的终端如何确定它必须将t解释为单个符号ي,而不是两个符号� �

【问题讨论】:

  • 你需要定义这段代码执行的环境

标签: c++ utf-8 character-encoding char


【解决方案1】:

终端正在确定如何显示您输入的字节。您在 2 字节 UTF-8 编码的 Unicode 字符的两个字节之间为其提供换行符 (std::endl)。而不是这个:

std::cout << m0 << std::endl;       // Prints �
std::cout << m1 << std::endl;       // Prints �

试试这个:

std::cout << m0 << m1 << std::endl; // Prints ي

为什么m0m1 在您的原始代码中打印为
因为您的代码正在发送字节 [217, 110, 138, 110],它不能解释为 UTF-8。 (假设std::endl对应\n字符,值为110。)

【讨论】:

    【解决方案2】:

    您正在处理两种不同的类型,unsigned char[]unsigned char。 如果你在t 上做sizeof,你会发现它被占用了 三个字节,strlen( t ) 将返回 2。另一方面 手,m0m1 是单个字符。

    当你输出一个unsigned char[]时,它会被转换成一个 unsigned char*,并且流输出所有字节,直到 它遇到'\0'(这是t 中的第三个字节)。什么时候 你输出一个unsigned char,流输出就是那个 字节。所以在你的第一行,输出设备接收 2 个字节,然后是行尾。在最后两个中,它收到 1 个字节,然后是行尾。然后那个字节 行尾,不是合法的 UTF-8 字符,所以显示 设备显示一些内容以表明存在错误, 或者它不明白。

    在使用 UTF-8(或任何其他多字节编码)时,您 无法从字符串中提取单个字节并期望它们 有什么实际意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 2015-10-26
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      相关资源
      最近更新 更多