在Visual C++2013中使用wifstrem进行Shift JIS解码失败
Shift-JIS decoding fails using wifstrem in Visual C++ 2013
我正在尝试使用std::wifstream和std::getline读取以Shift-JIS(cp932)编码的文本文件。以下代码在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
应该为true。
在VS2010中编译时,结果与预期一致。但在VS2013中编译时,line1
包含ASCII行,但line2
为空,good
为false。
我在CRT中进行了调试(因为源代码是Visual Studio提供的),发现在两个版本之间修改了一个名为_Mbrtowc
的内部函数(在文件xmbtowc.c中),并且它们用于检测双字节字符的前导字节的方式发生了变化,而VS 2013中的函数无法检测前导字节,因此无法解码字节流。
进一步的调试揭示了一个点,即_Cvtvec
对象的_Isleadbyte
数组被初始化(在函数_Getcvt()
中,在文件xwctomph.c中),并且初始化会产生错误的结果。它似乎总是使用代码页1252,这是我系统上的默认代码页,而不是为正在使用的流设置的932。然而,我无法决定它是否是设计的,我错过了获得好结果所需的一些步骤,或者这确实是VS2013 CRT中的一个错误。
不幸的是,我没有安装VS2012,所以我无法在那个版本上进行测试。
欢迎对这个话题有任何见解!
我找到了一个解决方法:如果为了创建区域设置,我显式地更改全局MBC代码页,则区域设置将正确初始化,并且行将按预期读取和解码。
const int oldMbcp = _getmbcp();
_setmbcp(932);
const std::locale locale("Japanese_Japan.932");
_setmbcp(oldMbcp);
相关文章:
- 通过递归进行因子分解
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 使用libgit2、c++进行pull
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 如何使用模板函数的函数签名进行SFINAE
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 将模板化的类型与C++中的某些类/类型进行比较
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 从文本文件中读取时钟时间和事件时间并进行处理
- 对字符串进行位操作
- 是否可以使用winusb同时与多个相同的usb设备进行通信
- 是否可以对零模板参数进行模板专门化
- 对字符串进行排序时,在c++中处理sort()
- 热键/按钮,根据需要进行编译,但不运行(在F5和Ctrl+Shift+B之间)
- 当按下shift时,对编辑文本控件进行子类处理以接受小写字符
- 在Visual C++2013中使用wifstrem进行Shift JIS解码失败