Namespaces
Variants

strncpy, strncpy_s

Von de.cppreference.net
< C | String | Byte
Definiert in der Header-Datei <string.h>
char* strncpy( char* dest, const char* src, size_t count );
(1) (bis C99)
char* strncpy( char* restrict dest, const char* restrict src, size_t count );
(seit C99)
errno_t strncpy_s( char* restrict dest, rsize_t destsz,
                   const char* restrict src, rsize_t count );
(2) (seit C11)
1) Kopiert höchstens count Zeichen des Zeichenarrays, auf das src zeigt (einschließlich des abschließenden Nullzeichens, aber keine der Zeichen, die auf das Nullzeichen folgen), in das Zeichenarray, auf das dest zeigt.
Wenn count erreicht wird, bevor das gesamte Array src kopiert wurde, wird das resultierende Zeichenarray nicht nullterminiert.
Wenn nach dem Kopieren des abschließenden Nullzeichens von src count nicht erreicht ist, werden zusätzliche Nullzeichen nach dest geschrieben, bis insgesamt count Zeichen geschrieben wurden.
Das Verhalten ist undefiniert, wenn sich die Zeichenarrays überschneiden, wenn entweder dest oder src kein Zeiger auf ein Zeichenarray ist (einschließlich wenn dest oder src ein Nullzeiger ist), wenn die Größe des Arrays, auf das dest zeigt, kleiner als count ist, oder wenn die Größe des Arrays, auf das src zeigt, kleiner als count ist und es kein Nullzeichen enthält.
2) Gleich wie (1), außer dass die Funktion nicht weiter Nullen in das Zielarray schreibt, um bis count aufzufüllen; sie stoppt nach dem Schreiben des abschließenden Nullzeichens (wenn es kein Nullzeichen in der Quelle gab, schreibt sie eines an dest[count] und stoppt dann). Außerdem werden die folgenden Fehler zur Laufzeit erkannt und rufen die derzeit installierte Constraint-Handler-Funktion auf:
  • src oder dest ist ein Nullzeiger
  • destsz ist null oder größer als RSIZE_MAX
  • count ist größer als RSIZE_MAX
  • count ist größer oder gleich destsz, aber destsz ist kleiner oder gleich strnlen_s(src, count), mit anderen Worten, es würde zu einem Abschneiden kommen
  • Es würde eine Überschneidung zwischen Quell- und Zielstring auftreten
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das durch dest < strnlen_s(src, destsz) <= destsz gezeigt wird; mit anderen Worten, ein fehlerhafter Wert von destsz den bevorstehenden Pufferüberlauf nicht offenlegt. Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das durch src < strnlen_s(src, count) < destsz gezeigt wird; mit anderen Worten, ein fehlerhafter Wert von count den bevorstehenden Pufferüberlauf nicht offenlegt.
Wie bei allen grenzgeprüften Funktionen ist strncpy_s nur garantiert verfügbar, wenn __STDC_LIB_EXT1__ von der Implementierung definiert ist und der Benutzer __STDC_WANT_LIB_EXT1__ auf die ganzzahlige Konstante 1 setzt, bevor er <string.h> einbindet.

Parameter

dest - Zeiger auf das Zeichenarray, in das kopiert werden soll
src - Zeiger auf das Zeichenarray, aus dem kopiert werden soll
count - maximale Anzahl zu kopierender Zeichen
destsz - die Größe des Zielpuffers

Rückgabewert

1) gibt eine Kopie von dest
zurück2)dest[0] gibt bei Erfolg Null zurück, bei Fehler einen Wert ungleich Null. Außerdem wird bei Fehler Null in dest geschrieben (außer destsz ist ein Nullzeiger oder ist null oder größer als RSIZE_MAX

) und kann den Rest des Zielarrays mit unspezifizierten Werten überschreiben.

Hinweisestrncpy_sWie durch den Post-C11-DR 468 korrigiert, darf , anders als strcpy

, den Rest des Zielarrays nur dann überschreiben, wenn ein Fehler auftritt. strncpyAnders als strncpy_s füllt

das Zielarray nicht mit Nullen auf. Dies ist eine häufige Fehlerquelle bei der Umstellung vorhandenen Codes auf die grenzgeprüfte Version. strncpy_sObwohl das Abschneiden, um in den Zielpuffer zu passen, ein Sicherheitsrisiko darstellt und daher eine Laufzeitbeschränkungsverletzung für count ist, ist es möglich, das abschneidende Verhalten zu erhalten, indem count gleich der Größe des Zielarrays minus eins gesetzt wird: Es kopiert die ersten strncpy_s(dst, sizeof dst, src, (sizeof dst)-1);

Bytes und hängt wie immer den Nullterminator an:

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

int main(void)
{
    char src[] = "hi";
    char dest[6] = "abcdef"; // no null terminator
    strncpy(dest, src, 5); // writes five characters 'h', 'i', '\0', '\0', '\0' to dest
    printf("strncpy(dest, src, 5) to a 6-byte dest gives : ");
    for (size_t n = 0; n < sizeof dest; ++n) {
        char c = dest[n];
        c ? printf("'%c' ", c) : printf("'\\0' ");
    }

    printf("\nstrncpy(dest2, src, 2) to a 2-byte dst gives : ");
    char dest2[2];
    strncpy(dest2, src, 2); // truncation: writes two characters 'h', 'i', to dest2
    for (size_t n = 0; n < sizeof dest2; ++n) {
        char c = dest2[n];
        c ? printf("'%c' ", c) : printf("'\\0' ");
    }
    printf("\n");

#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    char dst1[6], src1[100] = "hello";
    errno_t r1 = strncpy_s(dst1, 6, src1, 100);  // writes 0 to r1, 6 characters to dst1
    printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' to dst1

    char dst2[5], src2[7] = {'g','o','o','d','b','y','e'};
    errno_t r2 = strncpy_s(dst2, 5, src2, 7);    // copy overflows the destination array
    printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // writes nonzero to r2,'\0' to dst2[0]

    char dst3[5];
    errno_t r3 = strncpy_s(dst3, 5, src2, 4);    // writes 0 to r3, 5 characters to dst3
    printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' to dst3
#endif
}

Diesen Code ausführen

strncpy(dest, src, 5) to a 6-byte dst gives : 'h' 'i' '\0' '\0' '\0' 'f'
strncpy(dest2, src, 2) to a 2-byte dst gives : 'h' 'i'
dst1 = "hello", r1 = 0
dst2 = "", r2 = 22
dst3 = "good", r3 = 0

Mögliche Ausgabe:

  • Referenzen
  • C23 Standard (ISO/IEC 9899:2024):
  • K.3.7.1.4 Die strncpy_s-Funktion (p: TBD)
  • C17 Standard (ISO/IEC 9899:2018):
  • 7.24.2.4 Die strncpy-Funktion (p: 265)
  • K.3.7.1.4 Die strncpy_s-Funktion (p: 447-448)
  • C11 Standard (ISO/IEC 9899:2011):
  • 7.24.2.4 Die strncpy-Funktion (p: 363-364)
  • K.3.7.1.4 Die strncpy_s-Funktion (p: 616-617)
  • C99 Standard (ISO/IEC 9899:1999):
  • 7.21.2.4 Die strncpy-Funktion (p: 326-327)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 4.11.2.4 Die strncpy-Funktion

Siehe auch

kopiert einen String in einen anderen
(Funktion)
kopiert einen Puffer in einen anderen
(Funktion)
(Dynamic Memory TR)
allokiert eine Kopie eines Strings bis zu einer bestimmten Größe
(Funktion)
C++-Dokumentation für strncpy