Hvordan sammenkæder jeg konstante/literaelle strenge i C?

Jeg arbejder i C, og jeg skal sammenkæde et par ting.

Lige nu har jeg dette:

message = strcat("TEXT ", var);

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

Hvis du har erfaring med C er jeg sikker på at du er klar over at dette giver dig en segmenteringsfejl når du prøver at køre det. Så hvordan arbejder jeg udenom det?

Løsning

I C er "strings" bare almindelige char arrays. Derfor kan du ikke direkte sammenkæde dem med andre "strings".

Du kan bruge funktionen strcat, som tilføjer strengen, der peges på af src, til slutningen af strengen, der peges på af dest:

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

Her er et eksempel fra cplusplus.com:

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

For den første parameter skal du angive selve destinationsbufferen. Destinationsbufferen skal være en char array-buffer. F.eks: eksempel: char buffer[1024];

Sørg for, at den første parameter har plads nok til at gemme det, du forsøger at kopiere ind i den. Hvis det er tilgængeligt for dig, er det sikrere at bruge funktioner som f.eks: Hvis du er sikker på at være sikker, er det lettere at bruge dem: strcpy_s og strcat_s, hvor du udtrykkeligt skal angive størrelsen på destinationsbufferen.

Note: En string literal kan ikke bruges som buffer, da det er en konstant. Derfor skal du altid allokere et char array til bufferen.

Returværdien af strcat kan simpelthen ignoreres, den returnerer blot den samme pointer som blev overgivet som det første argument. Den er der for nemheds skyld, og gør det muligt at kæde opkaldene sammen i én kodelinje:

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

Så dit problem kunne løses på følgende måde:

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

Det er udefineret adfærd at forsøge at ændre string-litraaler, hvilket er det, som noget som:

strcat ("Hello, ", name);

vil forsøge at gøre. Det vil forsøge at hæfte strengen name på i slutningen af strenglitteraturen "Hello, ", som ikke er veldefineret.

Prøv noget som dette. Det opnår det, som du tilsyneladende forsøger at gøre:

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

Dette opretter et bufferområde, der er tilladt at blive ændret, og kopierer derefter både strenglitteraturen og anden tekst til det. Bare vær forsigtig med bufferoverløb. Hvis du kontrollerer inputdataene (eller kontrollerer dem på forhånd), er det fint at bruge buffere med fast længde, som jeg har gjort.

Ellers bør du bruge afbødningsstrategier som f.eks. at allokere nok hukommelse fra heap'en til at sikre, at du kan håndtere det. Med andre ord, noget i stil med:

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

Det første argument i strcat() skal kunne rumme tilstrækkelig plads til den sammenkædede streng. Alloker derfor en buffer med tilstrækkelig plads til at modtage resultatet.

char bigEnough[64] = "";

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

/* and so on */

strcat() sammenkæder det andet argument med det første argument og gemmer resultatet i det første argument, den returnerede char* er blot dette første argument, og kun for din bekvemmeligheds skyld.

Du får ikke en nyallokeret streng med det første og det andet argument sammenkædet, hvilket jeg gætter på, at du forventede ud fra din kode.

Kommentarer (0)