Multibyte Chars mit glibc



  • Hallo,

    ich versuche, die locale-abhängigen Zeichensatzfunktionen der GNU C Library zu verstehen. Ich habe etwas in der glibc-Doku gestöbert und herumprobiert, bekomme aber nicht die erwarteten Ergebnisse. Was läuft da falsch?

    Danke!

    // testmb.c
    
    #include <stdlib.h> // MB_CUR_MAX
    #include <stdio.h> // printf()
    #include <limits.h> // MB_LEN_MAX
    #include <wchar.h> // mbrtowc()
    
    int
    main(int argc, char* argv[])
    {
      // erwartetes Ergebnis für MB_CUR_MAX:
      // bei LC_TYPE=de_DE (= ISO 8859-1): 1
      // bei LC_TYPE=de_DE.UTF-8: 4
      printf("MB_LEN_MAX: %d\nMB_CUR_MAX: %d\n", MB_LEN_MAX, MB_CUR_MAX);
    
      wchar_t* result = malloc(sizeof(wchar_t));
      size_t erg;
    
      // äöüß in ISO 8859-1
      const char data1[] = {0xe4, 0xf6, 0xfc, 0xdf, 0x00};
      printf("%s\n", data1); // Ausgabe hängt von Einstellung des Terminals/XTerm ab
      erg = mbrtowc(result, data1, (size_t) 1, NULL);
      // Rückgabewert von mbrtowc():
      // -2: unvollständiges Multibytezeichen
      // -1: ungültige Bytefolge
      // 0: Zeichen ist NULL
      // > 0: Anzahl verwertete Zeichen
      // erwartetes Ergebnis:
      // bei LC_TYPE=de_DE: 1 (ä = 1 Byte)
      // bei LC_TYPE=de_DE.UTF-8: -2 (0xe4 = 1110 0100 = Startbyte 3-Byte-Zeichen)
      printf ("mbrtowc(0xe4): %d\n", erg);
    
      // äöüß in UTF-8
      const char data2[] = {0xc3, 0xa4, 0xc3, 0xb6, 0xc3, 0xbc, 0xc3, 0x9f, 0x00};
      printf("%s\n", data2); // Ausgabe hängt von Einstellung des Terminals/XTerm ab
      erg = mbrtowc(result, data2, (size_t) 2, NULL);
      // erwartetes Ergebnis:
      // bei LC_TYPE=de_DE: 1 (0xc3 = A mit Tilde)
      // bei LC_TYPE=de_DE.UTF-8: 2 (ä = 2 Bytes)
      printf ("mbrtowc(0xc3 0xa4): %d\n", erg);
    
      return 0;
    }
    
    emily@Cervelat:~$ gcc -Wall -o testmb testmb.c
    emily@Cervelat:~$ locale
    LANG=de_DE.UTF-8
    LANGUAGE=de_DE:de:en_GB:en
    LC_CTYPE="de_DE.UTF-8"
    LC_NUMERIC="de_DE.UTF-8"
    LC_TIME="de_DE.UTF-8"
    LC_COLLATE="de_DE.UTF-8"
    LC_MONETARY="de_DE.UTF-8"
    LC_MESSAGES="de_DE.UTF-8"
    LC_PAPER="de_DE.UTF-8"
    LC_NAME="de_DE.UTF-8"
    LC_ADDRESS="de_DE.UTF-8"
    LC_TELEPHONE="de_DE.UTF-8"
    LC_MEASUREMENT="de_DE.UTF-8"
    LC_IDENTIFICATION="de_DE.UTF-8"
    LC_ALL=
    emily@Cervelat:~$ ./testmb
    MB_LEN_MAX: 16
    MB_CUR_MAX: 1
    äöüß
    mbrtowc(0xe4): -1
    ÀöÌß
    mbrtowc(0xc3 0xa4): -1
    emily@Cervelat:~$ export LC_CTYPE=de_DE
    emily@Cervelat:~$ locale
    LANG=de_DE.UTF-8
    LANGUAGE=de_DE:de:en_GB:en
    LC_CTYPE=de_DE
    LC_NUMERIC="de_DE.UTF-8"
    LC_TIME="de_DE.UTF-8"
    LC_COLLATE="de_DE.UTF-8"
    LC_MONETARY="de_DE.UTF-8"
    LC_MESSAGES="de_DE.UTF-8"
    LC_PAPER="de_DE.UTF-8"
    LC_NAME="de_DE.UTF-8"
    LC_ADDRESS="de_DE.UTF-8"
    LC_TELEPHONE="de_DE.UTF-8"
    LC_MEASUREMENT="de_DE.UTF-8"
    LC_IDENTIFICATION="de_DE.UTF-8"
    LC_ALL=
    emily@Cervelat:~$ ./testmb
    MB_LEN_MAX: 16
    MB_CUR_MAX: 1
    äöüß
    mbrtowc(0xe4): -1
    ÀöÌß
    mbrtowc(0xc3 0xa4): -1
    

    System: Ubuntu Linux 06.06, gcc 4.03, glibc 2.3.6


Anmelden zum Antworten