【问题标题】:Shift-JIS decoding fails using wifstrem in Visual C++ 2013在 Visual C++ 2013 中使用 wifstrem 进行 Shift-JIS 解码失败
【发布时间】: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


【解决方案1】:

我找到了一种解决方法:如果为了创建语言环境,我明确更改了全局 MBC 代码页,则语言环境会正确初始化,并且会按预期读取和解码行。

const int oldMbcp = _getmbcp();
_setmbcp(932);
const std::locale locale("Japanese_Japan.932");
_setmbcp(oldMbcp);

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
相关资源
最近更新 更多