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

Windows10下C语言程序写入特殊字符(ÅÄÖ)到文件的乱码问题求助

解决Windows下C语言scanf输入特殊字符写入文件乱码的问题

嘿,我碰到过类似的坑!Windows控制台编码和文件编码不匹配确实容易搞出乱码,咱们一步步来搞定它:

问题根源

你已经注意到了,fprintf直接写特殊字符完全正常,但scanf输入后就乱码——这核心原因是Windows控制台默认用的是OEM编码(比如瑞典语环境下可能是CP850),而你设置的程序locale是UTF-8,同时文件也是以UTF-8格式写入的。scanf读取的是控制台输出的OEM编码字节,直接丢进UTF-8文件里自然就变成乱码;而代码里的字符串字面量是编译器按UTF-8处理的,所以写入完全没问题。

两种实用解决方案

方案一:让控制台和程序统一用UTF-8

这个方法最简单,只需要两步:

  1. 切换控制台编码:打开cmd或PowerShell,先执行这条命令:
    chcp 65001
    
    这会把控制台编码切换为UTF-8。
  2. 补全并优化代码:用fgets代替scanf(避免截断空格),完整代码如下:
    #include <stdio.h>
    #include <locale.h>
    
    int main() {
        char s[30];
        // Windows下用".UTF-8"兼容性比"sv_SE.UTF-8"更好
        setlocale(LC_ALL, ".UTF-8");
        FILE *fp = fopen("test.txt", "w+");
        if (!fp) {
            perror("Failed to open file");
            return 1;
        }
    
        fprintf(fp, "Test: åäö ÅÄÖ\n"); // 正常工作
        printf("Write something: ");
        // 用fgets读取整行输入,包括空格
        fgets(s, sizeof(s), stdin);
        fprintf(fp, "%s", s);
    
        fclose(fp);
        return 0;
    }
    
    编译运行后输入ÖÄÅöäååå,打开test.txt就能看到正确内容了。

方案二:编码转换(无需修改控制台设置)

如果不想每次都切换控制台编码,可以用Windows API把读取到的OEM编码转换成UTF-8再写入:

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

int main() {
    char oem_buf[30];
    wchar_t wide_buf[30];
    char utf8_buf[60]; // UTF-8每个字符最多占3字节,预留足够空间
    FILE *fp = fopen("test.txt", "w+");

    if (!fp) {
        perror("Failed to open file");
        return 1;
    }

    fprintf(fp, "Test: åäö ÅÄÖ\n");
    printf("Write something: ");
    fgets(oem_buf, sizeof(oem_buf), stdin);

    // 第一步:把OEM编码字符串转成宽字符
    int len = MultiByteToWideChar(GetOEMCP(), 0, oem_buf, -1, wide_buf, sizeof(wide_buf)/sizeof(wchar_t));
    if (len == 0) {
        printf("Failed to convert OEM to wide char\n");
        return 1;
    }

    // 第二步:把宽字符转成UTF-8编码
    len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, sizeof(utf8_buf), NULL, NULL);
    if (len == 0) {
        printf("Failed to convert wide char to UTF-8\n");
        return 1;
    }

    fprintf(fp, "%s", utf8_buf);
    fclose(fp);
    return 0;
}

这个方案会自动处理编码转换,不管控制台用什么编码,都能把输入转成UTF-8写入文件。

小补充

  • 尽量用fgets代替scanf("%s"),后者会在遇到空格时停止读取,体验很差;
  • fprintf直接写正常是因为你的源文件是UTF-8编码保存的,编译器会把字符串字面量编译成UTF-8字节,和文件编码匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:05:13