Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?
-
@SophiaL sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?
so:
bool isNullTerminated(const std::string &s) { return s[s.size()] == '\0'; }
Ausnahmsweise darf man bei std::string im geschlossenen Intervall
[0, size()]
indexieren statt wie sonst üblich im halboffenen Intervall[0, size()[
. Siehe https://en.cppreference.com/w/cpp/string/basic_string/operator_at.
-
@Finnegan Ich wollte eigentlich d'rauf hinaus, daß der bloße Zugriff undefined behaviour hat.
-
Wenn man weiss wie gross der Puffer ist, kann man prüfen ob im Puffer irgendwo ein NUL-Terminator ist. Kann man damit prüfen ob "der String" NUL-terminiert ist? Nicht unbedingt. Ich könnte einen 100 Zeichen Puffer haben und an Position 50 steht ein NUL Zeichen. Weiss ich jetzt dass "der String" NUL-terminiert ist? Nein, denn "der String" den irgendjemand reingeschrieben hat könnte auch nur 4 Zeichen lang und nicht terminiert sein. Ist also irgendwo Definitionssache was "der String" ist.
Oder anders gesagt: man kann nur prüfen ob ein Puffer terminiert ist, und das auch nur wenn man weiss wie gross er ist.
Der einzige Fall wo man prüfen kann ob "der String" NUL-terminiert ist ist, wenn man weiss wie lange "der String" ist, und dass der Puffer mindestens ein Zeichen länger ist.
ps: Und natürlich meine ich Code-Unit wenn ich "Zeichen" schreibe. Ich wollte eventuelle Anfänger die das lesen nur nicht noch mehr verwirren.
-
Was die Frage wie UTF-8 oder UTF-16 String terminiert sind angeht...
Na entweder gar nicht (wenn man mit nicht terminierten Strings arbeitet), oder wie jeder andere normale NUL-terminierte String auch: mit einer NUL Code-Unit. Wobei eine Code-Unit bei UTF-8 ein Byte lang ist, bei UTF-16 zwei Bytes und bei UTF-32 sind es dann 4 Bytes.
Das schöne bei UTF-8 und UTF-16 ist ja dass der Wertebereich der mittleren und hinteren Code-Units eingeschränkt ist und u.A. niemals 0 sein kann. D.h. wenn man eine Code-Unit mit Wert 0 liest, dann weiss man dass man am Ende angekommen ist. Und wenn noch Code-Units fehlen um die aktuelle Sequenz abzuschliessen, dann ist man trotzdem am Ende und hat einfach nur einen unvollständige Sequenz am Ende die man nicht dekodieren kann.
-
@Swordfish sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
@Finnegan Ich wollte eigentlich d'rauf hinaus, daß der bloße Zugriff undefined behaviour hat.
Verstehe. Liegt vielleicht daran, dass ich meistens in einer Welt programmiere, wo ich weiss, wie gross ein Speicherbereich ist, auf den ich ohne UB zugreifen darf - wenn mich nicht mal wieder irgendeine Lib zu was anderem zwingt
@hustbaer sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Ich könnte einen 100 Zeichen Puffer haben und an Position 50 steht ein NUL Zeichen. Weiss ich jetzt dass "der String" NUL-terminiert ist? Nein,
Zumindest kann man wissen dass man "einen String" hat, der nullterminiert ist - das ist auch schonmal was, wenn weiterer Code nur komische Werte produziert, statt an UB zu zerschellen
-
@Finnegan Ja, ich hab ja geschrieben "Ist also irgendwo Definitionssache was "der String" ist."
-
@Finnegan sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
@Belli sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Das brauchst Du nicht zu prüfen: wenn eine Folge von chars im Speicher nicht 0-terminiert ist, ist es kein String.
Umgekehrt: Ein (C-)String ist immer nullterminiert, weil es sonst kein (C-)String ist.Du weisst schon, dass die Realität oft nicht so schön wohldefiniert und widerspruchsfrei wie die mathematische Theorie ist, oder? Dann ist die Aufgabe eben: "Prüfen Sie, ob die char-Folge ein C-String ist".
Ja, es kommt halt auf jedes Wort an, so wie SeppJ immer so schön betont, bei einem Programm auf jedes Zeichen.
Ich weiß natürlich was Du meinst, so wie Du auch weißt, was ich meine, trotzdem halte ich es für riskant, die Aufgabenstellung so anzupassen, dass eine gefundene 'Lösung' richtig ist.
Wer sagt denn, dass der Aufgabensteller nicht genau die Antwort haben will, die ich gegeben habe?Deshalb vielleicht:
@Swordfish sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Vielleicht sollten wir warten bis sich @SophiaL wieder meldet und dann hoffentlich die KONKRETE AUFGABE preisgibt.
-
@Swordfish sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Und ja, ein Zeichen in UTF-16 ist mindestens 16 bit breit.
Mindestens, oder exakt?
Ich dachte bisher, nur bei UTF8 können Zeichen unterschiedliche Bitbreiten haben.
-
@A-Grau sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
@Swordfish sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Und ja, ein Zeichen in UTF-16 ist mindestens 16 bit breit.
Mindestens, oder exakt?
Ich dachte bisher, nur bei UTF8 können Zeichen unterschiedliche Bitbreiten haben.Mindestens. Eine Code-Unit von UTF-16 hat exakt 16 Bit, und ein Code-Point kann aus einer oder Zwei Code-Units bestehen (Stichwort Surrogate-Pairs). Weiters kann aber auch ein "Zeichen" (Glyph) aus mehreren Code-Units bestehen (Stichwort Combining Diacritics).
-
@Ein-ehemaliger-Benutzer sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
@Swordfish sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Und ja, ein Zeichen in UTF-16 ist mindestens 16 bit breit.
Mindestens, oder exakt?
Ich dachte bisher, nur bei UTF8 können Zeichen unterschiedliche Bitbreiten haben.Falsch gedacht - und ein häufiges Missverständnis. Mindestens! Das kannst du dir auch leicht überlegen, denn es gibt aktuell ca 250.000 Code Points (siehe https://www.unicode.org/versions/Unicode6.2.0/appD.pdf#page=3), ein 16-Bit-Wert kann aber nur verschiedene Werte darstellen.
Lies mal https://utf8everywhere.org/ - Zitat:
UTF-16 is often misused as a fixed-width encoding, even by the Windows package programs themselves: in plain Windows edit control (until Vista), it takes two backspaces to delete a character which takes 4 bytes in UTF-16. On Windows 7, the console displays such characters as two invalid characters, regardless of the font being used.
Du bist also nicht allein mit dieser Fehlannahme.