Unicode/Multi-Byte?



  • Tag, ich hab mal ne Frage über Sonderzeichen.
    Und zwar habe ich das korrekt verstanden?:
    L"aö"
    würde 4 Bytes, nämlich 2 wchar_ts benutzen
    und "aö" würde 3 Bytes, nämlich 3 chars benutzen? Oder wie ist das alles zu verstehen?
    Also:
    Wenn L für Widestring steht und Widestring für Sonderzeichen, wieso ist es dann möglich in einem normalen String Sonderzeichen zu verwenden?



  • aö können auch 3 wchar_t's sein. (a + o + combining diaresis) Willkommen in der Welt von Unicode. 😉

    WideString steht nicht für Sonderzeichen.

    Nicht-ASCII-Zeichen in einem normalen String sind erstmal völlig legal. Es hängt halt komplett von deiner Kodierung ab. Du kannst auch UTF-8 in einem normalen String speichern.



  • L"aö"
    == 3*wchar_t ('ä', 'ö', '\0')
    wchar_t ist unter windows 2 byte lang und unter unix 4

    "aö"
    im deutschen ASCII-code 3 chars ('a', 'ö', '\0')
    in anderen ASCII-codes 3 chars ('a', '?', '\0')

    In einem normalen String kann man den für sein Land spezifischen ASCII-Code packen...
    bis 2^7 ist das weltweit(?) kompatibel - ab dann musst du (ziemlich aufwendig) umwandeln...

    wenn dein programm also auf einem russischen os läuft, dann wird das mit ä,ö,ü,ß,... nichts mehr - dann musst du auf wchar_t setzen, also std::wstring...

    falls du mehr wissen willst:
    nach "UCS" bzw "UTF" googlen (bzw direkt bei wikipedia suchen)
    oder du suchst hier im forum - ist auch eine immer wiederkehrende frage bzw problem ^^

    bb



  • Im übrigen ist L"aö" sowieso etwas völlig implementierungsabhängiges, da ö nicht zum Standard C++ Character Set gehört. Wenn sollte man das ö in dem Encoding escapen, in dem man es haben will.

    unskiled schrieb:

    wenn dein programm also auf einem russischen os läuft, dann wird das mit ä,ö,ü,ß,... nichts mehr - dann musst du auf wchar_t setzen, also std::wstring...

    Eben nicht. Es ist ein Trugschluss, dass std::wstring respektive wchar_t Ecnoding-Probleme löst. UTF-8 kann und sollte man eher in einem normalen Character-Array bzw. std::string ablegen. C++ kennt weder irgendwelche Formen von Encoding noch Unicode direkt, auch wenn man es den Streams beibringen kann. Vor der Ausgabe muss man das Encoding auf das des Ausgabemediums anpassen.
    Und wenn auf einem russischen OS ein Character-Literal mit L"aö" kompiliert wird, kommt vermutlich auch nur Mist bei raus.



  • 7H3 N4C3R schrieb:

    Eben nicht. Es ist ein Trugschluss, dass std::wstring respektive wchar_t Ecnoding-Probleme löst. UTF-8 kann und sollte man eher in einem normalen Character-Array bzw. std::string ablegen.

    Quelle?

    7H3 N4C3R schrieb:

    C++ kennt weder irgendwelche Formen von Encoding noch Unicode direkt

    C++ kennt std::wstring! Und hier in dem Thread gings nicht um Encoding...

    7H3 N4C3R schrieb:

    auch wenn man es den Streams beibringen kann. Vor der Ausgabe muss man das Encoding auf das des Ausgabemediums anpassen.

    Jopp - ich habe auch nie behauptet, dass beispielsweise die windows-console alles ausgeben könnte, was windows auch verarbeiten kann...

    7H3 N4C3R schrieb:

    Und wenn auf einem russischen OS ein Character-Literal mit L"aö" kompiliert wird, kommt vermutlich auch nur Mist bei raus.

    Deshalb sollte er mal nach UCS googlen - damit er merkt, dass man nicht L"äö" schreibt sondern die Unicode-Codierung nutzen sollte... (U+....)

    und wenn ich hier so was wie

    da ö nicht zum Standard C++ Character Set gehört

    lese... naja, lassen wir das...

    hf


  • Administrator

    @unskilled,
    wchar_t garantiert kein Unicode! Es heisst einfach nur, dass man für ein Charackterzeichen 2, bzw. 4, Bytes hat. Welches Zeichen nun zu welchem Wert gehört, bestimmt auch bei wchar_t das aktuelle Locale.
    Es kann also sein, dass ein anderer Zeichensatz verwendet wird und dadurch der Wert von ä in Unicode ein völlig anderes Zeichen darstellt.

    Grüssli



  • Dravere schrieb:

    wchar_t garantiert kein Unicode! [...] Welches Zeichen nun zu welchem Wert gehört, bestimmt auch bei wchar_t das aktuelle Locale.

    quelle?
    wchar_t garantiert mir, dass ich einem bestimmten zahlenwert genau einen buchstaben zuordnen kann - nämlich den, den der unicode-standard vorschreibt... dieser standard ist aber wiederrum international... das heißt aber, dass hier ein U+00AE genau das selbe darstellt, wie auch in Timbuktu?!
    oder ist daran irgendwas falsch?

    bb



  • unskilled schrieb:

    und wenn ich hier so was wie

    da ö nicht zum Standard C++ Character Set gehört

    lese... naja, lassen wir das...

    Aha, und was ist damit?

    unskilled schrieb:

    wchar_t garantiert mir, dass ich einem bestimmten zahlenwert genau einen buchstaben zuordnen kann - nämlich den, den der unicode-standard vorschreibt... dieser standard ist aber wiederrum international... das heißt aber, dass hier ein U+00AE genau das selbe darstellt, wie auch in Timbuktu?!
    oder ist daran irgendwas falsch?

    Quelle? 🙄 (diese Zeile kann Spuren von Nüssen und Sarkasmus enthalten)

    Du kannst auch wchar_t jeden anderen Zahlenwert zuordnen, auch einen den der Unicode-Standard nicht vorschreibt. Und das sogar, obwohl letzterer international ist.

    Es ist wchar_t völlig egal, sowie C++ als solches auch, ob du darin Unicode ablegst oder eine Schweineborstenverwaltung damit umsetzt. Zumal es grob so um die 90000 zugeordnete Unicode-Characters gibt, da reicht ein wchar_t mit 2 Byte ja garnicht aus. Huch. Da braucht man ja plötzlich 2 von für einen Unicode-Character.
    Wenn du ein U+wxyz irgendwo ablegst, hast du es schon in höchstem Maße mit Encoding zu tun. Einmal hast du dich auf Unicode festgelegt, zum anderen wählst du z.B. UTF-8, UTF-16LE, UTF-16BE oder vielleicht UTF-32 als Kodierung aus, abhängig vom Datentyp der die Daten aufnimmt. Und für einen Unicodecharacter braucht man u.U. mehrere "Characters" des zugrundeliegenden Typ. Für ein Glyph braucht man u.U. nochmal mehr. wchar_t brauchst du im Zusammenhang mit Unicode nur, wenn du dich für eine Kodierung entscheidest, die Unicodecharacters in 2-Byte oder meinetwegen 4-Byte breiten "Characters" der zugrundeliegenden Repräsentation kodiert.

    Im übrigen siehst du auch in Timbuktu mit "\xC2\xAE" (ohne L) ein ®, wenn man's in UTF-8 kodiert.

    Vielleicht interessiert dich auch das hier (eine Quelle...):

    ISO 14882 schrieb:

    2.13.2/5:

    A universal-character-name is translated to the encoding, in the execution character set, of the character named. If there is no such encoding, the universal-character-name is translated to an implementation defined encoding. [Note: in translation phase 1, a universal-character-name is introduced whenever an actual extended character is encountered in the source text. Therefore, all extended characters are described in terms of universal-character-names. However, the actual compiler implementation may use its own native character set, so long as the same results are obtained.


  • Administrator

    @unskilled,
    Ich kann dir keine Quelle geben, aus zwei Gründen:
    1. Ich habe keinen C++ Standard.
    2. Es gibt, nach meinen Informationen, nirgends im Standard die Erwähnung von Unicode.

    Es wäre somit deine Aufgabe uns die Stelle im Standard zu zeigen, wo steht, dass wchar_t für Unicode zu verwenden sei.

    Grüssli



  • ISO/IEC 14882:2003 §3.9.1 schrieb:

    Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest
    extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same
    size, signedness, and alignment requirements (3.9) as one of the other integral types, called its underlying
    type

    Nichts mit Unicode...



  • In der Praxis reicht die Plane 0 aber meist vollkommen aus, was mit sizeof(wchar_t)>=2 auf mindestens den populärsten Compilern für Desktopsysteme gegeben ist. Und das "Problem" der Combining Characters sollte imo nicht auf den Datentyp zurückfallen, solange du dich auf eine Normalization Form einigst.


Anmelden zum Antworten