std::string与Unicode的奇怪行为

6

我有以下这段代码:

#include <iostream>

std::string eps("ε");

int main()
{
    std::cout << eps << '\n';
    return 0;
}

一些代码在Ubuntu上使用g++和clang编译,甚至可以正确地打印出字符“ε”。我有几乎相同的代码片段,它可以使用cin愉快地读取“ε”并将其存储到std :: string中。顺便说一句,eps.size()为2。
我的问题是 - 这是如何工作的?我们如何将unicode字符插入std :: string中?我猜操作系统处理了所有与unicode相关的工作,但我不确定。
编辑
就输出而言,我明白了,终端负责显示正确的字符(在这种情况下是ε)。
但是对于输入:cin读取符号到“ ”或任何其他空格字符(我按字节理解)。因此,如果我取Ƞ,其中第二个字节为32 ' ',它只会读取第一个字节,然后停止。但它确实读取了Ƞ。怎么做到的呢?

3
也许你正在使用的编辑器会将文件保存为UTF-8编码。 - Captain Obvlious
2
std::cout只是将流发送到终端。如果您的终端处理UTF-8,则应该可以正常工作。 - MrEricSir
2
@SHR,“这个字符串不是UNICODE,而是UTF-8”是什么意思?请停止散布无稽之谈。猜猜看,我现在正在输入“UNICODE”。其他人上面给出的解释是正确的。他的编辑器将文件保存为utf-8,他的终端知道如何处理utf-8,所以一切正常。这与wstring无关,顺便说一句,它也不知道如何处理Unicode的所有复杂性。 - Praetorian
2
当字符被编码为UTF-8时,它们不仅仅是存储为它们的Unicode代码点。例如,Ƞ不会被存储为十六进制字节02 20。相反,它们被编码为一种特殊的UTF-8格式,对于Ƞ来说是C8 A0。 - Lithis
1
UTF-8编码被精心设计为向后兼容7位ASCII,并且适用于将C风格字符串视为带有尾随空字节的单字节字符流的应用程序。除了空字符以外,没有任何字符在其编码中具有空字节。此外,除非是ASCII字符,否则没有UTF-8字符会在其编码中包含7位ASCII字符。所有非ASCII Unicode字符仅使用0x80及以上的字节进行编码。 - Lithis
显示剩余6条评论
1个回答

5

最有可能的原因是所有内容都被编码为UTF-8,这也是我的系统上使用的编码方式:

$ xxd test.cpp
...
0000020: 2065 7073 2822 ceb5 2229 3b0a 0a69 6e74   eps("..");..int
                        ^^^^ ε in UTF-8                 ^^ TWO bytes!
...
$ g++ -o test.out test.cpp
$ ./test.out 
ε
$ ./test.out | xxd
0000000: ceb5 0a
         ^^^^              

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接