Verstehe Unicode nicht



  • #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
      std::string test = "你好";
      cout << test << endl;
      for(size_t i = 0; i < test.size(); ++i)
        std::cout << "0x"
                  << std::hex
                  << static_cast<unsigned>(static_cast<unsigned char>(test[i]))
                  << '\n';
    }
    
    # g++ -Wall -W -std=c++98 foo.cpp
    # ./a.out
    你好
    0xe4
    0xbd
    0xa0
    0xe5
    0xa5
    0xbd
    

    Das erste Beispiel (mit wstring) funktioniert so nicht, da wstring-Literale mit einem L beginnen (also anstelle "foo", L"foo") und du solltest wcout benutzen. Denk dran, dass du auch dein Terminal entsprechend einstellen musst oder ein locale bei wcout setzen!

    warum das ustring Beispiel nicht funktioniert, weiß ich jetzt nicht. Habe aber auch kein glibmm da, um das zu überprüfen.



  • UNICODE Strings sollte man IMO nicht in C++ Source Files packen. Zumindest nicht wenn man möchte dass alles reibungslos funktioniert. 😉



  • Und wie würdest du dann obiges Beispiel schreiben?



  • rüdiger schrieb:

    Sie ist doch nicht fest, wenn ich damit UTF-16 Strings darstelle. Ansonsten ist wchat_t einfach nicht breit genug unter den meisten Windows-Compilern, um alle Zeichen darzustellen, die das System darstellen kann.

    Ja, laut Standard muss wchar_t jedoch den maximalen Code-Point fassen können. Das heißt, es ist ganz klar als feste Zeichenbreite definiert. Wäre dem nicht so, wären die ganzen Standard-Konveriertungsfunktionen zwischen breiten Zeichen (wchar_t()) und Multibyte-Kodierungen (mittels char) auch relativ sinnlos.
    Aber selbst wenn die Standards in dem Punkt gebrochen werden, ändert das nichts daran, dass zwei Bytes für die mit Abstand meisten Zeichen ausreichen. In der gewöhnlichen Praxis wird man also vermutlich nie einen Unterschied zwischen UTF-16 und UCS-2 bei internen Repräsentationen bemerken. (Was natürlich nicht davon ablenken soll, dass man damit nicht auf Nummer sicher geht.)

    wcout kann übrigens mitunter ziemlich (Standard-)locale-resistent sein. Sicher ist man dagegen mit File-Streams (wofstream) - die haben mir in dem Punkt noch keinen Ärger gemacht.



  • edocinU schrieb:

    Und wie würdest du dann obiges Beispiel schreiben?

    Keine Ahnung was du da für Zeichen benutzt hast. Aber UCS und Unicode gibt man am besten in dieser Form ein:

    L"\u06A1\u0609\u06A0"
    

    Um genau zu sein: U-Escapes. Weiß nicht ob das U jetzt für UCS oder Unicode steht.



  • C++ ist noch nicht dazu geeignet, Unicode Strings zu verarbeiten. Vielleicht ändert sich das ja mit C++0x. Aber bis dahin würde ich an deiner Stelle einfach Perl verwenden. Damit geht das einfacher und unkompliziert:

    `#!/usr/bin/perl

    use Encode;

    binmode(STDOUT, ":utf8");

    my $test = decode_utf8("さくら");

    print($test, "\n");

    print(substr(test,0,1),substr(test, 0, 1), substr(test, 1, 1), substr($test, 2, 1), "\n");`

    Ausgbe wie erwartet:
    さくら
    さくら

    😋 👍



  • --------------------------
                             /|  /|  |                          |
                             ||__||  |       Trolle bitte       |
                            /   O O\__           nicht          |
                           /          \         füttern!        |
                          /      \     \                        |
                         /   _    \     \ ----------------------
                        /    |\____\     \     ||
                       /     | | | |\____/     ||
                      /       \|_|_|/   |    __||
                     /  /  \            |____| ||
                    /   |   | /|        |      --|
                    |   |   |//         |____  --|
             * _    |  |_|_|_|          |     \-/
          *-- _--\ _ \     //           |
            /  _     \\ _ //   |        /
          *  /   \_ /- | -     |       |
            *      ___ c_c_c_C/ \C_c_c_c____________
    


  • Artchi schrieb:

    --------------------------
                             /|  /|  |                          |
                             ||__||  |       Trolle bitte       |
                            /   O O\__           nicht          |
                           /          \         füttern!        |
                          /      \     \                        |
                         /   _    \     \ ----------------------
                        /    |\____\     \     ||
                       /     | | | |\____/     ||
                      /       \|_|_|/   |    __||
                     /  /  \            |____| ||
                    /   |   | /|        |      --|
                    |   |   |//         |____  --|
             * _    |  |_|_|_|          |     \-/
          *-- _--\ _ \     //           |
            /  _     \\ _ //   |        /
          *  /   \_ /- | -     |       |
            *      ___ c_c_c_C/ \C_c_c_c____________
    
    --------------------------
                             /|  /|  |                          |
                             ||__||  |       Trolle bitte       |
                            /   O O\__           nicht          |
                           /          \         füttern!        |
                          /      \     \                        |
                         /   _    \     \ ----------------------
                        /    |\____\     \     ||
                       /     | | | |\____/     ||
                      /       \|_|_|/   |    __||
                     /  /  \            |____| ||
                    /   |   | /|        |      --|
                    |   |   |//         |____  --|
             * _    |  |_|_|_|          |     \-/
          *-- _--\ _ \     //           |
            /  _     \\ _ //   |        /
          *  /   \_ /- | -     |       |
            *      ___ c_c_c_C/ \C_c_c_c____________
    


  • @Artchi:
    Es ist leider wirklich so, dass sich C++ (im Gegensatz zu z.B. Perl) mit Unicode noch recht schwer tut. Selbst mit Glib::ustring scheint es ja nicht richtig zu funktionieren (auch wenn ich es selbst noch nicht getestet habe).



  • Hihi.
    Perl, PHP, Java etc. setzen im Normalfall C oder C++ Libraries ein um mit Unicode zu arbeiten. Oft ist es einfach die (leider sehr schrottige) ICU.
    Und die kann man genausogut in C++ verwenden.


Anmelden zum Antworten