写入终端输出的UTF-8符号

时间:2014-10-16 17:12:09

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

我一直在努力理解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解释为单个符号ي,而不是两个符号� �

2 个答案:

答案 0 :(得分:4)

您正在处理两种不同类型,unsigned char[]unsigned char。 如果您要sizeof t,{> 1}},您会发现它已被占用 三个字节,strlen( t )将返回2.另一个 手,m0m1是单个字符。

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

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

答案 1 :(得分:0)

终端正在确定如何显示您正在为其提供的字节。您在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。)