Wie stelle ich sicher, dass die Zeichenfolge 'a' ist null terminiert? wenn a = "abcd" und ich sizeof (a), bekomme ich 4. Bedeutet das, dass es nicht nullterminiert ist? wenn es so wäre, hätte ich 5 bekommen?sizeof für eine Null abgeschlossen const Char *
Antwort
Wenn Sie ein char-Array übergeben werden, das möglicherweise null-terminierte Daten enthält, gibt es wirklich keine gute Möglichkeit, dies zu überprüfen. Das Beste, was Sie tun können, ist die Suche nach einem Nullzeichen bis zu einer bestimmten Länge (nicht unbegrenzt!). Aber 0 ist nicht gerade ein ungewöhnliches Datenbyte, das in einem nicht initialisierten Speicherbereich zu finden ist.
Dies ist eines der vielen Dinge über C Defacto String-Standard, die viele Menschen nicht mögen. Wenn Sie die Länge einer Zeichenfolge ermitteln, die ein Client Ihnen übergibt, ist dies im besten Fall eine O (n) -Suchoperation und im schlimmsten Fall eine Segmentierungsstörung.
Ein weiteres Problem ist natürlich, dass Arrays und Zeiger austauschbar sind.Das bedeutet array_name + 2
ist das gleiche wie &(array_name[2])
und sizeof(a)
ist sizeof(char*)
, nicht die Länge des Arrays.
Sie erhalten 4
, weil das die Größe eines Zeigers auf Ihrem System ist. Wenn Sie die Länge einer Null-terminierten Zeichenfolge erhalten möchten, möchten Sie die Funktion strlen
in der C-Standardbibliothek verwenden.
sizeof(a)
gibt Ihnen die Größe des Zeigers, nicht des Arrays von Zeichen, auf die der Zeiger zeigt. Es ist das gleiche wie wenn Sie sizeof(char*)
gesagt hätten.
Sie müssen strlen()
verwenden, um die Länge eines nullterminierten String zu berechnen (beachten Sie, dass die Länge zurück nicht den Null-Terminator enthalten, so strlen("abcd")
4, nicht 5). Oder können Sie ein Array mit dem Stringliteral initialisieren:
char a[] = "abcd";
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer
Die Stringliteral "abcd"
ist null beendet; Alle String-Literale sind null-terminiert.
Das OP hat bereits 'const' benutzt, daher ist' const char a [] 'wahrscheinlich eine bessere Idee als' char a [] '. – aschepler
Um weiter zu klären, gibt 'strlen()' nur die logische Länge der Daten im char-Array an, nicht die Anzahl der dafür zugewiesenen Bytes. Ich glaube nicht, dass es einen Weg gibt, diese Nummer zu bekommen. –
sizeof(a)
ist sizeof(const char*)
, die Größe des Zeigers. Es wird nicht durch den Inhalt von a
beeinflusst. Dafür wollen Sie strlen
.
Außerdem sind alle String-Literale mit doppeltem Anführungszeichen wie "abcd"
im Quellcode automatisch null-terminiert.
sizeof (a) gibt die Größe des const char *a
zurück ... nicht die Größe dessen, auf das es zeigt. Sie können strlen(a)
verwenden, um die Länge der nullterminierten Zeichenfolge zu ermitteln, und nein, das Ergebnis von strlen enthält den Nullterminator nicht.
Das Problem hier ist, dass Sie sizeof()
verwirren, die eine Kompilierzeitoperation mit der Länge einer Zeichenfolge ist, die eine Laufzeitoperation ist. Der Grund erhalten 4 zurück, wenn Sie sizeof(a)
ausführen, ist, dass a
ist ein Zeiger und die typische Größe eines Zeigers in C ist 4 Bytes. Um die Länge der Zeichenfolge zu erhalten, verwenden Sie strlen
.
Für die zweite Frage, wie Sie sicherstellen, dass eine Zeichenfolge null terminiert ist. Die einzige Möglichkeit, dies definitiv zu tun, besteht darin, die Zeichenfolge selbst zu beenden. Bei nur char*
gibt es keine Möglichkeit, zu 100% zu garantieren, dass es ordnungsgemäß null terminiert ist. Es muss sehr sorgfältig darauf geachtet werden, dass der Vertrag zwischen dem Hersteller und dem Verbraucher der Nummer char*
dahingehend verstanden wird, wer die Zeichenfolge beendet.
aah .... dumm mich. Aber wenn ich strlen (a) bekomme ich 4, und ich weiß, dass ein "abcd" (von gdb) hat. – hari
@hari, 4 ist korrekt, da die Länge der Zeichenfolge "abcd" tatsächlich 4 ist. Die Speicheranforderungen für "a" sind jedoch "strlen (a) + 1", um den Nullabschluss zu verarbeiten. Dies ist einer der Teile von C, die nur ein bisschen gewöhnungsbedürftig sind. – JaredPar
Das liegt daran, dass die Länge von "abcd" 4 ist. Strlen zählt den Null-Terminator nicht. – jer
- 1. C++ nicht null abgeschlossen Char-Array Ausgabe
- 2. C sizeof char * array
- 3. const char & als Argument für eine Funktion
- 4. sizeof Operator gibt 4 für (char + short)
- 5. C: „static const char * const“ auf „static const char *“
- 6. Warum gibt sizeof (char + char) 4 zurück?
- 7. const (char) * kann nicht
- 8. Kompilierzeichenfolgen: Konstruktorüberladung Vorrang zwischen 'const char * `/` const char [] `
- 9. ungültige Konvertierung von 'const char *' in 'char *'
- 10. Unterschied zwischen statischem const char * und const char *
- 11. Unterschied zwischen const char * p und char const * p
- 12. const char * Initialisierung
- 13. printf% s const char *
- 14. Pass char * zu const char * in c
- 15. const constexpr char * vs. constexpr char *
- 16. const char * Verkettung
- 17. Convert int const char *
- 18. C++: Bedeutung der const char * const *
- 19. nsstring und const char * conversion
- 20. Convert Typ „char **“ auf „const char **“
- 21. Cython wie man char ** in const char ** umwandelt?
- 22. C++: Größe eines char Array sizeof
- 23. convert BSTR zu const char *
- 24. ungültige Umwandlung const unsigned char
- 25. kann 'std :: basic_string <char>' zu 'const char *' für Argument '1' nicht zu 'int System (const char *)'
- 26. Login mit SQLite in C++ [Fehler] kann 'bool' nicht konvertieren zu 'const char *' für Argument '1' zu 'int strcmp (const char *, const char *)'
- 27. Convert CString zu const char *
- 28. initialisieren static char * const somevar
- 29. Const Char Verkettung und getenv()
- 30. Bedeutung von "char * _EXFUN (index, (const char *, int));"
'strnlen' für die Sicherheit. – nmichaels
'strnlen' ist plattformspezifisch, nicht im Standard. – jer
@Nathon: 'strnlen' fügt nicht wirklich Sicherheit hinzu, oder? Wenn für Ihre Funktion eine nullterminierte Zeichenfolge erforderlich ist und keine Zeichenfolge abgerufen wird (oder wenn eine Funktion als null-terminierte Zeichenfolge zurückgegeben wird und keine zurückgegeben wird), ist der Code bereits ungültig. –