Bestimmen der Länge eines String-Literals

Lesezeit: 4 Minuten

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:

$ gdb example.o
(gdb) disassemble longmessagelen
   0x00000000 <+0>: mov    $0x3e,%eax
   0x00000005 <+5>: ret

Dh der Compiler hat den Aufruf an ersetzt strlen mit dem konstanten Wert 0x3e = 62.

Verschwenden Sie keine Zeit mit Optimierungen, die der Compiler für Sie erledigen kann!

Strlen gibt Ihnen die Länge der Zeichenfolge während Größe von gibt die Größe von zurück Datentyp in Bytes, die Sie als Parameter eingegeben haben.

Strlen

Größe von

strlen kann sein?

size_t size = strlen(textMessages[2]);

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:

const char *messages[] = {
    "footer",
    "barter",
    "banger"
};

size_t sizeOfMessage1 = (messages[1] - messages[0]) / sizeof(char); // 7   (6 chars + '\0')

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.

Benutzer-Avatar
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

1135350cookie-checkBestimmen der Länge eines String-Literals

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy