Wie der Titel schon sagt, ist meine Frage, wie ich die Größe einer Zeichenfolge eingeben kann C
. Ist es gut zu verwenden sizeof
wenn ich es (die Zeichenfolge) in einer Funktion ohne deklariert habe malloc
drin? Oder wenn ich es als Zeiger deklariert habe? Was wäre, wenn ich es mit initialisiert hätte? malloc
? Ich hätte gerne eine erschöpfende Antwort.
Wie bekomme ich die Stringgröße in Bytes?
artaxerxe
nmichailow
Sie können verwenden Strlen. Die Größe wird durch das abschließende Nullzeichen bestimmt, daher sollte die übergebene Zeichenfolge gültig sein.
Wenn Sie die Größe des Speicherpuffers erhalten möchten, der Ihre Zeichenfolge enthält, und Sie einen Zeiger darauf haben:
- Wenn es sich um ein dynamisches Array handelt (mit malloc erstellt), ist es unmöglich, die Größe zu ermitteln, da der Compiler nicht weiß, auf welchen Zeiger zeigt. (Überprüfen Sie dies)
- Wenn es sich um ein statisches Array handelt, können Sie verwenden
sizeof
seine Größe zu bekommen.
Wenn Sie über den Unterschied zwischen dynamischen und statischen Arrays verwirrt sind, überprüfen Sie dies.
-
Eigentlich ist Größe
strlen()+1
(1 für Abschlusszeichen)– Agnius Vasiliauskas
21. Februar 2013 um 11:16 Uhr
-
@0x69 Die Größe von a Schnur wird normalerweise so definiert, dass das Null-Terminator ausgeschlossen wird.
– Bernhard Barker
21. Februar 2013 um 11:18 Uhr
-
@modifiablelvalue Die Implikation war – es ist unmöglich, die Größe direkt aus dem dynamischen Array abzurufen. Natürlich kann man die Größe speichern, aber darum geht es nicht.
– Bernhard Barker
21. Februar 2013 um 11:37 Uhr
-
@artaxerxe: C definiert, dass a
char
ist 1 Byte, aber es definiert nicht, dass ein Byte 8 Bits ist. Also, das stimmt zwarchar
ist für C immer ein Byte, es ist nicht unbedingt ein Oktett, und ein Großteil der Welt außerhalb des C-Standards denkt, dass “Byte” “Oktett” bedeutet. C-Implementierungen auf denenchar
größer als 8 Bit sind in der Minderzahl, beinhalten aber viele DSPs. Viele “portable” Codes laufen aus verschiedenen Gründen sowieso nicht auf DSPs, also müssen Sie entscheiden, ob Sie davon ausgehen möchten, dass ein Byte 8 Bits hat. Der WertCHAR_BIT
sagt es dir mit Sicherheit.– Steve Jessop
21. Februar 2013 um 11:47 Uhr
-
@Dukeling Hm … Dann kopiere
strlen()
Byte mitmemcpy
in einen anderen (nicht leeren) Puffer und drucke ihn. Was Sie sehen werden, ist Ihre neue Zeichenfolge + Müll. Dies ist für mich ein Argument, dass die Zeichenfolgengröße in Bytes iststrlen()+1
. (Allerdings Schnur Länge iststrlen()
).– Agnius Vasiliauskas
21. Februar 2013 um 16:54 Uhr
Bernhard Bärker
Verwenden strlen
um die Länge von a zu erhalten nullterminierte Zeichenfolge.
sizeof
gibt die Länge der zurück Reihe nicht die Saite. Wenn es ein Zeiger ist (char *s
), kein Array (char s[]
), funktioniert es nicht, da es die Größe des Zeigers zurückgibt (normalerweise 4 Bytes auf 32-Bit-Systemen). Ich glaube, ein Array wird als Zeiger übergeben oder zurückgegeben, sodass Sie die Verwendung verlieren würden sizeof
um die Größe des Arrays zu überprüfen.
So, nur wenn die Zeichenfolge das gesamte Array umfasst (z.B char s[] = "stuff"
), würde verwenden sizeof
Für ein statisch definiert array zurückgeben, was Sie wollen (und schneller sein, da es nicht durchlaufen müsste, um das Null-Terminator zu finden) (wenn das letzte Zeichen ein Null-Terminator ist, müssen Sie 1 subtrahieren). Wenn es nicht das gesamte Array umfasst, wird es nicht das zurückgeben, was Sie wollen.
Eine Alternative zu all dem ist das tatsächliche Speichern der Größe der Zeichenfolge.
-
Beachten Sie, dass
sizeof
gibt Ihnen nicht wirklich die Länge einer Zeichenfolge. Für ein Zeichenfolgenliteralsizeof
enthält das Null-Terminator. Für eine Reihe vonchar
,sizeof
gibt Ihnen die Anzahl der Elemente im Array (was eine unvorhersehbare Menge größer ist als eine Zeichenfolgenlänge des Inhalts des Arrays)– Simonc
21. Februar 2013 um 11:08 Uhr
-
Es kann sinnvoll sein, darauf hinzuweisen
strlen
undsizeof
zurück zwei grundlegend verschiedene Dinge.– alk
21. Februar 2013 um 11:09 Uhr
-
Die Größe eines Zeigers ist nicht immer 4 Bytes auf einem 32-Bit-System. Überlegen Sie, ob CHAR_BIT 32-Bit ist. Überlegen Sie außerdem, ob ein 16-Bit-Betriebssystem und ein Compiler auf diesem 32-Bit-System leben. CHAR_BIT kann auf 16-Bit-Betriebssystemen und -Hardware immer noch 32 Bit sein. Die Größe des Zeigers ist eine Entscheidung des Compilers, NICHT des Betriebssystems oder der Hardware. Wenn der Compiler dieselbe Größe wie das Betriebssystem oder die Hardware verwendet, ist dies die Wahl des Compilers. Außerdem können unterschiedliche Zeiger unterschiedliche Größen haben.
– autistisch
21. Februar 2013 um 11:32 Uhr
-
@modifablelvalue „immer“ in „normalerweise“ geändert.
– Bernhard Barker
21. Februar 2013 um 11:40 Uhr
Hyde
Während sizeof
funktioniert für diese bestimmte Art von Zeichenfolge:
char str[] = "content";
int charcount = sizeof str - 1; // -1 to exclude terminating '\0'
Es funktioniert nicht, wenn str
ist Zeiger (sizeof
gibt die Größe des Zeigers zurück, normalerweise 4 oder 8) oder ein Array mit angegebener Länge (sizeof
gibt die Byteanzahl zurück, die der angegebenen Länge entspricht, die für den Typ char gleich sind).
Benutz einfach strlen()
.
-
Da str in Ihrem Beispiel ein Typname ist, sollte er nicht in Klammern gesetzt werden?
– Widderläufer
12. Dezember 2014 um 23:03 Uhr
-
@ramrunner
str
ist Variablenname. Es ist also ein Arraysizeof str
gibt die Größe des gesamten Arrays in Bytes zurück. Wenn ein Array wie oben deklariert wird, ist die Arraygröße genau die Größe des Zeichenfolgenliterals einschließlich der Beendigung'\0'
. Undsizeof
hat einen höheren Vorrang als-
Alsosizeof str
benötigt keine Klammern, obwohl das Hinzufügen zur Verdeutlichung hier nicht schlecht wäre, gebe ich zu.– Hyde
13. Dezember 2014 um 8:13 Uhr
Wenn du benutzt sizeof()
dann ein char *str
und char str[]
wird unterschiedliche Antworten zurückgeben. char str[]
gibt die Länge der Zeichenfolge (einschließlich des Zeichenfolgenabschlusszeichens) zurück, während char *str
gibt die Größe des Zeigers zurück (je nach Compiler unterschiedlich).
A.Clymer
Ich verwende gerne:
(strlen(string) + 1 ) * sizeof(char)
Dadurch erhalten Sie die Puffergröße in Bytes. Sie können dies mit snprintf() unterstützen:
const char* message = "%s, World!";
char* string = (char*)malloc((strlen(message)+1))*sizeof(char));
snprintf(string, (strlen(message)+1))*sizeof(char), message, "Hello");
Prost! Funktion: size_t strlen (const char *s)
-
(1)
strlen()
gibt immer die Länge in Bytes zurück, Multiplikation mit 1 fügt nichts hinzu; (2) Es darf keine Beziehung zwischen der Größe des Puffers und der Länge der darin enthaltenen Zeichenkette geben; (3) Haben Sie versucht, diesen Code zu kompilieren?– Krähenmann
30. Dezember 2015 um 4:28 Uhr
-
(1) Nicht mit eins multipliziert (2) Ich ordne Bytes für einen Zeiger zu, also verwende ich die Zeichenfolgenlänge * Größe eines Zeichens (Inbytes) (3) Ich benutze es die ganze Zeit.
– A.Clymer
6. Januar 2016 um 7:18 Uhr
-
Wenn Sie einen Ruf aufbauen möchten, müssen Sie dies tun, indem Sie gute Antworten geben. Die letzte Bearbeitung beseitigt zumindest die vorherigen Fehler, aber jetzt ist es nicht einmal eine Antwort, sondern ein Kommentar. Alle anderen Antworten beziehen sich beide auf
strlen()
und geben Sie eine aussagekräftige Erklärung ab, dies ist einfach keine positive Antwort.– Krähenmann
26. Februar 2016 um 20:03 Uhr
-
Ich werde die Ablehnung gerne entfernen, wenn Sie eine anständige Antwort hinterlassen. Wenn Sie eine gute Antwort hinterlassen, werde ich sie gerne abstimmen. Ihr Originalcode würde auf keinem C-Compiler kompiliert werden, weder eingebettet noch anderweitig.
– Krähenmann
26. Februar 2016 um 20:11 Uhr
-
Es enthält nicht den anstößigen Code aus Ihrer ursprünglichen Antwort, daher ist es für den Punkt irrelevant.
1/2
ist immer null. Hör auf, meine Zeit mit diesem Unsinn zu verschwenden.– Krähenmann
26. Februar 2016 um 20:30 Uhr
Es gibt zwei Möglichkeiten, die String-Größe Bytes zu finden:
1. Lösung:
# include <iostream>
# include <cctype>
# include <cstring>
using namespace std;
int main()
{
char str[] = {"A lonely day."};
cout<<"The string bytes for str[] is: "<<strlen(str);
return 0;
}
2. Lösung:
# include <iostream>
# include <cstring>
using namespace std;
int main()
{
char str[] = {"A lonely day."};
cout<<"The string bytes for str[] is: "<<sizeof(str);
return 0;
}
Beide Lösung herstellt verschiedene Ausgänge. Ich werde es Ihnen erklären, nachdem Sie diese gelesen haben.
Die 1. Lösung verwendet strlen
und basierend auf cplusplus.com,
Die Länge eines C-Strings wird durch das abschließende Null-Zeichen bestimmt: AC-String ist so lang wie die Anzahl der Zeichen zwischen dem Anfang des Strings und dem abschließenden Nullzeichen (ohne das abschließende Nullzeichen selbst einzuschließen).
Das kann erklären, warum die 1. Lösung die Bytes der richtigen Zeichenfolgengröße druckt, wenn die 2. Lösung die Bytes der falschen Zeichenfolgengröße druckt. Aber wenn Sie immer noch nicht verstehen, dann lesen Sie weiter.
Die 2. Lösung verwendet sizeof
um die Zeichenfolgengröße in Bytes herauszufinden. Basierend auf dieser SO-Antwort heißt es (geändert):
sizeof("f")
muss 2 Bytes der Zeichenfolgengröße zurückgeben, eines für das ‘f’ und eines für das abschließende ‘\0’ (beendendes Nullzeichen).
Aus diesem Grund ist die Ausgabe Bytes der Zeichenfolgengröße 14. Eine für die gesamte Zeichenfolge und eine für ‘\0’.
Fazit:
Um die richtige Antwort für die 2. Lösung zu erhalten, müssen Sie dies tun sizeof(str)-1
.
Verweise:
- Sizeof-String-Literal
- https://cplusplus.com/reference/cstring/strlen/?kw=strlen
-
(1)
strlen()
gibt immer die Länge in Bytes zurück, Multiplikation mit 1 fügt nichts hinzu; (2) Es darf keine Beziehung zwischen der Größe des Puffers und der Länge der darin enthaltenen Zeichenkette geben; (3) Haben Sie versucht, diesen Code zu kompilieren?– Krähenmann
30. Dezember 2015 um 4:28 Uhr
-
(1) Nicht mit eins multipliziert (2) Ich ordne Bytes für einen Zeiger zu, also verwende ich die Zeichenfolgenlänge * Größe eines Zeichens (Inbytes) (3) Ich benutze es die ganze Zeit.
– A.Clymer
6. Januar 2016 um 7:18 Uhr
-
Wenn Sie einen Ruf aufbauen möchten, müssen Sie dies tun, indem Sie gute Antworten geben. Die letzte Bearbeitung beseitigt zumindest die vorherigen Fehler, aber jetzt ist es nicht einmal eine Antwort, sondern ein Kommentar. Alle anderen Antworten beziehen sich beide auf
strlen()
und geben Sie eine aussagekräftige Erklärung ab, dies ist einfach keine positive Antwort.– Krähenmann
26. Februar 2016 um 20:03 Uhr
-
Ich werde die Ablehnung gerne entfernen, wenn Sie eine anständige Antwort hinterlassen. Wenn Sie eine gute Antwort hinterlassen, werde ich sie gerne abstimmen. Ihr Originalcode würde auf keinem C-Compiler kompiliert werden, weder eingebettet noch anderweitig.
– Krähenmann
26. Februar 2016 um 20:11 Uhr
-
Es enthält nicht den anstößigen Code aus Ihrer ursprünglichen Antwort, daher ist es für den Punkt irrelevant.
1/2
ist immer null. Hör auf, meine Zeit mit diesem Unsinn zu verschwenden.– Krähenmann
26. Februar 2016 um 20:30 Uhr
Aus Ihrer Frage geht nicht hervor, ob Sie die Größe der “Zeichenfolge” oder die Größe des Zeichen-Arrays / Speicherblocks mit der “Zeichenfolge” wissen möchten.
– alk
21. Februar 2013 um 11:10 Uhr
@alk Bearbeitet. Hoffe, klarer zu sein. Vielen Dank.
– artaxerxe
21. Februar 2013 um 11:16 Uhr