2013-06-15 1 views
2

Microsoft 표준 라이브러리 구현 (MSVC11)에서 std::codecvt<wchar_t, char, std::mbstate_t>::in()을 사용하여 doublebyte 코드 페이지로 인코딩 된 문자열을 UTF-16 문자열로 변환하고 싶습니다. 예를 들어, 다음 프로그램을 고려 :MSVC (std :: codecvt)의 Doublebyte 인코딩 : 리드 바이트가 인식되지 않습니다.

#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'; 
} 

디버깅, 나는 in() 내부 통과, 내부 _Mbrtowc() 기능 (브라운관 \ 컴파일합니다 \의 xmbtowc.c)를 호출 끝나는하는 부분을 발견했을 때 (C를?) std::locale{_Page=932 _Mbcurmax=2 _Isclocale=0 ...}으로 초기화됩니다. 여기서 ...는 _Isleadbyte 멤버를 나타내는 것으로 32 개 0의 배열 (unsigned char 유형)로 초기화됩니다. 따라서 함수가 바이트를 처리 할 때이 배열을 검사하여 당연히 이 아니고 선두 바이트 인이라는 결론에 도달하게됩니다. 따라서 행복하게 MultiByteToWideChar() Win-API 함수를 호출합니다.이 함수는 물론 반쪽 문자를 변환하지 못합니다. 따라서 _Mbrtowc()은 오류 코드 -1을 반환합니다. 오류 코드 -1은 호출 스택 위로 모든 것을 취소하고 궁극적으로 2 (std::codecvt_base::result::error)가 반환됩니다.

MS 표준 라이브러리의 버그입니까? (휴대 전화 방식으로이 문제를 해결하려면 (#ifdef의 최소 금액)?

+0

I repro. 디버깅하기위한 매우 추악한 코드, connect.microsoft.com –

답변

1

내가 Microsoft에 내부적으로보고했다. 이제는 새로운 버그로 채웠습니다 (DevDiv # 737880). 하지만 연결 항목을 작성하는 법을 권합니다. http://connect.microsoft.com/VisualStudio

+0

감사합니다! 사실,이 버그의 영향을 직접받지는 못했지만 관련된 (제 3 자 라이브러리) 버그에 대한 최소한의 예제를 만들 때 발견했습니다. 하지만 시간이 걸릴 것이고 연결 버그를 제기 할 것이라고 생각합니다. – Oberon

+0

불행히도, 필자는 버그를 제기 할 수없는 것처럼 보입니다 : 필자는 반복적으로 필자가 필자가 요구하는 프로필 정보를 완성하도록 요청받습니다 : connect.microsoft.com "필수 프로필 정보 완성"- (다음) -> social.microsoft.com "내 프로필 편집"- (저장) -> profile.microsoft.com "등록"- (다음) -> (다시 시작). 물론 필자는 필요한 모든 필드 (*)를 채 웁니다. – Oberon

1

VC2010/Windows 7 64 비트에 코드를 붙여 넣습니다.

예상대로 작동합니다. 여기 출력은 다음과 같습니다

Japanese_Japan.932 
0 
30a2 

그것은 아마 VC2012 도입 버그의 ...

관련 문제