Come posso concatenare stringhe const/literal in C?

Sto lavorando in C, e devo concatenare alcune cose.

In questo momento ho questo:

message = strcat("TEXT ", var);

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

Ora, se hai esperienza in C, sono sicuro che ti rendi conto che questo ti dà un errore di segmentazione quando cerchi di eseguirlo. Quindi come faccio a lavorare intorno a questo?

Soluzione

In C, le "stringhe" sono solo semplici array di char. Pertanto, non è possibile concatenarle direttamente con altre "stringhe".

Puoi usare la funzione strcat, che aggiunge la stringa indicata da src alla fine della stringa indicata da dest:

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

Ecco un esempio da cplusplus.com:

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

Per il primo parametro, dovete fornire il buffer di destinazione stesso. Il buffer di destinazione deve essere un buffer char array. Ad esempio: char buffer[1024];

Assicuratevi che il primo parametro abbia abbastanza spazio per memorizzare ciò che state cercando di copiare al suo interno. Se disponibile, è più sicuro usare funzioni come: strcpy_s e strcat_s dove dovete esplicitamente specificare la dimensione del buffer di destinazione.

Nota: Un letterale di stringa non può essere usato come buffer, poiché è una costante. Quindi, dovete sempre allocare un array di char per il buffer.

Il valore di ritorno di strcat può essere semplicemente ignorato, restituisce semplicemente lo stesso puntatore che è stato passato come primo argomento. È lì per comodità e ti permette di concatenare le chiamate in una sola linea di codice:

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

Quindi il tuo problema potrebbe essere risolto come segue:

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

È un comportamento non definito tentare di modificare i letterali di stringa, che è ciò che qualcosa come:

strcat ("Hello, ", name);

tenterà di fare. Cercherà di attaccare la stringa name alla fine del letterale di stringa "Hello, ", che non è ben definito.

Prova qualcosa del genere. Raggiunge quello che sembra tu stia cercando di fare:

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

Questo crea un'area buffer che è autorizzata ad essere modificata e poi copia sia la stringa letterale che altro testo in essa. Fai solo attenzione ai buffer overflow. Se controllate i dati in ingresso (o li controllate prima), va bene usare buffer di lunghezza fissa come ho fatto io.

Altrimenti, dovresti usare strategie di mitigazione come l'allocazione di abbastanza memoria dall'heap per assicurarti di poterlo gestire. In altre parole, qualcosa come:

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.
Commentari (5)

Il primo argomento di strcat() deve poter contenere abbastanza spazio per la stringa concatenata. Quindi alloca un buffer con abbastanza spazio per ricevere il risultato.

char bigEnough[64] = "";

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

/* and so on */

strcat() concatena il secondo argomento con il primo argomento, e memorizza il risultato nel primo argomento, il char* restituito è semplicemente questo primo argomento, e solo per vostra comodità.

Non si ottiene una nuova stringa allocata con il primo e il secondo argomento concatenati, cosa che immagino vi aspettavate in base al vostro codice.

Commentari (0)