我正在尝试使用 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();
该文件包含多行,其中第一行仅包含 ASCII 字符,第二行是日语脚本。因此,当这段代码运行时,line1
应包含 ASCII 行,line2
日语脚本,以及good
应该是真的。
在VS2010中编译,结果符合预期。但是在VS2013中编译时,line1
包含 ASCII 行,但是line2
是空的,并且good
是假的。
我调试到 CRT(因为 Visual Studio 提供了源代码),发现一个名为_Mbrtowc
(在文件xmbtowc.c中)在两个版本之间进行了修改,并且它们用于检测双字节字符的前导字节的方式发生了变化,VS 2013中的检测不到前导字节,因此无法解码字节流。
进一步的调试揭示了一个点,其中_Cvtvec
对象的_Isleadbyte
数组被初始化(在函数中_Getcvt()
,在文件 xwctomb.c 中),并且初始化会产生错误的结果。它似乎总是使用代码页 1252,这是我系统上的默认代码页,而不是为正在使用的流设置的 932。然而,我无法确定这是否是设计使然,并且我错过了一些获得良好结果所需的步骤,或者这确实是 VS2013 的 CRT 中的一个错误。
不幸的是我没有安装VS2012,所以我无法在该版本上进行测试。
欢迎对此主题有任何见解!
我找到了一个解决方法:如果为了创建区域设置,我显式更改全局 MBC 代码页,则区域设置会正确初始化,并且会按预期读取和解码行。
const int oldMbcp = _getmbcp();
_setmbcp(932);
const std::locale locale("Japanese_Japan.932");
_setmbcp(oldMbcp);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)