保存到文件时,日文字符写入不正确

时间:2014-12-10 07:27:09

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

我有一个基于.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编码。这个文件LOADS很好(我在Excel中看到的字符与我在记事本中看到的相同),但如果我将其保存为未修改,则字符将更改为 ?? 。我认为这是因为 std :: string std :: ofstream 类将它错误地写为简单的ASCII流。

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

%String(mystring.c_str());

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

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

问题在于编码问题,但我对目前究竟发生了什么并不清楚。我想了解为什么文件读取正确但没有正确写入?

我已修改我的应用程序以读取/写入UTF-8并解决了问题,但我仍然想知道潜在的问题。

1 个答案:

答案 0 :(得分:0)

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

<强>解
marshal_as 不提供更改此选项的选项,因此解决方案是通过直接使用带有CP_ACP选项的 WideCharToMultiByte API来封送.NET字符串。它对我有用。