You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20中如何用char8_t存储表情符号并输出?

char8_t/char16_t/char32_t与表情符号的常见问题解析

一、为什么std::cout输出char32_t会报错?

你遇到的错误是因为std::cout是基于char(对应UTF-8)的输出流,C++标准并没有为它提供直接输出char32_t类型的重载,反而把对应的operator<<标记为删除状态,所以直接写std::cout << c(c是char32_t类型)会触发「使用已删除函数」的编译错误。

解决方法

如果想输出char32_t对应的字符,需要先把UTF-32编码的char32_t转换为UTF-8字符串再输出,比如用C++标准库的字符转换工具:

#include <iostream>
#include <string>
#include <codecvt>
#include <locale>

int main() {
    char32_t c = U'😋';
    // 将UTF-32转为UTF-8字符串
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
    std::string utf8_str = conv.to_bytes(c);
    std::cout << utf8_str << std::endl;
    return 0;
}

注意:C17中std::codecvt被标记为弃用,C20已移除。如果用C++20及以上版本,可以手动实现UTF-32到UTF-8的转换,也可以通过输出码点数值来调试:std::cout << static_cast<uint32_t>(c)。

二、为什么表情符号不能存入char8_t或char16_t的字符字面量?

核心原因是表情符号😋的Unicode码点是U+1F60B,属于「补充平面」(码点范围U+10000~U+10FFFF),超出了单个char16_t或char8_t的存储能力:

  • char16_t的限制:它对应UTF-16编码,单个char16_t只能存储基本多语言平面(U+0000~U+FFFF)的码点。补充平面的码点需要用两个char16_t组成的代理对表示,所以u'😋'这种单个字符字面量会报错——编译器无法把需要两个单元的编码塞进一个char16_t里。正确的做法是用字符串字面量u"😋",它的类型是const char16_t[],包含完整的代理对。

  • char8_t的限制:它对应UTF-8编码的单个字节。而😋的UTF-8编码是4个字节(0xF0 0x9F 0x98 0x8B),单个char8_t只能存其中一个字节,无法容纳整个表情符号。u8'😋'这种字符字面量要求是单个UTF-8字节单元,自然会编译失败。正确的写法是用字符串字面量u8"😋",类型是const char8_t[],包含完整的4个字节编码。

正确示例代码

// 正确存储表情符号的方式
const char16_t* c1 = u"😋";
const char8_t* c2 = u8"😋";
auto c3 = u"😋";   // 类型为const char16_t[]
auto c4 = u8"😋";  // 类型为const char8_t[]

内容的提问来源于stack exchange,提问作者Sheldon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 06:27:42