problema de conversão de sequência de caracteres de byte duplo no Visual Studio 2015
Estou tentando converter a sequência de caracteres de byte duplo (DBCS) no CP936 parawchar_t
usando localidade C ++. Este é o código:
#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;
}
Agora, a conversão sempre termina com erro eerrno
definido como 42, que éEILSEQ
. Eu depurei o código e acho que posso ver o que está errado, mas não entendo o porquê.
O que dá errado é que o código que leva à chamada paraMultiByteToWideChar()
, tem um condicional como este:
if ( ploc->_Isleadbyte[ch >> 3] & (1 << (ch & 7)) )
Essa ramificação nunca é usada, apesar do fato de a cadeia de origem AFAIK conter byte de chumbo e byte à direita. Eu verifiquei o_Isleadbyte
matriz no depurador e são todos os zeros. Portanto, este ramo que define o comprimento da entrada como2
nunca é tomado e, em vez disso, aquele em que comprimento está definido como1
é tomada e, assim, oMultiByteToWideChar()
falha porque o byte principal deve ser acompanhado pelo byte final.
Eu até chequei issoC_936.NLS
está presente emC:\Windows\System32\
, então esse não deve ser o problema.
Então, acho que a pergunta é: esse problema acabou, com o código de teste, com a instalação do sistema operacional Windows, faltando componentes? Ou esse problema está no código do Visual Studio 2015?
ATUALIZAR
Então, aliás, me deparei com esta pergunta:A decodificação Shift-JIS falha ao usar o wifstrem no Visual C ++ 2013
A resposta do próprio OP mostra uma solução alternativa:
const int oldMbcp = _getmbcp();
_setmbcp(932);
const std::locale locale("Japanese_Japan.932");
_setmbcp(oldMbcp);
A mesma solução alternativa parece funcionar para o CP936 que estou tentando usar.
ATUALIZAÇÃO 2
Eu arquivei umrelatório de erro com a Microsoft.