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
相关产品推荐
相关产品推荐

