strncpy, strncpy_s
Von de.cppreference.net
| 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:
srcoderdestist ein Nullzeigerdestszist null oder größer als RSIZE_MAXcountist größer als RSIZE_MAXcountist größer oder gleichdestsz, aberdestszist kleiner oder gleichstrnlen_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:
Beispiel
#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
(C11) |
kopiert einen String in einen anderen (Funktion) |
(C11) |
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
| |