Moin moin,
ich fange gerade an, Multibyte Zeichen zu verwenden, um endlich Unicode in meine Programme rein zu bekommen. Nun frage ich mich aber, wie ich prüfen kann ob bei einem wchar_t String ein Terminierungszeichen vorhanden ist. Hier mein Beispiel:
Aramis hat geschrieben:Naja, auch bei Verwendung eines std::wstring's wäre es hilfreich zu wissen wie der Terminator genau aussieht ... :-)
Warum? Wenn man String-Literale in den Code einbaut, fügt der Compiler den Terminator automatisch an. Will man die Länge oder Größe eines Strings wissen, benutzt man ::std::wstring::length(). Will man formatieren, benutzt man den operator += (), oder, für Komplexeres, ::std::wstringstream. Ich sehe nirgends einen Grund, sich mit dem Terminator zu befassen, außer vielleicht Neugierde.
Nun, ein std::string kann auch mitten drin Terminator enthalten. Das wird in der Praxis sogar hin und wieder verwendet, zB bei den doppel nullterminierten Stringlisten.
Zunächst einmal sind Doppelnuller echte Fossilien, mit denen heute kaum noch jemand zu tun haben wird, wenn man nicht gerade direkt am Kernel werkelt ;)
Weiterhin sind doppelt nullterminierte Strings keine Strings, in denen mittendrin ein paar Nullen auftauchen, sondern Arrays von Strings, die mit einem leeren String abschließen (also zufälligerweise zwei Nullen enthalten). Man hat dort also genauso wenig auf einen Terminator zu prüfen wie überall auch, sondern stattdessen, ob die Länge eines Sub-Strings 0 ist.
Krishty hat geschrieben:Zunächst einmal sind Doppelnuller echte Fossilien, mit denen heute kaum noch jemand zu tun haben wird, wenn man nicht gerade direkt am Kernel werkelt ;)
Weiterhin sind doppelt nullterminierte Strings keine Strings, in denen mittendrin ein paar Nullen auftauchen, sondern Arrays von Strings, die mit einem leeren String abschließen (also zufälligerweise zwei Nullen enthalten). Man hat dort also genauso wenig auf einen Terminator zu prüfen wie überall auch, sondern stattdessen, ob die Länge eines Sub-Strings 0 ist.
Es kann aber auch sein, daß man aufgrund einer nicht ganz so defensiven Programmierung versehentlich '\0' von einem Anwender des Codes irgendwo in den String eingefügt wurde. Dann stimmt plötzlich die Länge nicht mehr, da size() bz. lenght() jeweils nach '\0' sucht und der String als zu kurz angesehen wird ( nicht aber die capacity ). Das ist dann keine Absicht, aber als Fehler nicht auf Anhieb zu erkennen. Anders formuliert: ich hatte das schon :).
Du redest jetzt aber nicht mehr von std::string oder wstring, oder? Die speichern die Länge nämlich intern und haben absolut kein Problem mit Nullchars im String. Wär ja noch schlimmer, wenn die bei jedem Aufruf von length() wieder die Bytes durchzählen.
Doch, allerdings habe ich hier gezwungendermaßen eine ältere STL-Version vorliegen. Da sah ich das Phänomen. Allerdings kann es durchaus sein, daß der String unter der Hand noch wo umkopiert wurde, nachdem der '\0'-Terminierer eingebaut wurde ( das geschah per []-Operator ). Ich hatte an dem Gerät keinen Debugzugriff, um das durchzusteppen. Ich schau mal in die Implementierung, wie die das regeln.
Krishty hat geschrieben:Zunächst einmal sind Doppelnuller echte Fossilien, mit denen heute kaum noch jemand zu tun haben wird, wenn man nicht gerade direkt am Kernel werkelt ;)
Ja, aber mit wchar_t und wstring hat das nichts zu tun. Interessant wird der Terminator z.b. sobald man den String mal den String als allgemeine Byte-Daten betrachten muss, weil man ihn binaer auf Platte speichert oder ueber Netzwerk verschickt. f'`8k
Krishty hat geschrieben:Zunächst einmal sind Doppelnuller echte Fossilien, mit denen heute kaum noch jemand zu tun haben wird, wenn man nicht gerade direkt am Kernel werkelt ;)
Weiterhin sind doppelt nullterminierte Strings keine Strings, in denen mittendrin ein paar Nullen auftauchen, sondern Arrays von Strings, die mit einem leeren String abschließen (also zufälligerweise zwei Nullen enthalten). Man hat dort also genauso wenig auf einen Terminator zu prüfen wie überall auch, sondern stattdessen, ob die Länge eines Sub-Strings 0 ist.
Naja, dass doppelt nullterminierte Strings Arrays von Strings sind wage ich doch sehr zu bezweifeln, aber du meinst sicher das richtige.:) Aber auch wenn ein doppelt-nulterminierter String nicht immer mit zwei Nullen endet kann man sowas in einem std::string speichern, wenn man will. Und dann muss man sehr wohl auf Terminator prüfen. Und es gibt eigentlich noch recht viele APIs, die sowas erwarten..
Helmut hat geschrieben:Naja, dass doppelt nullterminierte Strings Arrays von Strings sind wage ich doch sehr zu bezweifeln, aber du meinst sicher das richtige.:)
Da bin ich mir irgendwie nicht mehr sicher ;) Kannst du mir genau erklären, was du unter doppelt nullterminierten Strings verstehst? Ich habe mich bis jetzt vor allem auf diese Erklärung gestützt („think of it as a packed array of null-terminated strings, with a zero-length string as the terminator“).
Helmut hat geschrieben:[…] auch wenn ein doppelt-nulterminierter String nicht immer mit zwei Nullen endet […]
Helmut hat geschrieben:[…] auch wenn ein doppelt-nulterminierter String nicht immer mit zwei Nullen endet […]
Woher dann der Name?
Wenn du nicht schon den Link in deinem eigenen Beitrag hättest würde ich ihn jetzt posten ;) Da steht doch gerade drin, dass nicht jeder "Doppelnuller" (cooler Name;)) mit zwei Nullen endet. Der Name rührt schlicht und einfach daher, dass eine korrekte Formulierung viel zu lange ist.
Zum Thema Arrays, da hast du das Wort "packed" vergessen ;) Ein Array von C-Strings wäre char* bla[]. Also nur falsch formuliert, wie ich schon vermuttet hatte.