Wie verkette ich const/literal strings in C?

Ich arbeite in C, und ich habe ein paar Dinge zu verketten.

Im Moment habe ich dies:

message = strcat("TEXT ", var);

message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));

Wenn Sie Erfahrung mit C haben, wissen Sie sicher, dass dies zu einem Segmentierungsfehler führt, wenn Sie versuchen, es auszuführen. Wie kann ich das also umgehen?

Lösung

In C sind "Strings" nur einfache "Char"-Arrays. Daher können Sie sie nicht direkt mit anderen "Strings" verketten.

Sie können die Funktion strcat verwenden, die die Zeichenkette, auf die src zeigt, an das Ende der Zeichenkette anhängt, auf die dest zeigt:

char *strcat(char *dest, const char *src);

Hier ist ein Beispiel von cplusplus.com:

char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");

Für den ersten Parameter müssen Sie den Zielpuffer selbst angeben. Der Zielpuffer muss ein Char-Array-Puffer sein. Z.B.: char buffer[1024];

**Vergewissern Sie sich, dass der erste Parameter genügend Platz hat, um das zu speichern, was Sie hineinkopieren wollen. Wenn es Ihnen möglich ist, ist es sicherer, Funktionen wie zu verwenden: strcpy_s und strcat_s, bei denen Sie die Größe des Zielpuffers explizit angeben müssen.

Anmerkung_: Ein String-Literal kann nicht als Puffer verwendet werden, da es eine Konstante ist. Daher müssen Sie immer ein char-Array für den Puffer zuweisen.

Der Rückgabewert von strcat kann einfach ignoriert werden, er gibt lediglich denselben Zeiger zurück, der als erstes Argument übergeben wurde. Er dient der Bequemlichkeit und ermöglicht es Ihnen, die Aufrufe in einer einzigen Codezeile zusammenzufassen:

strcat(strcat(str, foo), bar);

Ihr Problem könnte also wie folgt gelöst werden:

char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);
Kommentare (14)

Es ist ein undefiniertes Verhalten, wenn versucht wird, String-Literale zu ändern, was in etwa der Fall ist:

strcat ("Hello, ", name);

versuchen wird. Es wird versuchen, die Zeichenkette "name" an das Ende des String-Literales ""Hallo, "`" anzuhängen, was nicht gut definiert ist.

Versuchen Sie etwas wie dies. Es erreicht das, was Sie anscheinend zu tun versuchen:

char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);

Dies erzeugt einen Pufferbereich, der erlaubt ist, geändert zu werden, und kopiert dann sowohl das Zeichenkettenliteral als auch anderen Text in diesen Bereich. Seien Sie nur vorsichtig mit Pufferüberläufen. Wenn Sie die Eingabedaten kontrollieren (oder sie vorher überprüfen), ist es in Ordnung, Puffer mit fester Länge zu verwenden, wie ich es getan habe.

Andernfalls sollten Sie Vermeidungsstrategien anwenden, wie z. B. die Zuweisung von genügend Speicher aus dem Heap, um sicherzustellen, dass Sie das Problem bewältigen können. Mit anderen Worten, etwas wie:

const static char TEXT[] = "TEXT ";

// Make *sure* you have enough space.

char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
     handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);

// Need to free message at some point after you're done with it.
Kommentare (5)

Das erste Argument von strcat() muss genügend Platz für die verkettete Zeichenkette bieten. Weisen Sie also einen Puffer mit genügend Platz zu, um das Ergebnis aufzunehmen.

char bigEnough[64] = "";

strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);

/* and so on */

strcat() verkettet das zweite Argument mit dem ersten Argument und speichert das Ergebnis im ersten Argument. Das zurückgegebene char* ist einfach dieses erste Argument und dient nur Ihrer Bequemlichkeit.

Sie erhalten keine neu zugewiesene Zeichenkette mit dem ersten und zweiten Argument verkettet, was Sie aufgrund Ihres Codes wohl erwartet haben.

Kommentare (0)