C ++ 11의 문자열 리터럴에 대한 유니 코드 인코딩 character, no

후속 관련된 질문 , 나는 C ++ 11의 새로운 문자 및 문자열 리터럴 유형에 대해 묻고 싶습니다. 이제 4 가지 종류의 문자와 5 가지 종류의 문자열 리터럴이있는 것 같습니다. 문자 유형 :

char     a =  '\x30';         // character, no semantics
wchar_t  b = L'\xFFEF';       // wide character, no semantics
char16_t c = u'\u00F6';       // 16-bit, assumed UTF16?
char32_t d = U'\U0010FFFF';   // 32-bit, assumed UCS-4

그리고 문자열 리터럴 :

char     A[] =  "Hello\x0A";         // byte string, "narrow encoding"
wchar_t  B[] = L"Hell\xF6\x0A";      // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6";        // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto     E[] = u8"\u00F6\U0010FFFF"; // (3)

질문은 이것입니다 : \x/ \u/ \U문자 참조는 모든 문자열 유형과 자유롭게 결합 할 수 있습니까? 모든 문자열 유형이 고정 너비입니까? 즉, 배열이 리터럴에 나타나는만큼 정확하게 요소를 포함 합니까? 아니면 \x/ \u/ \U참조에 대한 가변 바이트 수로 확장됩니까? 마 u""u8""문자열은 예를 들어, 의미를 인코딩 한 내가 말할 수있는 char16_t x[] = u"\U0010FFFF", 그리고 비 BMP 코드 포인트는 두 단위 UTF16 순서로 인코딩됩니다? 그리고 비슷하게 u8? (1)에서 외로운 대리자를 쓸 수 \u있습니까? 마지막으로 인코딩을 인식하는 문자열 함수가 있습니까 (즉, 문자를 인식하고 유효하지 않은 바이트 시퀀스를 감지 할 수 있음)?

이것은 약간의 개방형 질문이지만 새로운 C ++ 11의 새로운 UTF 인코딩 및 유형 기능에 대해 가능한 한 완전한 그림을 얻고 싶습니다.



답변

\ x / \ u / \ U 문자 참조는 모든 문자열 유형과 자유롭게 결합 할 수 있습니까?

호는 \x아무것도 사용할 수 있지만 \u하고 \U만 특이 UTF 인코딩 된 문자열에 사용될 수있다. 그러나 어떤 UTF로 인코딩 된 문자열을, \u그리고 \U당신이 맞는 볼 수 있습니다.

모든 문자열 유형이 고정 너비입니까? 즉, 배열이 리터럴에 나타나는만큼 정확하게 요소를 포함합니까, 아니면 \ x / \ u / \ U 참조에 대한 가변 바이트 수로 확장됩니까?

당신이 의미하는 방식이 아닙니다. \x,, \u\U문자열 인코딩을 기반으로 변환됩니다. 이러한 “코드 단위”(유니 코드 용어 사용. A char16_t는 UTF-16 코드 단위) 값의 수는 포함하는 문자열의 인코딩에 따라 다릅니다. 리터럴 u8"\u1024"은 2 char와 null 종결자를 포함하는 문자열을 만듭니다 . 리터럴 u"\u1024"은 1 char16_t과 null 종결자를 포함하는 문자열을 만듭니다 .

사용되는 코드 단위 수는 유니 코드 인코딩을 기반으로합니다.

u “”및 u8 “”문자열에 인코딩 의미가 있습니까? 예를 들어 char16_t x [] = u “\ U0010FFFF”라고 말할 수 있으며 비 BMP 코드 포인트는 2 단위 UTF16 시퀀스로 인코딩됩니까?

u""UTF-16으로 인코딩 된 문자열을 만듭니다. u8""UTF-8로 인코딩 된 문자열을 만듭니다. 유니 코드 사양에 따라 인코딩됩니다.

(1)에서 \ u로 고독한 대리자를 쓸 수 있습니까?

절대적으로하지. 사양은 \u또는에 대한 코드 포인트로 UTF-16 서로 게이트 쌍 (0xD800-0xDFFF)을 사용하는 것을 명시 적으로 금지합니다 \U.

마지막으로 인코딩을 인식하는 문자열 함수가 있습니까 (즉, 문자를 인식하고 유효하지 않은 바이트 시퀀스를 감지 할 수 있음)?

절대적으로하지. 글쎄요, 다시 말하겠습니다.

std::basic_string유니 코드 인코딩을 처리하지 않습니다. 확실히 UTF로 인코딩 된 문자열을 저장할있습니다 . 그러나 그들은 단지의 순서로 생각할 수있는 char, char16_t또는 char32_t; 특정 메커니즘으로 인코딩 된 일련의 유니 코드 코드 포인트로 생각할 수 없습니다. basic_string::length()코드 포인트가 아닌 코드 단위의 수를 반환합니다. 그리고 분명히 C 표준 라이브러리 문자열 함수는 완전히 쓸모가 없습니다.

그러나 유니 코드 문자열의 “길이”는 코드 포인트의 수를 의미하지 않습니다. 일부 코드 포인트는 이전 코드 포인트와 결합되는 “문자”(불행한 이름)를 결합합니다. 따라서 여러 코드 포인트가 단일 시각적 문자에 매핑 될 수 있습니다.

Iostreams는 실제로 유니 코드 인코딩 값을 읽고 쓸 수 있습니다. 이렇게하려면 로케일을 사용하여 인코딩을 지정하고 다양한 위치에 적절하게 삽입해야합니다. 이것은 말처럼 쉬운 일이며 방법을 보여줄 코드가 없습니다.