"Character" in modernen Sprachen?



  • Früher wurden Codes wie ASCII und ähnliches verwendet, bei dem man ein Zeichen wunderbar in einem Byte unterbringen konnte. Strings waren dann einfach Datenfelder bestehend aus solchen Zeichen. Man kann also jederzeit jedes beliebige Zeichen eines Strings adressieren und als einzelnen Character interpretieren.
    Dann kam Unicode und hat mehr Zeichen definiert, als in ein Byte passen. Das war aber immernoch kein Problem. Man verwendet statt einem Byte einfach zwei. Man kann auch einzelne Zeichen immernoch wunderbar adressieren.
    Doch dann wurden es noch mehr Zeichen und es gibt UTF-8, UTF-16 und UTF-32. Man könnte jetzt hingehen und Strings als Feld mit 4-Byte Elementen aufbauen und UTF-32 codiert arbeiten. Das würde aber sehr viel Platz verschwenden und passt auch nicht gut zu den Schnittstellen der Betriebssysteme (UTF-16 bei Windows, UTF-8 bei Linux, ...).
    Verwendet man aber die auf der Plattform übliche Codierung (also UTF-8 oder UTF-16) hat man das Problem, das man einzelne Zeichen nichtmehr gut verarbeiten kann (belegt das Zeichen jetzt ein, zwei oder drei Byte? Man muss den String tatsächlich linear durchlaufen, um das nte Zeichen zu finden, statt die Position berechnen zu können). Und wie soll man das Einzelne Zeichen dann Speichern? Als UTF-32, obwohl der String UTF-8 oder UTF-16 codiert ist?
    Sollte man Typen, die einzelne Zeichen speichern, komplett weglassen. Wenn man ein einzelnes Zeichen haben will ist es eben ein String, der aus nur einem Zeichen besteht. Dann könnten "einzelne Zeichen" problemlos UTF-8/16 kodiert bleiben.
    Oder sollte es mehrere String-Typen geben, einen UTF-8/16-codierten, um mit dem Betriebsystem zu kommunizieren und einen UTF-32 codierten, wenn man viel auf Zeichen-Ebene arbeiten will?



  • Vor dem gleichen Problem stand ich bei einem aktuellem Projekt. Ich hab mich für UTF-32 entschieden, da man entweder mehr RAM brauch oder eben für gewöhnliche Operationen, wie iterieren etc., mehr Rechenzeit opfern muss. Der Fontrenderer unterstützt UTF-32 auch direkt und deswegen war das kein Problem.

    Das std::basic_string-Interface ist leider nicht auf Multibytezeichensätze ausgelegt, so dass du dir mal glib::ustring oder ähnliches angucken solltest.



  • Helium schrieb:

    Sollte man Typen, die einzelne Zeichen speichern, komplett weglassen. Wenn man ein einzelnes Zeichen haben will ist es eben ein String, der aus nur einem Zeichen besteht. Dann könnten "einzelne Zeichen" problemlos UTF-8/16 kodiert bleiben.

    Imo sollten Typen für einzelne Zeichen bestehen bleiben. Für mich wäre es ziemlich heavy, wenn ich für ein einzelnes Zeichen extra 'nen String brauche. Erst recht, wenn dahinter noch dynamische Speicherallokierung oder ähnliches steht.



  • In Java und C# (im Visual C++ auch) wird es so gehandhabt, dass ein char (16 Bit) nicht gleichbedeutend mit einem Zeichen ist. Wenn ich aus einem String das n-te char heraushole, habe ich nicht zwangsläufig das n-te Zeichen, da manche Zeichen mit ein Paar von chars kodiert werden. (recht ausführliche Beschreibung)

    In der Praxis wird man allerdings fast nie in die Verlegenheit kommen, dass ein char für ein Zeichen nicht ausreicht und das einzige was dann nicht mehr wirklich korrekt arbeitet, ist der random acces. Bei der Textausgabe wird das wohl kein großes Problem sein, da der String dann sowieso sequentiell gelesen werden muss.

    Ich stimme groovemaster zu, es wäre extrem ineffizient, für jedes Zeichen einen Mini-String anzufertigen.

    Vermutlich wäre UTF-32 die beste Lösung, aber sehen wir es doch mal so: Die allermeisten Programme benutzen noch immer ISO-blabla Kodierung, ich wäre schon froh, wenn sie nur wenigstens UTF-8 benutzen würden, damit die Kodierung jedes Zeichens eindeutig ist. Und dagegen ist UTF-16 schon fast ein Gottesgeschenk, zumal es fast immer ausreicht, ich glaube, sogar japanisch ist damit kein Problem.



  • UTF-16 reicht sogar für japanisch, da UTF-16 Unicode ist. Ich schätze mal, nur die Chinesen brauchen mehr. 😉

    In C++ gibts doch std::wstring, da ist ein Zeichen 16bit groß. Kann man also auch gut benutzen. Unicode wird aber vom aktuellen C++ Standard leider nicht offiziell unterstützt, das soll aber im nächsten Standard verabschiedet werden, was auch Zeit wird.



  • UTF ist nicht Unicode, sondern eine Art, den Unicode zu implementieren. In UTF-16 kann genauso wie in UTF-8 oder UTF-32 jedes einzelne Unicode-Zeichen kodiert werden.
    Die Vor- und Nachteile dieser Verfahren ergeben sich aus dem Speicherbedarf und der unterschiedlichen Fähigkeit zum Random Acces auf ein bestimmtes Zeichen.

    btw. bin ich eigentlich der einzige, der das hier völligen Schrott findet?

    UTF-16 und UTF-32 werden deswegen [wegen dem Speicherbedarf] kaum noch verwendet. Sie wurden durch UTF-8 abgelöst.

    UTF-32 stellt jedes Unicode-Zeichen mit einem 4 Byte (32 Bit) langen Code dar. Das hat unter anderem den Vorteil, dass man schon an der Länge einer Zeichenkette erkennen kann, wieviele Unicode Codepoints enthalten sind. Das heißt nicht, dass die Anzahl der Zeichen feststeht, da manche Zeichen eine Kombination mehrerer Unicode Codepoints sind.

    Bei UTF-32 ?!!?



  • @Artchi
    Die größe von wchar_t ist nicht festgelegt. Unter Windows sind das in der Regel veraltete 16 Bit unter Unix (GCC) sind das 32 Bit. Das Problem ist, dass die C++ Standard Tools (basic_string,str*) nicht Multibyte-Zeichensatz kompatibel sind. Deswegen kann man ohne weiteres kein std::wstring für UTF-16 (oder UTF-8) nutzen.

    Das ist außerdem sehr problematisch für die portabilität. Ich hoffe mal im neuen C++ Standard kommen (a) Vorschriften für wchar_t = UCS-4 und (b) Mulitbyte Support.

    @Optimizer
    dann editier doch mal ein wenig 🙂



  • Jo, werd ich am WE mal machen. Ihr dürft es dann auseinandernehmen. 🙂


Anmelden zum Antworten