strncpy, strncpy_s
|
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) |
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.
count
erreicht wird, bevor das gesamte Array
src
kopiert wurde, ist das resultierende Zeichenarray nicht nullterminiert.
src
,
count
nicht erreicht ist, werden zusätzliche Nullzeichen in
dest
geschrieben, bis insgesamt
count
Zeichen geschrieben wurden.
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.
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:
-
-
srcoderdestist ein Nullzeiger -
destszist null oder größer als RSIZE_MAX -
countist größer als RSIZE_MAX -
countist größer oder gleichdestsz, aberdestszist 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
-
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_snur 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
dest
zurück
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
|
(C11)
|
kopiert einen String in einen anderen
(Funktion) |
|
(C11)
|
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
|
|