2016-12-12 11 views
6

좁은 ostream에 wchar_t, char16_t 또는 char32_t 값을 입력하면 코드 포인트의 숫자 값이 인쇄됩니다.iostreams -`wchar_t` 또는`charXX_t` 값을 문자로 출력

#include <iostream> 
using std::cout; 
int main() 
{ 
    cout << 'x' << L'x' << u'x' << U'x' << '\n'; 
} 

인쇄 x120120120. 이는 basic_ostreamcharT의 특정 조합에 대해 operator<<이 있지만 다른 문자 유형에 대한 유사 연산자가 없기 때문에 자동으로 int으로 변환되어 인쇄됩니다. 유사하게, 비 좁은 문자열 리터럴 (L"x", u"x", U"X") 자동 캐릭터에게 (wstring, u16string, u32string)는 심지어 컴파일되지 개체 void* 변환 포인터 값으로서 출력하고, 비 좁은한다.

그래서, 질문은 : 좁은 ostream에에 문자 오히려 코드 포인트의 숫자 값보다, 같은 wchar_t, char16_t, 또는 char32_t 값을 출력하는 가장 끔찍한 방법은 무엇입니까? ostream의 인코딩에서 해당 인코딩으로 표현할 수있는 코드 포인트를 올바르게 변환해야하며 코드 포인트를 나타낼 수 없을 때 오류를보고해야합니다. (예를 들어, u'…' 주어와 UTF-8 ostream에, 상기 3 바이트 시퀀스 0xE2을 0x80 0xA6를 스트림에 기록한다;하지만 u'â' 부여하고 KOI8-R의 ostream에이 오류가보고되어야한다.) 마찬가지로

, 좁은 ostream에서 비 좁은 C 문자열 또는 문자열 객체를 출력 인코딩으로 변환하는 방법은 무엇입니까?

ISO C++ 11에서 수행 할 수없는 경우 플랫폼 별 답변을 취할 것입니다.

은 (this question에 의해 영감을.)

+2

, 당신도 1) 넓은 ostream에를 사용하는, 또는 2)) 잠재적 손실 변환되는 (자신을 인코딩 좁은에 와이드 문자 데이터를 변환합니다. ostream은 전환을 수행 할 수 없습니다. ['std :: wstring_convert'] (http : //en.cppreference.com/w/cpp/locale/wstring_convert) 또는 [ICONV] (https://www.gnu.org/software/libiconv/) 또는 [ICU] (http : //site.icu-project. org /). –

답변

2

당신이 언급 한 바와 같이이 좁은 ostream에 대한 operator<<(std::ostream&, const wchar_t)이 없습니다. 구문을 사용하고자한다면 ostreamwchar과 함께 사용하는 방법을 가르쳐서 루틴을 먼저 정수로 변환해야하는보다 나은 오버로드로 선택하도록 할 수 있습니다.

당신은 모험을 좋아하는 경우 :

namespace std { 
    ostream& operator<< (ostream& os, wchar_t wc) { 
    if(unsigned(wc) < 256) // or another upper bound 
     return os << (unsigned char)wc; 
    else 
     throw your_favourite_exception; // or handle the error in some other way 
    } 
} 

그렇지 않으면, 투명 wchar_t을 포함하고 사용자 정의 friend operator<<을 가지고 간단한 struct을하고 출력하기 전에 당신의 넓은 문자를 변환합니다.

편집 : 당신의 로케일을 설정하는 것을 잊지 마세요

ostream& operator<< (ostream& os, wchar_t wc) { 
    std::mbstate_t state{}; 
    std::string mb(MB_CUR_MAX, '\0'); 
    size_t ret = std::wcrtomb(&mb[0], wc, &state); 
    if(ret == static_cast<std::size_t>(-1)) 
     deal_with_the_error(); 
    return os << mb; 
} 

:는 같은 <cwchar>에서 기능을 사용할 수 있습니다, 및 로케일에서 즉석 변환을 만들려면 시스템 기본 : 요컨대

std::locale::global(std::locale("")); 
std::cout << L'ŭ'; 
+0

값을 좁은 출력 인코딩으로 변환하지 않습니다. 그것은 필수적이며, 아직 내가 어떻게 해야할지 모르는 부분이기도합니다. – zwol

+0

@zwol 와이드 문자를 ASCII 문자로 변환하고 그렇지 않으면 거부하는 경우와 달리 어떻게 변환 하시겠습니까? 그런 다음 악센트 등을 삭제하는 등 구체적이어야합니다. –

+0

귀하의 예제는 이것을 통과하는 'x'를 사용합니다 ('L' x'의 경우 다른 유형의 경우에도 동일하게 수행해야합니다). –