Após uma pergunta relacionada , gostaria de perguntar sobre os novos tipos de caracteres e literais de string no C ++ 11. Parece que agora temos quatro tipos de caracteres e cinco tipos de literais de string. Os tipos de personagem:
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
E os literais de string:
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)
A questão é: as referências do caractere / \x
/ \u
podem \U
ser combinadas livremente com todos os tipos de string? Todos os tipos de string têm largura fixa, ou seja, os arrays contêm exatamente tantos elementos quanto aparecem no literal, ou as referências \x
/ \u
/ \U
são expandidas em um número variável de bytes? As strings u""
e u8""
têm semântica de codificação, por exemplo, posso dizer char16_t x[] = u"\U0010FFFF"
, e o codepoint não BMP é codificado em uma sequência UTF16 de duas unidades? E da mesma forma para u8
? Em (1), posso escrever substitutos solitários com \u
? Finalmente, alguma das funções de string reconhece a codificação (ou seja, elas reconhecem os caracteres e podem detectar sequências de bytes inválidas)?
Esta é uma questão um pouco aberta, mas gostaria de obter uma imagem o mais completa possível da nova codificação UTF e recursos de tipo do novo C ++ 11.
u"\U0010FFFF"
em um par substituto.Respostas:
No.
\x
pode ser utilizado em qualquer coisa, mas\u
e\U
só pode ser utilizado em cadeias que são especificamente codificado-UTF. No entanto, para qualquer string codificada em UTF,\u
e\U
pode ser usado como desejar.Não da maneira que você quer dizer.
\x
,\u
e\U
são convertidos com base na codificação da string. O número dessas "unidades de código" (usando termos Unicode. Achar16_t
é uma unidade de código UTF-16) depende da codificação da string que o contém. O literalu8"\u1024"
criaria uma string contendo 2char
s mais um terminador nulo. O literalu"\u1024"
criaria uma string contendo 1char16_t
mais um terminador nulo.O número de unidades de código usado é baseado na codificação Unicode.
u""
cria uma string codificada em UTF-16.u8""
cria uma string codificada em UTF-8. Eles serão codificados de acordo com a especificação Unicode.Absolutamente não. A especificação proíbe expressamente o uso de pares substitutos UTF-16 (0xD800-0xDFFF) como pontos de código para
\u
ou\U
.Absolutamente não. Bem, deixe-me reformular isso.
std::basic_string
não lida com codificações Unicode. Eles certamente podem armazenar strings codificadas em UTF. Mas eles só podem pensar neles como seqüências dechar
,char16_t
ouchar32_t
; eles não podem pensar neles como uma sequência de pontos de código Unicode que são codificados com um mecanismo específico.basic_string::length()
retornará o número de unidades de código, não pontos de código. E, obviamente, as funções de string da biblioteca padrão C são totalmente inúteisDeve-se notar, entretanto, que "comprimento" para uma string Unicode não significa o número de pontos de código. Alguns pontos de código combinam "caracteres" (um nome infeliz), que se combinam com o ponto de código anterior. Assim, vários pontos de código podem ser mapeados para um único caractere visual.
Iostreams pode, de fato, ler / gravar valores codificados em Unicode. Para fazer isso, você terá que usar uma localidade para especificar a codificação e inseri-la adequadamente nos vários lugares. É mais fácil falar do que fazer, e não tenho nenhum código para mostrar como.
fonte
\x
não pode ser usado com nada, por exemplo U + 1F984 não funcionará com o prefixo \ x\u
e\U
não pode ser usado com caracteres de controle ASCII, pelo menos no Clang.