Gegeben ein Array von Zeigern auf Zeichenfolgenliterale:
char *textMessages[] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
}
Wie bestimmt man die Länge eines bestimmten String-Literals – etwa des dritten? Ich habe versucht, den Befehl sizeof wie folgt zu verwenden:
int size = sizeof(textMessages[2]);
Aber das Ergebnis scheint eher die Anzahl der Zeiger im Array zu sein als die Länge des String-Literals.
sizeof(textMessages[2]) ergibt die Größe der char* Typ. Das ist reiner Zufall sizeof(char*) ist auf Ihrem System zufällig 4 und hat nichts mit der Anzahl der Elemente in Ihrem Array zu tun.
– Ben Cottrell
22. September 2012 um 7:33 Uhr
Sie sollten erwägen, die Definition zu verwenden static const char textMesssages[][4] für dein Array.
– Michael Foukarakis
22. September 2012 um 8:43 Uhr
@MichaelFoukarakis Es gibt nur drei Zeiger im Array (beachten Sie die Zeichenfolgenverkettung).
– Jens
22. September 2012 um 10:19 Uhr
@Jens: Na ja, mein Punkt lag nicht wirklich in der Wahl der Nummer, obwohl ich für einen Sentinel-Wert plädieren würde.
– Michael Foukarakis
22. September 2012 um 11:20 Uhr
Wenn Sie möchten, dass die Nummer berechnet wird Kompilierzeit (im Gegensatz zur Laufzeit mit strlen) ist es vollkommen in Ordnung, einen Ausdruck wie zu verwenden
sizeof "A really large text message that "
"is spread over multiple lines";
Möglicherweise möchten Sie jedoch ein Makro verwenden, um die Wiederholung des langen Literals zu vermeiden:
#define LONGLITERAL "A really large text message that " \
"is spread over multiple lines"
Beachten Sie, dass der von zurückgegebene Wert sizeof enthält die abschließende NUL, ist also eins mehr als strlen.
Ich möchte die Länge jeder Zeichenfolge bestimmen, damit ich die Längen indizieren und an eine Funktion übergeben kann. Ist es möglich, ein solches Array von Längen zur Kompilierzeit zu berechnen?
– Zach
23. September 2012 um 2:12 Uhr
Mein Ansatz wäre, ein Array von zu deklarieren und zu initialisieren struct { char *ptr; size_t len; } x[]. Dann kannst du anrufen foo(x[i].ptr, x[i].len). Da C keine Zeichenfolgenlängen herumhält, gibt es keine andere Möglichkeit, als die Zeichenfolgenlängen in Ihrem Code zu verfolgen.
– Jens
23. September 2012 um 10:09 Uhr
Mein Vorschlag wäre zu verwenden Strlen und aktivieren Sie Compiler-Optimierungen.
Zum Beispiel mit gcc 4.7 auf x86:
#include <string.h>
static const char *textMessages[3] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
};
size_t longmessagelen(void)
{
return strlen(textMessages[2]);
}
Nach dem Rennen make CFLAGS="-ggdb -O3" example.o:
Sie sollten die verwenden strlen() Bibliotheksmethode, um die Länge einer Zeichenfolge zu erhalten. sizeof gibt Ihnen die Größe von textMessages[2]ein Zeiger, der maschinenabhängig wäre (4 Bytes oder 8 Bytes).
Sie könnten die Tatsache ausnutzen, dass Werte in einem Array aufeinander folgen:
Die Größe wird bestimmt, indem die Begrenzungen der Elemente verwendet werden. Der Abstand zwischen dem Anfang des ersten und dem Anfang des zweiten Elements hat die Größe des ersten.
Dazu gehört auch die Kündigung \0. Die Lösung funktioniert natürlich nur mit konstanten Strings richtig. Wenn die Zeichenfolgen Zeiger gewesen wären, würden Sie die Größe eines Zeigers anstelle der Länge der Zeichenfolge erhalten.
Es ist nicht garantiert, dass dies funktioniert. Wenn die Felder ausgerichtet sind, kann dies zu falschen Größen führen, und es können andere Einschränkungen durch den Compiler eingeführt werden, z. B. das Zusammenführen identischer Zeichenfolgen. Außerdem benötigen Sie mindestens zwei Elemente in Ihrem Array.
Mahmud Imam
Ich werde Ihnen etwas sagen, gemäß meinem Wissen sind Arrays und Zeiger dasselbe außer wenn Sie verwenden sizeof.
Wenn Sie verwenden sizeof auf einem Zeiger wird es immer zurückkehren 4 BYTE unabhängig davon, worauf der Zeiger zeigt, aber wenn er für ein Array verwendet wird, wird er zurückkehren Wie lang ist das Array groß in Bytes?.
In Ihrem Beispiel hier *textMessage[] ist ein Array von Zeigern, also wenn Sie verwenden sizeof(textMessage[2]) es wird zurückkehren 4 BYTE Weil textMessage[2] ist ein Zeiger.
Ich hoffe, es wird für Sie nützlich sein.
Ich habe nicht verstanden, was du willst
– Mahmoud Emam
22. September 2012 um 19:44 Uhr
Meine Absicht war es, Ihnen zu sagen, dass Sie Ihr Wissen über die verbessern sollen Unterschied von Arrays und Zeigern, indem alle gelesen werden c-faq.com/aryptr/index.html Arrays sind keine Zeiger und haben oft 2 oder 8 statt 4 Bytes und ihre Größe kann sogar davon abhängen, auf welchen Typ sie zeigen. Das meiste, was Sie geschrieben haben, ist also technisch falsch.
– Jens
22. September 2012 um 20:06 Uhr
Zeiger sind nicht immer 4 Bytes groß.
– Jeff G
9. Februar 2016 um 19:01 Uhr
11353500cookie-checkBestimmen der Länge eines String-Literalsyes
sizeof(textMessages[2])
ergibt die Größe derchar*
Typ. Das ist reiner Zufallsizeof(char*)
ist auf Ihrem System zufällig 4 und hat nichts mit der Anzahl der Elemente in Ihrem Array zu tun.– Ben Cottrell
22. September 2012 um 7:33 Uhr
Sie sollten erwägen, die Definition zu verwenden
static const char textMesssages[][4]
für dein Array.– Michael Foukarakis
22. September 2012 um 8:43 Uhr
@MichaelFoukarakis Es gibt nur drei Zeiger im Array (beachten Sie die Zeichenfolgenverkettung).
– Jens
22. September 2012 um 10:19 Uhr
@Jens: Na ja, mein Punkt lag nicht wirklich in der Wahl der Nummer, obwohl ich für einen Sentinel-Wert plädieren würde.
– Michael Foukarakis
22. September 2012 um 11:20 Uhr