Jak wykonać konkatenację stałych/literalnych łańcuchów w C?

Pracuję w C i muszę połączyć kilka rzeczy.

W tej chwili mam to:

message = strcat("TEXT ", var);

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

Teraz, jeśli masz doświadczenie w C I'm sure you realize that this gives you a segmentation fault when you try to run it. Więc jak mogę to obejść?

Rozwiązanie

W C, "łańcuchy" są po prostu zwykłymi tablicami char. Dlatego nie można'bezpośrednio konkatenować ich z innymi "łańcuchami".

Możesz użyć funkcji strcat, która dołącza łańcuch wskazany przez src do końca łańcucha wskazanego przez dest:

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

Oto przykład przykład z cplusplus.com:

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

Dla pierwszego parametru należy podać sam bufor docelowy. Bufor docelowy musi być buforem w postaci tablicy znaków. Np: char buffer[1024];.

Upewnij się, że pierwszy parametr ma wystarczająco dużo miejsca, aby przechować to, co próbujesz do niego skopiować. Jeśli jest to dla Ciebie dostępne, bezpieczniej jest używać funkcji takich jak: strcpy_s i strcat_s, gdzie jawnie musisz określić rozmiar bufora docelowego.

Uwaga: Literał łańcuchowy nie może być użyty jako bufor, ponieważ jest to stała. Tak więc, zawsze musisz przydzielić tablicę znaków dla bufora.

Wartość zwracana przez strcat może być po prostu zignorowana, zwraca ona po prostu ten sam wskaźnik, który został przekazany jako pierwszy argument. Jest tam dla wygody, i pozwala na połączenie wywołań w jedną linię kodu:

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

Tak więc twój problem można rozwiązać w następujący sposób:

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

Niezdefiniowanym zachowaniem jest próba modyfikacji literałów łańcuchów, czyli to, co coś takiego:

strcat ("Hello, ", name);

będzie próbowało to zrobić. Spróbuje ono dodać łańcuch name na koniec literału "Hello, ", który nie jest dobrze zdefiniowany.

Spróbuj czegoś takiego. Osiąga to, co wydaje się, że próbujesz zrobić:

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

Tworzy to obszar bufora, który jest dozwolony do modyfikacji, a następnie kopiuje do niego zarówno literał łańcuchowy, jak i inny tekst. Po prostu uważaj na przepełnienia bufora. Jeśli kontrolujesz dane wejściowe (lub sprawdzasz je wcześniej), to dobrze jest używać buforów o stałej długości, tak jak ja to zrobiłem.

W przeciwnym razie powinieneś użyć strategii łagodzących, takich jak przydzielanie wystarczającej ilości pamięci ze sterty, aby upewnić się, że możesz sobie z tym poradzić. Innymi słowy, coś w stylu:

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

Pierwszy argument strcat() musi być w stanie pomieścić wystarczająco dużo miejsca dla konkatenowanego łańcucha. Zatem zaalokować bufor z wystarczającą ilością miejsca, aby otrzymać wynik.

char bigEnough[64] = "";

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

/* and so on */

strcat() połączy drugi argument z pierwszym, i zapisze wynik w pierwszym argumencie, zwrócony char* jest po prostu tym pierwszym argumentem, i to tylko dla twojej wygody.

Nie otrzymujesz nowo przydzielonego ciągu znaków z pierwszym i drugim argumentem, który I'd guess you expected based on your code.

Komentarze (0)