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

C#调用C预处理器时UTF-8输入文件字符损坏如何修复?

修复C#调用MSVC cl.exe时UTF-8输出乱码问题

问题背景

已经成功将代码页1252的旧C文件转成UTF-8:

var file = @"..."           // input file
var tmp  = @"...\tmp.c"     // output file
var lines = File.ReadAllLines(file, Encoding.GetEncoding(1252));
File.WriteAllLines(tmp, lines, Encoding.UTF8);

通过Visual Studio命令行执行cl /utf-8 /C /EP tmp.c > tmp.c.i2能生成有效的UTF-8文件,但用C#的Process调用时,英镑符号£(原十六进制c2 a3)变成┬ú(e2 94 ac c3 ba),项目符号•(原e2 80 a2 09)变成ÔÇó(c3 94 c3 87 c3 b3),字符损坏。

问题原因

Windows控制台默认使用代码页437作为输出编码,当通过C#的Process重定向标准输出时,StandardOutput默认会采用当前系统的控制台编码(而非UTF-8)去读取cl.exe的输出,而cl.exe已经通过/utf-8参数输出UTF-8内容,编码不匹配导致乱码。

修复方法

直接在Process的StartInfo中指定StandardOutputEncoding为UTF-8,让读取编码和cl.exe的输出编码一致:

修改后的完整代码片段:

// call preprocessor
var proc = new Process
{
    StartInfo =
    {
        FileName = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x86\cl.exe",
        WorkingDirectory = work,
        Arguments = "/utf-8 /C /EP tmp.c",
        CreateNoWindow = true,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = false,
        // 关键设置:指定读取标准输出的编码为UTF-8
        StandardOutputEncoding = Encoding.UTF8
    }
};
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
File.WriteAllText(Path.Combine(formatted, "tmp.c.i"), output, Encoding.UTF8);

备选方案(若上述方法无效)

如果还是存在编码问题,可以直接读取字节流再转换为UTF-8字符串,跳过默认的编码自动转换:

proc.Start();
string output;
using (var stream = proc.StandardOutput.BaseStream)
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
    output = reader.ReadToEnd();
}
proc.WaitForExit();
File.WriteAllText(Path.Combine(formatted, "tmp.c.i"), output, Encoding.UTF8);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:50:21