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

使用_setmode(_fileno(stdin), _O_U16TEXT)时wscanf无法正常工作问题

问题根因与修复方案

根因分析

  • 仅为标准输入stdin设置了_O_U16TEXT模式,未同步设置标准输出stdout的模式,导致模式不匹配:
    • _O_U16TEXT是Windows平台特有的IO模式,要求对应的流输入输出均为UTF-16编码的宽字符序列,运行时不会额外做多字节转码处理
    • 未设置stdout的模式时,wprintf输出的宽字符提示语会被默认的多字节转码逻辑处理,容易出现输出失败、缓冲区未刷新的问题,残留的无效数据会进入输入流,导致wscanf匹配数字格式失败,返回0,input变量不会被修改
  • Windows控制台默认代码页通常为936(简体中文)、1252(英文)或1251(西里尔文),未切换为65001(UTF-8)时,输入的字符编码和_O_U16TEXT要求的UTF-16编码不匹配,也会导致解析失败

修复方案

方案1:保持_O_U16TEXT模式配置

  1. 统一设置标准输入、输出流的模式,补充stdout的模式配置:
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main()
{
    int input = -1;
    // 同步设置stdin和stdout的模式
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stdout), _O_U16TEXT);

    wprintf (L"Enter a number: ");
    wscanf  (L"%d", &input);
    wprintf (L"%d", input);

    return 0;
}
  1. 运行程序前先在控制台执行命令chcp 65001,将控制台代码页切换为UTF-8,同时将控制台字体修改为支持西里尔字符的字体(如Consolas、Lucida Console,不要使用系统默认点阵字体),即可正常输入输出西里尔字符与数字。

方案2:使用区域设置替代IO模式修改

无需修改_setmode配置,只需在代码入口添加区域声明即可处理西里尔字符,兼容性更强:

#include <stdio.h>
#include <locale.h>

int main()
{
    int input = -1;
    // 设置区域为俄语UTF-8编码
    setlocale(LC_ALL, "ru_RU.UTF-8");

    wprintf (L"Enter a number: ");
    wscanf  (L"%d", &input);
    wprintf (L"%d", input);

    return 0;
}

使用该方案时同样需要将控制台代码页切换为65001,且使用支持西里尔字符的字体。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:06:02