strncpy, strncpy_s
|
Défini dans l'en-tête
<string.h>
|
||
| (1) | ||
|
char
*
strncpy
(
char
*
dest,
const
char
*
src,
size_t
count
)
;
|
(jusqu'à C99) | |
|
char
*
strncpy
(
char
*
restrict
dest,
const
char
*
restrict
src,
size_t
count
)
;
|
(depuis C99) | |
|
errno_t strncpy_s
(
char
*
restrict
dest, rsize_t destsz,
const char * restrict src, rsize_t count ) ; |
(2) | (depuis C11) |
count
caractères du tableau de caractères pointé par
src
(incluant le caractère nul de terminaison, mais aucun des caractères suivant le caractère nul) vers le tableau de caractères pointé par
dest
.
count
est atteint avant que la totalité du tableau
src
ne soit copiée, le tableau de caractères résultant n'est pas terminé par un caractère nul.
src
,
count
n'est pas atteint, des caractères nuls supplémentaires sont écrits dans
dest
jusqu'à ce qu'un total de
count
caractères aient été écrits.
dest
ou
src
n'est pas un pointeur vers un tableau de caractères (y compris si
dest
ou
src
est un pointeur nul), si la taille du tableau pointé par
dest
est inférieure à
count
, ou si la taille du tableau pointé par
src
est inférieure à
count
et qu'il ne contient pas de caractère nul.
count
, elle s'arrête après avoir écrit le caractère nul de terminaison (s'il n'y avait pas de nul dans la source, elle en écrit un à
dest
[
count
]
puis s'arrête). De plus, les erreurs suivantes sont détectées à l'exécution et appellent la fonction
gestionnaire de contraintes
actuellement installée :
-
-
srcoudestest un pointeur nul -
destszest zéro ou supérieur à RSIZE_MAX -
countest supérieur à RSIZE_MAX -
countest supérieur ou égal àdestsz, maisdestszest inférieur ou égal à strnlen_s ( src, count ) , en d'autres termes, une troncation se produirait - un chevauchement se produirait entre les chaînes source et destination
-
dest
<
strnlen_s
(
src, destsz
)
<=
destsz
; en d'autres termes, une valeur erronée de
destsz
n'expose pas le dépassement de tampon imminent. Le comportement est indéfini si la taille du tableau de caractères pointé par
src
<
strnlen_s
(
src, count
)
<
destsz
; en d'autres termes, une valeur erronée de
count
peut permettre un dépassement de tampon.
-
Comme pour toutes les fonctions à vérification de limites,
strncpy_sn'est garantie d'être disponible que si __STDC_LIB_EXT1__ est défini par l'implémentation et si l'utilisateur définit __STDC_WANT_LIB_EXT1__ à la constante entière 1 avant d'inclure <string.h> .
Table des matières |
Paramètres
| dest | - | pointeur vers le tableau de caractères à copier |
| src | - | pointeur vers le tableau de caractères à copier depuis |
| count | - | nombre maximum de caractères à copier |
| destsz | - | taille du tampon de destination |
Valeur de retour
dest
dest
est un pointeur nul ou
destsz
est zéro ou supérieur à
RSIZE_MAX
) et peut altérer le reste du tableau de destination avec des valeurs non spécifiées.
Notes
Comme corrigé par le DR 468 post-C11,
strncpy_s
, contrairement à
strcpy_s
, n'est autorisé à écraser la fin du tableau de destination qu'en cas d'erreur.
Contrairement à
strncpy
,
strncpy_s
ne remplit pas le tableau de destination avec des zéros. Ceci est une source fréquente d'erreurs lors de la conversion de code existant vers la version avec vérification des limites.
Bien que la troncature pour ajuster le tampon de destination soit un risque de sécurité et donc une violation des contraintes d'exécution pour
strncpy_s
, il est possible d'obtenir le comportement de troncature en spécifiant
count
égal à la taille du tableau de destination moins un : cela copiera les premiers
count
octets et ajoutera le terminateur nul comme toujours :
strncpy_s
(
dst,
sizeof
dst, src,
(
sizeof
dst
)
-
1
)
;
Exemple
#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"; // pas de terminateur nul strncpy(dest, src, 5); // écrit cinq caractères 'h', 'i', '\0', '\0', '\0' dans dest printf("strncpy(dest, src, 5) vers une dest de 6 octets donne : "); for (size_t n = 0; n < sizeof dest; ++n) { char c = dest[n]; c ? printf("'%c' ", c) : printf("'\\0' "); } printf("\nstrncpy(dest2, src, 2) vers une dst de 2 octets donne : "); char dest2[2]; strncpy(dest2, src, 2); // troncation : écrit deux caractères 'h', 'i' dans 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); // écrit 0 dans r1, 6 caractères dans dst1 printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' dans dst1 char dst2[5], src2[7] = {'g','o','o','d','b','y','e'}; errno_t r2 = strncpy_s(dst2, 5, src2, 7); // la copie dépasse la capacité du tableau de destination printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // écrit une valeur non nulle dans r2, '\0' dans dst2[0] char dst3[5]; errno_t r3 = strncpy_s(dst3, 5, src2, 4); // écrit 0 dans r3, 5 caractères dans dst3 printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' dans dst3 #endif }
Sortie possible :
strncpy(dest, src, 5) vers une dst de 6 octets donne : 'h' 'i' '\0' '\0' '\0' 'f' strncpy(dest2, src, 2) vers une dst de 2 octets donne : 'h' 'i' dst1 = "hello", r1 = 0 dst2 = "", r2 = 22 dst3 = "good", r3 = 0
Références
- Norme C17 (ISO/CEI 9899:2018) :
-
- 7.24.2.4 La fonction strncpy (p : 265)
-
- K.3.7.1.4 La fonction strncpy_s (p : 447-448)
- Norme C11 (ISO/CEI 9899:2011):
-
- 7.24.2.4 La fonction strncpy (p: 363-364)
-
- K.3.7.1.4 La fonction strncpy_s (p: 616-617)
- Norme C99 (ISO/CEI 9899:1999) :
-
- 7.21.2.4 La fonction strncpy (p: 326-327)
- Norme C89/C90 (ISO/IEC 9899:1990) :
-
- 4.11.2.4 Fonction strncpy
Voir aussi
|
(C11)
|
copie une chaîne vers une autre
(fonction) |
|
(C11)
|
copie un tampon vers un autre
(fonction) |
|
(dynamic memory TR)
|
alloue une copie d'une chaîne jusqu'à une taille spécifiée
(fonction) |
|
Documentation C++
pour
strncpy
|
|