MSVC上的双字节编码(std :: codecvt):引导字节无法识别

我想在Microsoft标准库实现(MSVC11)中使用std::codecvt<wchar_t, char, std::mbstate_t>::in()将双字节代码页中编码的string转换为UTF-16string。 例如,考虑以下程序:

 #include <iostream> #include <locale> int main() { // KATAKANA LETTER A (U+30A2) in Shift-JIS (Codepage 932) // http://msdn.microsoft.com/en-us/goglobal/cc305152 char const cs[] = "\x83\x41"; std::locale loc = std::locale("Japanese"); // Output: "Japanese_Japan.932" (as expected) std::cout << loc.name() << '\n'; typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_t; cvt_t const& codecvt = std::use_facet<cvt_t>(loc); wchar_t out = 0; std::mbstate_t mbst = std::mbstate_t(); char const* mid; wchar_t* outmid; // Output: "2" (error) (expected: "0" (ok)) std::cout << codecvt.in( mbst, cs, cs + 2, mid, &out, &out + 1, outmid) << '\n'; // Output: "0" (expected: "30a2") std::cout << std::hex << out << '\n'; } 

在debugging的时候,我发现in()调用内部_Mbrtowc()函数(crt \ src \ xmbtowc.c),传递std::locale的内部(C?)部分,用{_Page=932 _Mbcurmax=2 _Isclocale=0 ...} ,其中…代表(这似乎是问题) _Isleadbyte成员,初始化为32个零(unsigned chartypes)的数组。 因此,当函数处理'\x32'前导字节时,它会检查这个数组,并自然会得出(错误的)结论,即这不是一个前导字节。 所以它很高兴地调用MultiByteToWideChar() Win-API函数,当然这个函数不能转换halfed字符。 所以, _Mbrtowc()返回错误代码-1,它或多或less地取消了调用堆栈中的所有内容,并最终返回2( std::codecvt_base::result::error )。

这是MS标准库中的错误(似乎是这样)? (如何)我可以以便携的方式解决这个问题(即用最less量的#ifdef )?

我在内部向微软报告。 现在已经填补了它作为一个新的错误(DevDiv#737880)。 但我建议填写一个连接项目: http : //connect.microsoft.com/VisualStudio

我复制粘贴在VC2010 / Windows 7 64位的代码。

它按照你的预期工作。 这是输出:

 Japanese_Japan.932 0 30a2 

这可能是一个VC2012引入的错误…