Domanda

Sto scrivendo una piccola app che devo testare con caratteri utf-8 di diverso numero di lunghezze di byte.

Posso inserire caratteri unicode per test che sono codificati in utf-8 con 1,2 e 3 byte semplicemente facendo, per esempio:

string in = "pi = \u3a0";

Ma come posso ottenere un carattere Unicode codificato con 4 byte? Ho provato:

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

Quale, per quanto ho capito, dovrebbe essere emesso. Ma quando lo stampo ottengo ?0

Cosa mi sto perdendo?

Modifica

L'ho fatto funzionare aggiungendo zeri iniziali:

string in = "\U00010102";

Vorrei averci pensato prima :)

È stato utile?

Soluzione

Esiste una forma più lunga di escape nello schema \ U seguito da otto cifre, piuttosto che \ u seguito da quattro cifre. Questo è usato anche in Java e Python, tra gli altri:

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

Tuttavia, se si utilizzano stringhe di byte, perché non semplicemente sfuggire a ogni byte come sopra, piuttosto che fare affidamento sul compilatore per convertire l'escape in una stringa UTF-8? Anche questo sembrerebbe più portatile - se compilo il seguente programma:

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

Su win32 con le mie opzioni attuali, cl dà:

avviso C4566: il carattere rappresentato dal nome di carattere universale '\ UD800DD02' non può essere rappresentato nella tabella codici corrente (932)

Il compilatore tenta di convertire tutti gli escape unicode nelle stringhe di byte nella tabella codici di sistema, che a differenza di UTF-8 non può rappresentare tutti i caratteri unicode. Stranamente ha capito che \ U00010102 è \ uD800 \ uDD02 in UTF-16 (la sua rappresentazione unicode interna) e ha modificato la fuga nel messaggio di errore ...

Quando eseguito, il programma stampa:

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

Nota che i bytestring UTF-8 e le stringhe estese sono corretti, ma il compilatore non è riuscito a convertire " \ U00010102 " , fornendo la stringa di byte " ?? " , un risultato errato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top