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) |
-
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, eine Trunkierung würde auftreten - Es würde eine Überschneidung zwischen der Quell- und der Zielzeichenkette auftreten
-
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_snur 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
dest zurück[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
| (C11) |
kopiert einen String in einen anderen (Funktion) |
| (C11) |
kopiert einen Puffer in einen anderen (Funktion) |
| (Dynamischer Speicher-TR) |
kopiert einen String bis zu einer angegebenen Größe, indem Speicher zugewiesen wird (Funktion) |
| C++ Dokumentation für strncpy
| |