C ++中的奇怪行为

时间:2014-07-16 12:36:10

标签: c++ utf-16

此程序代替打印所有三个字符,只打印一个。为什么它会这样?

#include<iostream>
#include<string>

using namespace std;

int main() 
{
    string a("   ");
    a[0] = (char)65519; //Supposed to be UTF 16 characters
    a[1] = (char)65471;
    a[2] = (char)65469;

    //prints �
    cout << a << std::endl;

    //prints �
    for(int i = 0; i < a.size(); ++i) 
    {
        std::cout << a[i];
    }

    cout << "\n";
    return 0;
}

我能理解对正在打印的 字符的理解,因为我的字符集没有有效的字形/表示,但为什么不打印3个这样的字符而只打印一个?为什么即使我使用for循环也会发生?

编辑:从下面的评论中,我并不关心信息的丢失。我知道我将一个整数(32位)类型转换为char(8位)并且我丢失了信息。我关心的是,为什么不打印所有三个字符而只打印一个?

2 个答案:

答案 0 :(得分:7)

丢弃每个16位值的一半后,剩余的8位值为:

0xef 0xbf 0xbd

由于这些不是ASCII值(范围为0x000x7f),因此输出取决于终端如何解释非ASCII值。一个常见的编码是UTF-8,这三个值碰巧形成了Unicode replacement character的有效UTF-8编码,显示为�。

答案 1 :(得分:2)

a[0] = (char)65519;

哦,拜托,永远不要写这样的东西。不要忘记char包含一个字节,因此char的最大值是127.您还可以写入(char)255(对于有符号字符为-1或对于无符号字符为255)但不超过255.

对于Unicode,请编写以下内容

wstring a(L"   ");
a[0] = (wchar_t)65519; //Supposed to be UTF 16 characters
a[1] = (wchar_t)65471;
a[2] = (wchar_t)65469;