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

Windows下C语言fgets无法读取UTF-8输入的解决办法咨询

Windows下MinGW32中fgets读取UTF-8输入乱码的问题解决

问题描述

在Windows系统的VSCode环境中使用MinGW32编译器编写如下C代码:

#include <stdio.h>
#define SIZE 100

int main(void) {

   char myWord[SIZE];

   printf("Enter \"blå\": ");
   fgets(myWord, sizeof(myWord), stdin);
   printf("Entered string: %s", myWord);

   return 0;
}

运行后得到异常输出:

Enter "blå": blå
Entered string: bl近场内,为arts任意 axios Establishing�健报酬� Open试用shaled string: bl

已通过CHCP 65001设置控制台字符编码为UTF-8,解决了输出乱码问题,但fgets仍无法正常读取用户输入,需修改stdin编码以适配UTF-8。

解决方法

核心原因

CHCP 65001仅设置了控制台的输出代码页,但MinGW32默认使用系统ANSI locale,导致标准输入流(stdin)的编码与控制台的UTF-8编码不匹配,fgets读取UTF-8多字节字符时出现解析错误。

基于locale.h的解决方案

通过setlocale()函数指定UTF-8 locale,让C标准库的输入输出流适配UTF-8编码,具体修改如下:

#include <stdio.h>
#include <locale.h>
#define SIZE 100

int main(void) {
    // 设置全局locale为UTF-8,统一输入输出的编码处理
    setlocale(LC_ALL, ".UTF-8");

    char myWord[SIZE];

    printf("Enter \"blå\": ");
    fgets(myWord, sizeof(myWord), stdin);
    printf("Entered string: %s", myWord);

    return 0;
}

说明

  • setlocale(LC_ALL, ".UTF-8")会告诉C标准库使用UTF-8编码处理所有本地化相关操作,包括标准输入输出流的字符编码解析。
  • 该方法无需依赖Windows特定API,保持代码可移植性,同时与CHCP 65001的控制台设置匹配,确保输入输出编码一致。

备选方案(Windows API方式)

如果上述方法无效,可直接使用Windows API的宽字符读取函数ReadConsoleW,再将宽字符转换为UTF-8存储,示例代码如下:

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#define SIZE 100

int main(void) {
    wchar_t wideBuf[SIZE];
    char utf8Buf[SIZE];

    printf("Enter \"blå\": ");
    // 读取宽字符输入
    ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), wideBuf, SIZE-1, NULL, NULL);
    // 将宽字符转换为UTF-8
    WideCharToMultiByte(CP_UTF8, 0, wideBuf, -1, utf8Buf, SIZE, NULL, NULL);

    printf("Entered string: %s", utf8Buf);

    return 0;
}

该方法直接绕过C标准库的locale限制,通过系统API处理UTF-8编码,但代码仅适用于Windows平台。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:05:35