【问题标题】:Japanese characters are not written correctly when saving to a file保存到文件时,日文字符写入不正确
【发布时间】:2015-02-08 07:36:54
【问题描述】:

我有一个基于 .NET 的 Excel 插件,它使用 C++/CLI 库来读取/写入专有文件。 C++/CLI 库链接到一些提供类来读取和写入这些文件的核心 C++ 库。核心类使用 std::string 和 std::i/ofstream 来读取/写入专有文件中的数据。

所以当保存数据时,它来自:
Excel >> .NET AddIn (string) >> C++/CLI Lib (System::String) >> C++ Core Lib (std::string)

一切都适用于简单文本 (ASCII) 文件。现在我有一个文本文件(ANSI 编码),其中包含一些日文字符,保存在日文机器上。我认为它默认使用 SHIFT-JIS 编码。该文件加载良好(我在 Excel 中看到的字符与在记事本中看到的相同),但如果我将其原封不动地保存回来,则字符将变为 ??。我认为这是因为 std::stringstd::ofstream 类将其错误地写为简单的 ASCII 流。

我在读取文件时使用以下语法将它们转换为 .NET 字符串:

%String(mystring.c_str());

在写入时将它们从 .NET 字符串转换为 std::strings 的以下内容:

msclr::interop::marshal_as<std::string>(mydotnetstring)

在我看来,问题在于编码,但我不清楚到底发生了什么。我想了解为什么文件读取正确但写入不正确?

我已将我的应用程序修改为读/写 UTF-8,这解决了问题,但我仍然想知道根本问题。

【问题讨论】:

    标签: c++ .net string unicode character-encoding


    【解决方案1】:

    好的,我想我已经找到了根本问题。问题是 msclr::interop::marshal_as 方法在内部使用 CP_THREAD_ACP 选项调用 WideCharToMultiByte API,这意味着使用活动线程的代码页。此 .NET 插件在 Excel 进程中运行,当前线程的 CodePage(日语系统上为 952)与默认 CodePage (1252) 不同。我通过检查示例应用程序中 ma​​rshal_as 调用的返回值与日本机器上的 .NET 插件来验证这一点。示例应用程序将两个日文字符串转换为 4 个字节,而插件只是将其转换为 2 个未知的“?”字节。

    SOLUTION
    ma​​rshal_as 不提供更改此选项的选项,因此解决方案是直接使用 WideCharToMultiByte 编组 .NET 字符串strong> 带有 CP_ACP 选项的 API。它对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-23
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 1970-01-01
      相关资源
      最近更新 更多