我一直在努力理解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 �
}
产生输出的终端如何确定它必须将t
解释为单个符号ي
,而不是两个符号� �
?
答案 0 :(得分:4)
您正在处理两种不同类型,unsigned char[]
和unsigned char
。
如果您要sizeof
t
,{> 1}},您会发现它已被占用
三个字节,strlen( t )
将返回2.另一个
手,m0
和m1
是单个字符。
输出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 ي
为什么m0
和m1
在原始代码中打印为�
?
因为您的代码正在发送字节[217, 110, 138, 110]
,这不能解释为UTF-8。 (假设std::endl
对应\n
字符,值为110。)