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

如何最小化修改代码实现跨平台正确打印西里尔字符абв?

跨平台正确打印Unicode字符的C++最小化修改方案

嘿,这个跨平台输出Unicode字符的问题我太熟悉了!本质是Linux和Windows的控制台编码、标准流默认配置差异搞的鬼。先看看你的原代码和问题输出:

原代码

#include <iostream>
int main() {
    std::cout << "abc" << std::endl;
    std::wcout << L"abc" << std::endl;
    std::cout << "абв" << std::endl;
    std::wcout << L"абв" << std::endl;
    return 0;
}

原平台输出差异

Linux系统输出:
abc
abc
абв
012

Windows系统输出(缺少最后一行):
abc
abc
рст

最小化修改后的代码

只需要加平台相关的编码配置代码,核心逻辑完全不动:

#include <iostream>
#if defined(_WIN32)
#include <windows.h>
#endif

int main() {
    // 统一配置控制台和标准流的编码匹配
#if defined(_WIN32)
    // Windows下强制控制台输出用UTF-8,同时给宽字符流绑定正确locale
    SetConsoleOutputCP(CP_UTF8);
    std::wcout.imbue(std::locale(""));
#else
    // Linux下给宽字符流绑定系统默认UTF-8 locale即可
    std::wcout.imbue(std::locale(""));
#endif

    // 原逻辑完全保留
    std::cout << "abc" << std::endl;
    std::wcout << L"abc" << std::endl;
    std::cout << "абв" << std::endl;
    std::wcout << L"абв" << std::endl;
    return 0;
}

修改原因拆解

咱们逐个平台说为啥要这么改:

  • Linux侧:默认std::wcout用的是"C" locale,只会处理ASCII字符,遇到абв这种Unicode宽字符就会乱转成012。给wcout绑定系统默认的locale(一般是UTF-8),就能正确把宽字符转成控制台支持的UTF-8编码输出。而std::cout本来输出的就是UTF-8多字节字符串,Linux控制台默认支持,所以不需要额外改。
  • Windows侧:
    1. 控制台默认用的是GBK类的本地编码,std::cout输出的UTF-8字符串会被当成GBK解析,所以абв变成了рст。用SetConsoleOutputCP(CP_UTF8)把控制台输出编码设为UTF-8,就能让cout的输出正确显示。
    2. 默认的std::wcout同样因为locale问题,无法把宽字符转成控制台编码,直接输出失败导致最后一行消失。绑定空字符串的locale(会自动匹配系统当前的UTF-8配置),就能解决宽字符流的转换问题。

这样改完之后,两边的控制台都会正确输出四行内容:abc、abc、абв、абв,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:09:23