Namespaces
Variants

strncpy, strncpy_s

From cppreference.net
< c ‎ | string ‎ | byte
Definiert in Header <string.h>
(1)
char * strncpy ( char * dest, const char * src, size_t count ) ;
(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 ohne die Zeichen, die dem Nullzeichen folgen), in das Zeichenarray, auf das dest zeigt.
Wenn count erreicht wird, bevor das gesamte Array src kopiert wurde, ist das resultierende Zeichenarray nicht nullterminiert.
Wenn nach dem Kopieren des abschließenden Nullzeichens von src , count nicht erreicht ist, werden zusätzliche Nullzeichen in dest geschrieben, bis insgesamt count Zeichen geschrieben wurden.
Das Verhalten ist undefiniert, wenn die Zeichenarrays sich überlappen, 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 von dest gezeigten Arrays kleiner als count ist, oder wenn die Größe des von src gezeigten Arrays kleiner als count ist und es kein Nullzeichen enthält.
2) Gleich wie (1) , außer dass die Funktion nicht mit dem Schreiben von Nullen in das Zielarray fortfährt, um bis count aufzufüllen, sondern nach dem Schreiben des abschließenden Nullzeichens stoppt (wenn kein Nullzeichen in der Quelle vorhanden war, schreibt sie eines bei dest [ count ] und stoppt dann). Zudem werden die folgenden Fehler zur Laufzeit erkannt und rufen die aktuell 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 ein Abschneiden auftreten
  • es würde eine Überlappung zwischen Quell- und Zielzeichenfolge auftreten
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das dest zeigt, < strnlen_s ( src, destsz ) <= destsz ; mit anderen Worten, ein fehlerhafter Wert von destsz macht den drohenden Pufferüberlauf nicht sichtbar. Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das src zeigt, < strnlen_s ( src, count ) < destsz ; mit anderen Worten, ein fehlerhafter Wert von count kann einen Pufferüberlauf ermöglichen.
Wie bei allen grenzprüfenden Funktionen ist strncpy_s nur garantiert verfügbar, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ auf die Integer-Konstante 1 setzt, bevor <string.h> eingebunden wird.

Inhaltsverzeichnis

Parameter

dest - Zeiger auf das Ziel-Zeichenarray
src - Zeiger auf das Quell-Zeichenarray
count - maximale Anzahl zu kopierender Zeichen
destsz - Größe des Zielpuffers

Rückgabewert

1) gibt eine Kopie von dest zurück
2) gibt bei Erfolg Null zurück, gibt bei Fehler einen Wert ungleich Null zurück. Außerdem wird bei einem Fehler Null in dest [ 0 ] geschrieben (sofern dest kein Nullzeiger ist und destsz nicht Null oder größer als RSIZE_MAX ist) und der Rest des Zielarrays kann mit nicht spezifizierten Werten überschrieben werden.

Hinweise

Wie durch den post-C11 DR 468 korrigiert, strncpy_s , im Gegensatz zu strcpy_s , darf nur den restlichen Teil des Zielarrays überschreiben, wenn ein Fehler auftritt.

Im Gegensatz zu strncpy füllt strncpy_s das Zielarray nicht mit Nullen auf. Dies ist eine häufige Fehlerquelle bei der Portierung bestehenden Codes auf die grenzprüfende Version.

Obwohl das Abschneiden zur Anpassung an den Zielpuffer ein Sicherheitsrisiko darstellt und daher einen Verstoß gegen die Laufzeitbeschränkungen für strncpy_s darstellt, ist es möglich, das abschneidende Verhalten zu erreichen, indem count gleich der Größe des Zielarrays minus eins angegeben wird: Es kopiert die ersten count Bytes und fügt wie immer den Nullterminator an: strncpy_s ( dst, sizeof dst, src, ( sizeof dst ) - 1 ) ;

Beispiel

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
    char src[] = "hi";
    char dest[6] = "abcdef"; // kein Null-Terminator
    strncpy(dest, src, 5); // schreibt fünf Zeichen 'h', 'i', '\0', '\0', '\0' nach dest
    printf("strncpy(dest, src, 5) zu einem 6-Byte-Ziel ergibt: ");
    for (size_t n = 0; n < sizeof dest; ++n) {
        char c = dest[n];
        c ? printf("'%c' ", c) : printf("'\\0' ");
    }
    printf("\nstrncpy(dest2, src, 2) zu einem 2-Byte-Ziel ergibt: ");
    char dest2[2];
    strncpy(dest2, src, 2); // Trunkierung: schreibt zwei Zeichen 'h', 'i' nach 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);  // schreibt 0 nach r1, 6 Zeichen nach dst1
    printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' nach dst1
    char dst2[5], src2[7] = {'g','o','o','d','b','y','e'};
    errno_t r2 = strncpy_s(dst2, 5, src2, 7);    // Kopieren überläuft das Zielarray
    printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // schreibt ungleich null nach r2, '\0' nach dst2[0]
    char dst3[5];
    errno_t r3 = strncpy_s(dst3, 5, src2, 4);    // schreibt 0 nach r3, 5 Zeichen nach dst3
    printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' nach dst3
#endif
}

Mögliche Ausgabe:

strncpy(dest, src, 5) zu einem 6-Byte-Ziel ergibt: 'h' 'i' '\0' '\0' '\0' 'f'
strncpy(dest2, src, 2) zu einem 2-Byte-Ziel ergibt: 'h' 'i'
dst1 = "hello", r1 = 0
dst2 = "", r2 = 22
dst3 = "good", r3 = 0

Referenzen

  • C17 Standard (ISO/IEC 9899:2018):
  • 7.24.2.4 Die strncpy-Funktion (S: 265)
  • K.3.7.1.4 Die strncpy_s-Funktion (S: 447-448)
  • C11-Standard (ISO/IEC 9899:2011):
  • 7.24.2.4 Die strncpy-Funktion (S: 363-364)
  • K.3.7.1.4 Die strncpy_s-Funktion (S: 616-617)
  • C99-Standard (ISO/IEC 9899:1999):
  • 7.21.2.4 Die strncpy-Funktion (S: 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)
weist eine Kopie eines Strings bis zur angegebenen Größe zu
(Funktion)
C++-Dokumentation für strncpy