Namespaces
Variants

strncat, strncat_s

Von de.cppreference.net
< c | String | Byte
Definiert in Header <string.h>
char* strncat( char* dest, const char* src, size_t count );
(1) (bis C99)
char* strncat( char* restrict dest, const char* restrict src, size_t count );
(seit C99)
errno_t strncat_s( char* restrict dest, rsize_t destsz,
                   const char* restrict src, rsize_t count );
(2) (seit C11)
1) Hängt höchstens count Zeichen aus dem Zeichenarray, auf das src zeigt, an das Ende des nullterminierten Byte-Strings, auf den dest zeigt, an; das Kopieren stoppt, wenn das Nullzeichen gefunden wird. Das Zeichen src[0] ersetzt den Nullterminator am Ende von dest. Das abschließende Nullzeichen wird immer am Ende angehängt (die maximale Anzahl von Bytes, die die Funktion schreiben kann, ist also count + 1).
Das Verhalten ist undefiniert, wenn das Zielarray nicht genügend Platz für den Inhalt von dest und die ersten count Zeichen von src plus das abschließende Nullzeichen hat. Das Verhalten ist undefiniert, wenn sich Quell- und Zielobjekte überschneiden. Das Verhalten ist undefiniert, wenn entweder dest kein Zeiger auf einen nullterminierten Byte-String oder src kein Zeiger auf ein Zeichenarray ist.
2) Wie (1), außer dass diese Funktion den Rest des Zielarrays (ab dem letzten geschriebenen Byte bis destsz) überschreiben kann und dass die folgenden Fehler zur Laufzeit erkannt werden und die derzeit installierte Constraint-Handler-Funktion aufrufen:
  • src oder dest ist ein Nullzeiger
  • destsz oder count ist Null oder größer als RSIZE_MAX
  • Es gibt kein Nullzeichen in den ersten destsz Bytes von dest
  • Es würde eine Verkürzung auftreten: count oder die Länge von src, je nachdem, welcher Wert kleiner ist, übersteigt den verfügbaren Platz zwischen dem Nullterminator von dest und destsz.
  • Es würde eine Überschneidung zwischen Quell- und Ziel-Strings auftreten
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das dest < strnlen(dest, destsz) + strnlen(src,count) + 1 < destsz zeigt, [...]; mit anderen Worten, ein fehlerhafter Wert von destsz legt den bevorstehenden Pufferüberlauf nicht offen. Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das src < strnlen(src,count) < destsz zeigt, [...]; mit anderen Worten, ein fehlerhafter Wert von count legt den bevorstehenden Pufferüberlauf nicht offen.
Wie bei allen begrenzungsgeprüften Funktionen ist strncat_s nur dann garantiert verfügbar, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und der Benutzer __STDC_WANT_LIB_EXT1__ vor der Einbindung von 1string.h< auf die ganzzahlige Konstante > setzt.

Parameter

dest - Zeiger auf den nullterminierten Byte-String, an den angehängt werden soll
src - Zeiger auf das Zeichenarray, aus dem kopiert werden soll
count - maximale Anzahl der zu kopierenden Zeichen
destsz - die Größe des Zielpuffers

Rückgabewert

1) gibt eine Kopie von dest
zurück2) gibt bei Erfolg Null zurück, bei Fehler einen Wert ungleich Null. Im Fehlerfall wird zudem Null in dest[0] geschrieben (es sei denn, dest ist ein Nullzeiger oder destsz ist Null oder größer als RSIZE_MAX).

Hinweise

Da strncat bei jedem Aufruf das Ende von dest suchen muss, ist es ineffizizient, viele Strings mit strncat zu einem einzigen zu verketten.

Obwohl die Verkürzung, um in den Zielpuffer zu passen, ein Sicherheitsrisiko darstellt und daher eine Laufzeitbedingungsverletzung für strncat_s ist, kann man das Verkürzungsverhalten erreichen, indem man count gleich der Größe des Zielarrays minus eins setzt: Es werden die ersten count Bytes kopiert und wie immer der Nullterminator angehängt: strncat_s(dst, sizeof dst, src, (sizeof dst) - strnlen_s(dst, sizeof dst) - 1);

Beispiel

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char str[50] = "Hello ";
    char str2[50] = "World!";
    strcat(str, str2);
    strncat(str, " Goodbye World!", 3);
    puts(str);

#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    char s1[100] = "good";
    char s5[1000] = "bye";
    int r1 = strncat_s(s1, 100, s5, 1000); // r1 is 0, s1 holds "goodbye\0"
    printf("s1 = %s, r1 = %d\n", s1, r1);
    char s2[6] = "hello";
    int r2 = strncat_s(s2, 6, "", 1); // r2 is 0, s2 holds "hello\0"
    printf("s2 = %s, r2 = %d\n", s2, r2);
    char s3[6] = "hello";
    int r3 = strncat_s(s3, 6, "X", 2); // r3 is non-zero, s3 holds "\0"
    printf("s3 = %s, r3 = %d\n", s3, r3);
    // the strncat_s truncation idiom:
    char s4[7] = "abc";
    int r4 = strncat_s(s4, 7, "defghijklmn", 3); // r4 is 0, s4 holds "abcdef\0"
    printf("s4 = %s, r4 = %d\n", s4, r4);
#endif
}

Mögliche Ausgabe:

Hello World! Go
s1 = goodbye, r1 = 0
s2 = hello, r2 = 0
s3 = , r3 = 22
s4 = abcdef, r4 = 0

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 7.26.3.2 Die strncat-Funktion (S. 379)
  • K.3.7.2.2 Die strncat_s-Funktion (S. TBD)
  • C17-Standard (ISO/IEC 9899:2018):
  • 7.24.3.2 Die strncat-Funktion (S. 265-266)
  • K.3.7.2.2 Die strncat_s-Funktion (S. 449-450)
  • C11-Standard (ISO/IEC 9899:2011):
  • 7.24.3.2 Die strncat-Funktion (S. 364-365)
  • K.3.7.2.2 Die strncat_s-Funktion (S. 618-620)
  • C99-Standard (ISO/IEC 9899:1999):
  • 7.21.3.2 Die strncat-Funktion (S. 327-328)
  • C89/C90-Standard (ISO/IEC 9899:1990):
  • 4.11.3.2 Die strncat-Funktion

Siehe auch

verkettet zwei Strings
(Funktion)
kopiert einen String in einen anderen
(Funktion)
kopiert einen Puffer in einen anderen, stoppt nach dem angegebenen Trennzeichen
(Funktion)
C++-Dokumentation für strncat