2017-05-26 1 views
0

Je suis en train de tester Unicode hors de portée BMP. Ci-dessous, j'utilise + UD834DF01 comme caractère d'exemple et essaye de le convertir en un caractère multi-octets, mais le programme a échoué et dit 'séquence d'octets illégaux', pourquoi?wctomb échouent: séquence d'octets illégale

#include <stdio.h> 
#include <wchar.h> 
#include <locale.h> 
#include <stdlib.h> 
#include <limits.h> 

int main(int argc, const char *argv[]) 
{ 
    setlocale(LC_ALL, ""); // my locale is UTF-8 

    wchar_t wc = 0xd834df01; 
    char bytes[MB_LEN_MAX] = {0}; 
    int r = wctomb(bytes, wc); 
    if (r > 0) { 
     for (int i = 0; i < MB_LEN_MAX; i++) 
      printf("0x%x\n", bytes[i]); 
    } else { 
     perror("fail"); 
    } 

    return 0; 
} 

Répondre

1

L'hex D834DF01 n'est pas un point de code Unicode valide; aucune valeur au-dessus de l'hex 110000 est. La paire (séquence de deux) unités de code 'substituts' D834 et DF01 est le UTF-16 codant pour le code de code U + 10D301 qui est dans une zone à usage privé et non un caractère standard, mais est validable en UTF-8 comme f4 8d 8c 81. UTF-16 est utilisé dans une grande partie de Windows, presque tout de Java, et d'autres endroits. Correction: J'ai fait la conversion de substitution dans ma tête et j'ai glissé un hexit; comme commenté, il est en réalité U + 1D301 digram for heavenly earth dans Tai Xuan Jing.

+0

Est-ce que cela veut dire que gcc utilise wchar_t pour représenter un codepoint Unicode? – noinput

+0

J'ai essayé libiconv, mais mon résultat est U + 01D301 et UTF-8 comme 0xf0 0x9d 0x8c 0x81 – noinput

+0

@noinput: le support large-char/string est la plupart du temps votre bibliothèque C plutôt que votre compilateur et la glibc moderne Unicode UCS- 4. Vous avez raison sur 1D301, voir modifier. –