Namensräume
Varianten
Aktionen

strncpy, strncpy_s

Von cppreference.com
< 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 aus dem durch `src` zeigenden Zeichen-Array (einschließlich des abschließenden Nullzeichens, aber nicht die Zeichen, die nach dem Nullzeichen kommen) in das durch `dest` zeigende Zeichen-Array.
Wenn `count` erreicht ist, bevor das gesamte Array `src` kopiert wurde, wird das resultierende Zeichen-Array nicht null-terminiert.
Wenn nach dem Kopieren des abschließenden Nullzeichens aus `src` `count` nicht erreicht ist, werden zusätzliche Nullzeichen in `dest` geschrieben, bis insgesamt `count` Zeichen geschrieben wurden.
Das Verhalten ist undefiniert, wenn sich die Zeichen-Arrays überlappen, wenn `dest` oder `src` kein Zeiger auf ein Zeichen-Array ist (einschließlich, wenn `dest` oder `src` ein Nullzeiger ist), wenn die Größe des durch `dest` zeigenden Arrays kleiner als `count` ist oder wenn die Größe des durch `src` zeigenden Arrays kleiner als `count` ist und es kein Nullzeichen enthält.
2) Dasselbe wie (1), außer dass die Funktion keine Nullen mehr in das Ziel-Array schreibt, um es bis `count` aufzufüllen. Sie stoppt nach dem Schreiben des abschließenden Nullzeichens (wenn keine Null im Quelltext vorhanden war, schreibt sie eine bei dest[count] und stoppt dann). Außerdem werden die folgenden Fehler zur Laufzeit erkannt und die aktuell installierte Constraint-Handler-Funktion aufgerufen
  • 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, eine Trunkierung würde auftreten
  • Es würde eine Überschneidung zwischen der Quell- und der Zielzeichenkette auftreten
Das Verhalten ist undefiniert, wenn die Größe des durch `dest` zeigenden Zeichen-Arrays < strnlen_s(src, destsz) <= destsz; mit anderen Worten, ein fehlerhafter Wert von destsz deckt den drohenden Pufferüberlauf nicht auf. Das Verhalten ist undefiniert, wenn die Größe des durch `src` zeigenden Zeichen-Arrays < strnlen_s(src, count) < destsz; mit anderen Worten, ein fehlerhafter Wert von count deckt den drohenden Pufferüberlauf nicht auf.
Wie bei allen grenzgeprüften Funktionen ist strncpy_s nur dann garantiert verfügbar, wenn __STDC_LIB_EXT1__ von der Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ vor dem Einbinden von <string.h> auf die Ganzzahlkonstante 1 setzt.

Inhalt

[bearbeiten] Parameter

dest - Zeiger auf das Zeichen-Array, in das kopiert werden soll
src - Zeiger auf das Zeichen-Array, aus dem kopiert werden soll
zählt - maximale Anzahl von zu kopierenden Zeichen
destsz - die Größe des Zielpuffers

[bearbeiten] Rückgabewert

1) Gibt eine Kopie von dest zurück
2) gibt null bei Erfolg zurück, gibt ungleich null bei Fehler zurück. Bei Fehler wird außerdem null nach dest[0] geschrieben (es sei denn, `dest` ist ein Nullzeiger oder `destsz` ist null oder größer als RSIZE_MAX) und der Rest des Ziel-Arrays kann mit nicht spezifizierten Werten überschrieben werden.

[bearbeiten] Hinweise

Wie durch den Post-C11 DR 468 korrigiert, darf strncpy_s im Gegensatz zu strcpy_s den Rest des Ziel-Arrays nur überschreiben, wenn ein Fehler auftritt.

Im Gegensatz zu strncpy füllt strncpy_s das Ziel-Array nicht mit Nullen auf. Dies ist eine häufige Fehlerquelle bei der Konvertierung bestehenden Codes auf die grenzgeprüfte Version.

Obwohl die Trunkierung, um in den Zielpuffer zu passen, ein Sicherheitsrisiko und somit eine Laufzeitbeschränkungsverletzung für strncpy_s darstellt, ist es möglich, das trunkierende Verhalten zu erzielen, indem `count` gleich der Größe des Ziel-Arrays minus eins angegeben wird: Es werden die ersten `count` Bytes kopiert und wie immer der Nullterminator angehängt: strncpy_s(dst, sizeof dst, src, (sizeof dst)-1);

[bearbeiten] 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"; // 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
}

Mögliche Ausgabe

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

[bearbeiten] Referenzen

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

[bearbeiten] Siehe auch

kopiert einen String in einen anderen
(Funktion) [bearbeiten]
kopiert einen Puffer in einen anderen
(Funktion) [bearbeiten]
(Dynamischer Speicher-TR)
kopiert einen String bis zu einer angegebenen Größe, indem Speicher zugewiesen wird
(Funktion) [bearbeiten]
C++ Dokumentation für strncpy