Łącz dwa łańcuchy w jeden ciąg.
Prototypy
#include <string.h>
char * strcat(char *restrict s1, const char *restrict s2);
char * strncat(char *restrict s1, const char *restrict s2, size_t n);
OPIS
strcat()
i strncat()
funkcji dołączenia kopię nul łańcucha S2 koniec przerwanego null ciąg s1, a następnie dodaj zakończenie \ 0 '. Ciąg s1 musi mieć wystarczającą ilość miejsca, aby pomieścić wynik.
Funkcja strncat() dodaje nie więcej niż n znaków z s2, a dodaje wtedy zakończenie \ 0 '.
Łańcuchy źródłowy i docelowy nie powinny się nakładać, ponieważ zachowanie jest nieokreślone jako zachowanie .
RETURN WARTOŚCI
The `strcat()` and `strncat()` functions return the pointer s1.
względy bezpieczeństwa
Funkcja strcat()
łatwo nadużywane w sposób, który pozwala szkodliwym użytkownikom dowolnie zmieniać program działający na funkcjonalność poprzez atak przepełnienia bufora.
Należy unikać używania strcat()
. Zamiast tego należy użyć strncat()
lub strlcat()
i upewnić się, że żadne inne znaki nie są kopiowane do bufora docelowego, niż mogą być przechowywane.
Uwaga, że strncat()
może być również problematyczne. Może to być problem dotyczący bezpieczeństwa, aby ciąg był w ogóle obcięty. Ponieważ ścięty ciąg nie będzie tak długi, jak oryginał, może odnosić się do zupełnie innego zasobu, a użycie obciętego zasobu może spowodować nieprawidłowe zachowanie w postaci . Przykład:
void
foo(const char *arbitrary_string)
{
char onstack[8] = "";
#if defined(BAD)
/*
* This first strcat is bad behavior. Do not use strcat!
*/
(void)strcat(onstack, arbitrary_string); /* BAD! */
#elif defined(BETTER)
/*
* The following two lines demonstrate better use of
* strncat().
*/
(void)strncat(onstack, arbitrary_string,
sizeof(onstack) - strlen(onstack) - 1);
#elif defined(BEST)
/*
* These lines are even more robust due to testing for
* truncation.
*/
if (strlen(arbitrary_string) + 1 >
sizeof(onstack) - strlen(onstack))
err(1, "onstack would be truncated");
(void)strncat(onstack, arbitrary_string,
sizeof(onstack) - strlen(onstack) - 1);
#endif
}
przykład
char dest[20] = "Hello";
char *src = ", World!";
char numbers[] = "12345678";
printf("dest before strcat: \"%s\"\n", dest); // "Hello"
strcat(dest, src);
printf("dest after strcat: \"%s\"\n", dest); // "Hello, World!"
strncat(dest, numbers, 3); // strcat first 3 chars of numbers
printf("dest after strncat: \"%s\"\n", dest); // "Hello, World!123"
+1. Podkreślam, że w niektórych systemach (np. BSD) kompilator ostrzega, jeśli używasz "wielkości-ogólnych" funkcji manipulowania ciągami znaków (strcat, strcpy, itp.). – dave
Myślę, że masz na myśli "... daj mu rozmiar bufora docelowego _minus rozmiar łańcucha, który już zawiera. " – Nemo
Ta odpowiedź jest niebezpiecznie błędna. @Nemo podszedł bliżej, ale myślę, że wciąż jest jeden. [Odpowiedź Pankaj] (http://stackoverflow.com/a/6502352/228539) wydaje się dokładna i jest bardzo szczegółowa. Musi to być "rozmiar bufora docelowego - długość ciągu docelowego - 1", aby odpowiednio uniknąć przepełnień bufora. Chociaż wydaje się to głupim wyborem przy projektowaniu tej funkcji, ponieważ musi ona z natury szukać terminatora zerowego przed rozpoczęciem kopiowania w każdym razie i może obliczyć długość wzdłuż drogi, abyśmy nie musieli robić tego dwa razy. – altendky