Pergunta

Eu estou escrevendo um pequeno aplicativo que eu preciso para testar com utf-8 caracteres de um número diferente de comprimentos de byte.

eu posso caracteres de entrada Unicode para teste que são codificados em utf-8 com 1,2 e 3 bytes muito bem, fazendo, por exemplo:

string in = "pi = \u3a0";

Mas como faço para obter um caractere Unicode que está codificado com 4 bytes? Eu tentei:

string in = "aegan check mark = \u10102";

que, tanto quanto eu entendo deve ser outputting. Mas quando eu imprimir isso eu recebo ?0

O que eu estou ausente?

EDIT:

Eu tenho que trabalhar, adicionando zeros à esquerda:

string in = "\U00010102";

desejo que eu tinha pensado nisso mais cedo:)

Foi útil?

Solução

Há uma forma mais longa de fuga na \U padrão seguido por oito dígitos, em vez de \u seguido por quatro dígitos. Isso também é usado em Java e Python, entre outros:

>>> '\xf0\x90\x84\x82'.decode("UTF-8")
u'\U00010102'

No entanto, se você estiver usando cadeias de bytes, porque não basta escapar cada byte como acima, em vez de depender o compilador para converter a fuga para uma string UTF-8? Este parece ser mais portátil, bem como - se eu compilar o seguinte programa:

#include <iostream>
#include <string>

int main()
{
    std::cout << "narrow: " << std::string("\uFF0E").length() <<
        " utf8: " << std::string("\xEF\xBC\x8E").length() <<
        " wide: " << std::wstring(L"\uFF0E").length() << std::endl;

    std::cout << "narrow: " << std::string("\U00010102").length() <<
        " utf8: " << std::string("\xF0\x90\x84\x82").length() <<
        " wide: " << std::wstring(L"\U00010102").length() << std::endl;
}

No win32 com meu opções atual cl dá:

warning C4566: character represented by universal-character-name '\UD800DD02' cannot be represented in the current code page (932)

O compilador tenta converter todos os escapes Unicode em strings de bytes para a página de código do sistema, que UTF-8 ao contrário não pode representar todos os caracteres Unicode. Estranhamente tem entendido que \U00010102 é \uD800\uDD02 em UTF-16 (a sua representação interna unicode) e mutilado a fuga na mensagem de erro ...

Quando executado, o programa imprime:

narrow: 2 utf8: 3 wide: 1
narrow: 2 utf8: 4 wide: 2

Note que as UTF-8 bytestrings e as grandes cadeias estão corretas, mas o compilador não conseguiu "\U00010102" convertido, dando a "??" cadeia de bytes, um resultado incorreto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top