Namespaces
Variants

strncpy, strncpy_s

From cppreference.net
< c ‎ | string ‎ | byte
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)
1) Copie au plus 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 .
Si 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.
Si, après avoir copié le caractère nul de terminaison de 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.
Le comportement est indéfini si les tableaux de caractères se chevauchent, si 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.
2) Identique à (1) , sauf que la fonction ne continue pas à écrire des zéros dans le tableau de destination pour compléter jusqu'à 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 :
  • src ou dest est un pointeur nul
  • destsz est zéro ou supérieur à RSIZE_MAX
  • count est supérieur à RSIZE_MAX
  • count est supérieur ou égal à destsz , mais destsz est 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
Le comportement est indéfini si la taille du tableau de caractères pointé par 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_s n'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

1) renvoie une copie de dest
2) renvoie zéro en cas de succès, renvoie une valeur non nulle en cas d'erreur. De plus, en cas d'erreur, écrit zéro dans dest [ 0 ] (sauf si 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

copie une chaîne vers une autre
(fonction)
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