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

