Verständnisproblem \0 bei Stringfunktionen, beachten oder nicht?
-
Hallo,
Ich habe Verständnisprobleme mit dem Stringterminierungszeichen.
Wenn ich sowas habe:
char buf[] = "Hallo Forum"; char buf2[strlen(buf)+1];
Muss ich jetzt:
strncpy(buf2, buf, strlen(buf));
oder
strncpy(buf2, buf, strlen(buf)+1);
Ich habe allgemein Probleme, weil ich nie weiss, ob ich das \0 beachten soll oder nicht. Wenn ich eine Zeichenkette in eine andere Zeichenkette kopiere, kann ich das \0 "abschneiden", weil die andere (wo es hinkopiert wird) Zeichenkette am Schluss ein \0 hat, oder?
Vielleicht habt ihr mir ja eine Denkhilfe, oder Eselsbrücke o.Ä.
!!! Herzlichen Dank !!!
TrollToll
-
Die str*-Funktionen lesen ihren String immer höchstens bis zur Ende-Marke \0. Die Länge, die Du bei strncpy angibst, ist nur eine Maximallänge. Wenn "buf" sowieso bereits vorher ein \0 Zeichen enthält, hört strncpy auf zu kopieren (kopiert das \0 Zeichen aber noch mit).
Anders gesagt: Wenn Du mit strncpy angibst 20 Zeichen zu kopieren, der Quellstring aber nur 10 Zeichen lang ist, bis die Terminierung auftaucht, kopiert strncpy genau 11 Bytes (10 Zeichen + Nullbyte). Wenn Du allerdings angibst, 20 Zeichen zu kopieren, der Quellstring aber 50 Zeichen lang ist, dann wird vorher abgebrochen und auch keine Nullterminierung geschrieben.
Zu Deinem Beispiel:
Die erste Form kopiert ein Zeichen zu wenig, und zwar das Nullzeichen. Da strncpy annimmt, im Buffer buf2 seien strlen(buf) Zeichen Platz, und da buf strlen(buf) Zeichen lang ist, wird strncpy das Nullbyte nicht kopieren.
Die zweite Form macht es hingegen genau richtig.
Der Sinn hinter dem Längenparameter bei strncpy ist aber eigentlich, die Länge des Zielpuffers zu übergeben, nicht die des Quellstrings.
-
Danke für die gute Beschreibung!!
-
Wenn ich das richtig verstanden habe müsste man die Strings dann so kopieren, damit man auf der sicheren Seite ist?
char ziel[128]; char *quelle; strncpy(ziel, quelle, sizeof(ziel)); ziel[sizeof(ziel) -1] = 0;