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

C++20及更高版本用cout打印Unicode字符串编译报错的原因及解决

C++20中cout打印Unicode字符串编译错误的原因及解决方法

问题场景

使用Visual C++ 2022 17.4.4版本,将C标准设置为C20及以上时,运行以下代码出现编译错误:

#include <iostream>

using namespace std;

int main()
{
  cout << u8"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n";
  return 0;
}

编译错误信息

1>C:\projects\cpp\test\test.cpp(7,8): error C2280: 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char8_t *)': attempting to reference a deleted function
1>C:\projects\cpp\test\test.cpp(7,8): error C2088: '<<': illegal for class

使用u(UTF-16)和U(UTF-32)字符串字面量时也会触发相同错误,但将标准切换为C17或C14时可正常编译。

错误原因

C++20标准正式引入char8_t作为UTF-8字符的专属类型,同时对标准库做了以下关键调整:

  1. u8字符串字面量的类型从C++17及更早的const char*改为const char8_t*;
  2. std::ostream(即cout,基于char类型)的operator<<重载中,针对char8_t*、char16_t*、char32_t*的版本被标记为删除函数。

这一设计的核心目的是避免隐式编码转换导致的乱码或未定义行为——cout默认处理的是窄字符(通常对应系统本地编码),直接输出UTF-8/16/32字符串可能因编码不匹配出现不可预期的错误。

正确的打印方式

1. 输出UTF-8字符串(u8字面量)

可以通过两种方式输出:

  • 直接调用cout.write输出字节序列,跳过类型检查:
#include <iostream>
#include <string_view>

using namespace std;

int main()
{
    const char8_t* str = u8"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n";
    cout.write(reinterpret_cast<const char*>(str), string_view(str).size());
    return 0;
}
  • 强制转换为const char*(需确保输出环境支持UTF-8编码,比如Windows控制台需先设置编码):
#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    SetConsoleOutputCP(CP_UTF8); // Windows平台设置控制台为UTF-8编码
    cout << reinterpret_cast<const char*>(u8"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n");
    return 0;
}

2. 输出UTF-16/UTF-32字符串(u/U字面量)

  • 使用对应编码的宽字符输出流std::wcout,并设置控制台编码(Windows平台):
#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    SetConsoleOutputCP(CP_UTF16); // Windows平台设置控制台为UTF-16编码
    wcout << u"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n";
    return 0;
}
  • 转换为UTF-8后通过cout输出,可借助C++20的std::codecvt或第三方库(如ICU)完成编码转换。

3. 使用C++20的std::print(推荐)

C++20引入的std::print可以直接处理所有Unicode字符串字面量,无需手动转换,且自动适配输出环境:

#include <print>

int main()
{
    std::print(u8"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n");
    std::print(u"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n");
    std::print(U"The official vowels in Danish are: a, e, i, o, u, \u00E6, \u00F8, \u00E5 and y.\n");
    return 0;
}

注意:Visual C++ 2022 17.4及以上版本已支持std::print,需确保启用C++20及以上标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 03:25:26