在Visual C++ 2013中使用wifstrem进行Shift-JIS解码失败

Pet*_*r B 5 c++ locale stl character-encoding visual-studio-2013

我试图使用std :: wifstream和std :: getline读取在Shift-JIS(cp 932)中编码的文本文件.以下代码在VS2010中有效,但在VS2013中失败:

std::wifstream in;
in.open("data932.txt");

const std::locale locale(".932");

in.imbue(locale);

std::wstring line1, line2;
std::getline(in, line1);
std::getline(in, line2);
const bool good = in.good();
Run Code Online (Sandbox Code Playgroud)

该文件包含多行,其中第一行仅包含ASCII字符,第二行包含日语脚本.因此,当此代码段运行时,line1应包含ASCII行,line2日语脚本,并且good应该为true.

在VS2010中编译时,结果如预期.但是在VS2013中编译时,line1包含ASCII行,但是line2为空,并且good为false.

我调试了CRT,(因为Visual Studio提供了源代码),发现_Mbrtowc在两个版本之间修改了一个内部函数(在文件xmbtowc.c中),以及它们用来检测一个引导字节的方式双字节字符已更改,VS 2013中的字符未能检测到前导字节,因此无法解码字节流.

进一步的调试揭示了一个点,其中一个_Cvtvec对象的_Isleadbyte数组被初始化(在函数中_Getcvt(),在文件xwctomb.c中),并且该初始化产生了错误的结果.它似乎总是使用代码页1252,它是我系统上的默认代码页,而不是932,它是为正在使用的流设置的.但是,我无法确定它是否是设计的,我错过了一些必要的步骤来获得一个好的结果,或者这确实是VS2013的CRT中的一个错误.

不幸的是我没有安装VS2012,所以我无法测试该版本.

欢迎任何有关此主题的见解!

Pet*_*r B 2

我找到了一个解决方法:如果为了创建区域设置,我显式更改全局 MBC 代码页,则区域设置会正确初始化,并且会按预期读取和解码行。

const int oldMbcp = _getmbcp();
_setmbcp(932);
const std::locale locale("Japanese_Japan.932");
_setmbcp(oldMbcp);
Run Code Online (Sandbox Code Playgroud)