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?
-
Das kannst Du nicht prüfen. Das ist eine Konvention, genannt C-String oder sz-String (String Zero-terminated). Da Du im C++-Forum postest nimm
std::string
.ein String
... welcher Form im Programm?
-
@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?
Deutsch: Meine Hausaufgabe ist ...
-
Ich bin zwar kompletter C++ Anfänger haber in meinem Kurs gerade eben den char-array gehabt.
Wenn du mit Visual Studio arbeitest und ein solches char array erstellst und auf den Text fährst siehst
du das immer ein char mehr vorhanden ist als das was du siehst.
Laut meinem Kursleiter ist es wie sword sagt eine Konvention ein sz-String, und mit dem Zählen in VS
ist nach meinem Kursleiter hinreichend bewiesen dass Strings und char-arrays immer mit dem \0 enden.Weiß nicht ob dir das weiterhilft, laut meinem Kursleiter ist das einfach da.
-
Vielleicht hilft dir auch das weiter
Link Text
-
@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?
vorschlag: Bau die strlen()-Funktion nach. Alle Zeichen abklappern bis eine 0 kommt. Gibt es enen Zugriffsfehler, weil du hinter dem string lesen wolltest, fehlt die Null.
-
@A-Grau
Das wird nicht funktionieren.Annahme ich habe einen ASCII String "Hallo" und einen UTF-16 String L"Hallo" hintereinander im Speicher stehen. Beide sind nicht nullterminiert.
Würde ich hier einen strlen Ansatz fahren, so würde er den ASCII String durchlaufen und beim UTF-16 String weitermachen. Bei UTF-16 sind aber Zeichen 2 Byte groß und so manches Zeichen beginnt mit einem Nullbyte. Dein Algorithmus würde dieses Nullbyte finden und für den ASCII String Nullterminiert ausgeben, was falsch ist.
-
@A-Grau sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Gibt es enen Zugriffsfehler, weil du hinter dem string lesen wolltest, fehlt die Null.
Ja nee. Undefined behaviour ist ... trommelwirbel ... undefined.
Aber, hey, wenn es für Dich "funktioniert" wird es schon passen.
-
@Quiche-Lorraine Du hast Recht. An UTF hab ich gar nicht gedacht. womit sind denn UTF8-Strings terminiert? Oder gibts da keine Terminierung?
Bei UTF16 hat man oft 2 null-Bytes hintereinander als Ende-Kennung.
Aber es ist doch eher ungewöhnlich, das mehrere String-Typen nebeneinander verwendet werden.
-
@A-Grau sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
womit sind denn UTF8-Strings terminiert?
ASCII
'\0'
ist auch in jedem UNICODE-Encoding0
. Und ja, ein Zeichen in UTF-16 ist mindestens 16 bit breit.
-
@SophiaL
Ich nehme an, Du sprichst von einem sogenannten C-String - sonst macht die Frage wenig Sinn ...
Also:
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.
-
@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".
-
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?:
Vielleicht sollten wir warten bis sich @SophiaL wieder meldet und dann hoffentlich die KONKRETE AUFGABE preisgibt.
Schon klar. ich finde es nur verwunderlich, dass sich hier ein paar so an deiser C-String-Konvention festgebissen haben. Ich finde es völlig klar, dass hier nach einem Programm gefragt ist, das prüft, ob der Speicherbereich einen 0-Char enthält, bevor dieser zuende ist und nicht nach einem mathematischen Beweis mit klaren Definitionen. Wann konnte man sich schonmal bei Software darauf verlassen, dass sie bugfrei ist, und solche Konventionen immer eingehalten werden?
-
@A-Grau sagte in Wie sieht ein Programm aus, das prüft, ob ein String tatsächlich mit einem \0-Zeichen terminiert ist?:
Aber es ist doch eher ungewöhnlich, das mehrere String-Typen nebeneinander verwendet werden.
Warum?
Es spielt aber auch keine Rolle. Die Bytes hinter einem String sind per se undefiniert. Es könnte ein weiterer String, ein double Wert oder eine Adresse gespeichert sein. Und sobald diese ein Nullbyte enthalten zeigt dein Algo ein Fehler an. Und selbst bei freiem Speicher ist es undefiniert.
Kleiner Tipp: Probiere es mal selbst aus. Lege den Zeiger auf einen int32_t, initialisiere den Int Wert mit 0xAABBCCDD und suche dann dein Nullbyte. Ich wette du stößt relativ schnell auf ein Nullbyte.
-
@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