如何在 char8_t 中存储表情符号并在 C++20 中打印出来?

问题描述 投票:0回答:3

我刚刚听说

char8_t
char16_t
char32_t
的存在,我正在测试它。当我尝试编译下面的代码时,
g++
抛出以下错误:

error: use of deleted function ‘std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, char32_t) [with _Traits = char_traits<char>]’
    6 |         std::cout << U'😋' << std::endl;
      |                      ^~~~~
#include <iostream>

int main() {
  char32_t c = U'😋';

  std::cout << c << std::endl;

  return 0;
}

另外,为什么我不能把表情符号变成

char8_t
char16_t
?例如,以下代码行不起作用:

char16_t c1 = u'😋';
char8_t c2 = u8'😋';
auto c3 = u'😋';
auto c4 = u8'😋';

根据我的理解,表情符号是 UTF-8 字符,因此应该适合

char8_t
.

c++ utf-8 c++20 emoji utf
3个回答
0
投票

表情符号是 UTF-8 字符

没有“UTF-8字符”这样的东西。

有 Unicode 代码点。这些可以用 UTF-8 编码表示,这样每个代码点都映射到一个或多个 UTF-8 代码单元的序列:

char8_t
s。但这意味着大多数代码点映射到多个
char8_t
s:AKA,一个字符串。表情符号不在映射到单个 UTF-8 代码单元的 127 个代码点中。

表情符号尤其可以由 多个 代码点构建,因此即使使用 UTF-32,您也不能保证任何表情符号都可以存储在单个

char32_t
代码点中。

最好始终将这些东西视为字符串,而不是字符。忘记“字符”甚至存在。


0
投票

当我尝试编译下面的代码时,g++ 抛出以下错误:

narrow 和 wide 标准流所期望的编码是依赖于实现的,也可能取决于你最终打印到的终端。如果要分别打印为

char
wchar_t
,则需要将字符转换为
std::cout
std::wcout
类型的正确编码。

另外,为什么我不能把emoji 放到char8_t 或char16_t 中?例如,以下代码行不起作用:

表情符号是 unicode 代码点 U+1F60B,在 UTF-8 和 UTF-16 编码中都需要多个代码单元。但是你正试图形成一个 character literal,它只包含 one 代码单元。

据我了解,表情符号是 UTF-8 字符 [...]

这没有意义。 UTF-8 是 unicode 代码点的编码。说一个字符“是 UTF-8”是没有意义的。这表明您可能对 Unicode 和字符/字符串编码的一般工作方式存在根本性的误解。我建议您阅读有关该主题的一些介绍。


0
投票

这个有效

#include <iostream>

int main() {
  const char* c = "😋";

  std::cout << c << std::endl;

  return 0;
}

解释。

  1. 😋 是一个多字节序列,不适合单个
    char
    。因此应该使用
    const char*
  2. 默认的源文件编码是UTF-8,因此Unicode字符只能在UTF-8编码中使用。对于
    char32_t
    它应该写成
    U'\x1F60B'
    .
  3. operator<<(std::basic_ostream)
    删除
    char8_t
    ,
    char16_t
    char32_t
    .
© www.soinside.com 2019 - 2024. All rights reserved.