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

Windows控制台打印Emoji问题:首次运行首个Emoji显示异常

Windows控制台首个Emoji显示异常问题分析

问题现象

  • 开发C语言Windows控制台应用,打印包含Emoji的Unicode字符时,首次运行且字符串首个字符为Emoji,该Emoji会显示为"??",后续字符显示正常;
  • 后续重复运行程序时,所有字符均显示正常;
  • 若字符串首个字符为普通Unicode字符(如中文、俄文等),则无异常;
  • 测试GCC、MSVC、Clang编译器均存在此问题。

复现代码

#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <io.h>
#include <fcntl.h>

int main(void)
{
   _setmode(_fileno(stdout), _O_U8TEXT);
   const wchar_t* string = L"😀🌸你好Приветשלוםمرحبا";
   wprintf(L"%ls\n", string);

   return EXIT_SUCCESS;
}

编译命令:gcc -std=c2x -Wall -pedantic -Werror -g -o stack stack.c

问题原因

这是Windows控制台的已知兼容性问题,与代码逻辑无关。核心原因如下:

  1. 当通过_setmode将标准输出切换到_O_U8TEXT模式时,Windows控制台内部的字符编码状态初始化存在延迟,无法正确处理首个输出的4字节UTF-8序列(Emoji属于Unicode辅助平面字符,对应4字节UTF-8编码);
  2. 首次运行后,控制台的编码状态已完成初始化,后续运行时可正常解析所有Unicode字符;
  3. 若首个字符是2字节UTF-8序列的普通Unicode字符,控制台初始化过程能及时完成,不会出现解析错误。

解决方法

可以通过以下两种方式规避该问题:

  • 方式一:提前触发控制台状态初始化
    在输出目标字符串前,先打印一个无显示影响的空宽字符,触发控制台完成编码状态初始化:
    // 在_setmode之后、wprintf之前添加
    wprintf(L"");
    
    也可以打印空格后回退光标,避免影响输出内容:
    wprintf(L" \b");
    
  • 方式二:使用Windows API设置编码
    改用SetConsoleOutputCP(CP_UTF8)替代_setmode设置控制台输出编码,配合宽字符输出可避免该问题(需包含<windows.h>头文件):
    #include <windows.h>
    // ...
    int main(void)
    {
        SetConsoleOutputCP(CP_UTF8);
        const wchar_t* string = L"😀🌸你好Приветשלוםمرحبا";
        wprintf(L"%ls\n", string);
        return EXIT_SUCCESS;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:45:12