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

C++导出CSV文件时中韩文乱码 如何无需额外操作正常查看?

CSV导出中韩文乱码修复方案

问题背景

已实现英文文本CSV文件导出及本地化功能,拉丁字母类语言(如德语)的内容均可正常显示,但程序无法正常导出中韩文到CSV,会显示乱码,效果如下:
非英文文本显示效果
正常英文版本显示效果如下:
预期输出效果
尝试按照UTF-8编码方案处理导出的CSV文件后,显示效果如下:
处理后显示效果
目前可正常导出和导入含中文的CSV文件,无运行报错,需求是导出的CSV无需任何额外操作即可直接正常显示中韩文内容。

现有代码

导出逻辑

ofstream file(filename);
// file.imbue(locale(file.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>()));
file << outputListWaveform << "\n";

//this is the part get the header of each column
for (int x = 0; x < data.size(); ++x)
{
    file << get<0>(data.at(x));
    if (x != data.size() - 1)
        file << ",";
}
file << "\n";

for (int i = 0; i < get<1>(data.at(0)).size(); ++i)
{
    for (int j = 0; j < data.size(); ++j)
    {
        auto header = get<0>(data.at(j));
        auto dVal = get<1>(data.at(j));
        auto bVal = get<2>(data.at(j));

        file << ((header == FileOpConstants::BOST || header == FileOpConstants::EOST) ? bVal.at(i) : dVal.at(i));
        if (j != data.size() - 1)
            file << ",";
    }
    file << "\n";
}

file.close();

导入逻辑

StepTable data;
ifstream file(filename);

if (!file.is_open())
{
    string errMsg = "Could not open file: " + filename;
    throw runtime_error(errMsg);
}

string line, colname;
if (file.good())
{
    getline(file, line); // metadata (e.g. "Output List Waveform" as generated using Cyclops)
    getline(file, line); // column header
    stringstream ss(line);
    while (getline(ss, colname, ','))
    {
        data.push_back({colname, vector<double>{}, vector<bool>{}});
    }
}

// Get Column Values (row by row)
while (getline(file, line))
{
    int i = 0;
    auto val = Utility::split(line, ',');
    for (const auto& v : val)
    {
        auto header = get<0>(data.at(i));
        if (header == FileOpConstants::BOST || header == FileOpConstants::EOST)
        {
            get<2>(data.at(i)).push_back(stoi(v));
        }
        else if(header == VoltageHeader || header == CurrentHeader || header == PowerHeader || header == ResistanceHeader || header == TimeHeader )
        {
            get<1>(data.at(i)).push_back(stod(v));
        }
        else{
            return {};
        }
        i++;
    }
}

file.close();
return data;

修复方案

乱码的核心原因是Windows平台下Excel默认采用ANSI编码读取CSV文件,如果你输出的是UTF-8编码内容不带BOM头,就会出现识别错误。推荐采用以下两种方案修复:

方案1:UTF-8带BOM(兼容性最优)

该方案修改量最小,跨平台适配性好,修改导出逻辑即可:

  1. 打开文件后优先写入3字节的UTF-8 BOM头 \xEF\xBB\xBF
  2. 确保所有写入的字符串本身为UTF-8编码(MSVC环境可添加编译选项 /utf-8 保证源码字符串编码正确)
    修改后的导出代码示例:
// 以二进制模式打开避免换行符被转义
ofstream file(filename, ios::binary);
// 写入UTF-8 BOM头
file << "\xEF\xBB\xBF";
// 后续原有写入逻辑完全不变
file << outputListWaveform << "\n";
// ... 剩余原有代码保持不变

导入逻辑无需修改,若需兼容无BOM的UTF-8文件,可在读取首行时判断前3字节是否为BOM,若是则跳过即可。

方案2:UTF-16 LE带BOM(Windows原生适配)

该方案在Windows平台下完全不会出现乱码,适合仅面向Windows用户的场景:

  1. 改用宽字符流 wofstream 写入文件
  2. 先写入2字节的UTF-16 LE BOM头 \xFF\xFE
  3. 启用你之前注释的imbue编码转换配置
  4. 所有写入内容转换为宽字符串格式
    修改后的导出代码示例:
wofstream file(filename, ios::binary);
// 写入UTF-16 LE BOM
file << L"\xFF\xFE";
file.imbue(locale(file.getloc(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>()));
// 后续所有写入内容需替换为wstring类型,例如:
file << w_outputListWaveform << L"\n";
// ... 其余写入逻辑对应调整为宽字符输出即可

导入逻辑需要对应改为宽字符流读取,适配宽字符串处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:51:02