Visual Studio 2015

时间:2015-10-21 08:10:40

标签: c++ visual-studio character-encoding visual-studio-2015 locale

我正在尝试使用C ++语言环境将CP936中的双字节字符序列(DBCS)转换为wchar_t。这是代码:

#include <iostream>
#include <locale>
#include <codecvt>

// 国 in CP936
char const src[] = "\xB9\xFA";

int main()
{
    std::locale loc(".936");
    typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
    codecvt_type const & cvt = std::use_facet<codecvt_type>(loc);

    std::mbstate_t state;
    std::memset(&state, 0, sizeof(state));

    char const * src_mid = src;
    wchar_t buf[10];
    wchar_t * buf_mid = buf;

    std::codecvt_base::result res = cvt.in(state,
        src, src + 2, src_mid,
        buf, buf + 10, buf_mid);
    int eno = errno;
    std::cout << "res: " << +res << "\n"
        << "errno: " << eno << "\n";

    return 0;
}

现在,转换始终以错误结束,errno设置为42,即EILSEQ。我调试了代码,我想我可以看到出了什么问题,但我不明白为什么。

出现问题的是最终导致调用MultiByteToWideChar()的代码有这样的条件:

if ( ploc->_Isleadbyte[ch >> 3] & (1 << (ch & 7)) )

尽管源字符串AFAIK包含正确的前导字节和尾随字节,但从未采用此分支。我在调试器中检查了_Isleadbyte数组,它全是零。所以这个将输入长度设置为2的分支从不被采用,而是采用长度设置为1的分支,因此MultiByteToWideChar()失败,因为前导字节必须伴随尾随字节。

我甚至检查C_936.NLS中是否存在C:\Windows\System32\,所以这不应该是问题。

所以,我想问题是:这个问题是否在我的最终,测试代码,Windows操作系统设置,缺少组件?或者是Visual Studio 2015代码中的这个问题吗?

更新

所以我偶然发现了这个问题:Shift-JIS decoding fails using wifstrem in Visual C++ 2013

OP自己的答案显示了一种解决方法:

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

同样的解决方法似乎适用于我尝试使用的CP936。

更新2

我向微软提交了bug report

0 个答案:

没有答案