【发布时间】:2014-10-28 21:04:36
【问题描述】:
我正在尝试使用 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 字符,第二行是日文脚本。因此,当这个 sn-p 运行时,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,所以我无法在那个版本上进行测试。
欢迎对此主题的任何见解!
【问题讨论】:
-
发布到 connect.microsoft.com
-
我会在打开文件之前开始尝试
imbue()新的语言环境:我认为流可能会在打开期间读取字符,一旦读取字符,它就不会更改使用的 @987654334 @分面。 -
@DietmarKühl 我刚刚检查过,但结果是一样的:在 VS2010 中有效,但在 VS2013 中以同样的方式失败。
-
@HansPassant 报告发送到 msft 连接:connect.microsoft.com/VisualStudio/feedback/details/1014054/…
标签: c++ stl visual-studio-2013 character-encoding locale