Namespaces
Variants

strncpy, strncpy_s

De fr.cppreference.net
Défini dans l'en-tête <string.h>
char* strncpy( char* dest, const char* src, size_t count );
(1) (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 (y compris le caractère nul de terminaison, mais pas les caractères qui le suivent) vers le tableau de caractères pointé par dest.
Si count est atteint avant que tout le tableau src ait été copié, 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 depuis 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 remplir 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 contrainte actuellement installée :
  • src ou dest est un pointeur nul
  • destsz est nul 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 troncature 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ébordement 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 n'expose pas le débordement de tampon imminent.
Comme pour toutes les fonctions avec vérification des limites, strncpy_s n'est garanti 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__ comme la constante entière 1 avant d'inclure <string.h>.

Paramètres

dest - pointeur vers le tableau de caractères à copier
src - pointeur vers le tableau de caractères à copier
count - nombre maximal de caractères à copier
destsz - la taille du tampon de destination

Valeur de retour

1) retourne une copie de dest
2) retourne zéro en cas de succès, retourne non nul 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 nul ou supérieur à RSIZE_MAX) et peut altérer le reste du tableau de destination avec des valeurs non spécifiées.

Notes

Corrigé par le DR 468 post-C11, strncpy_s, contrairement à strcpy, n'est autorisé à altérer le reste du tableau de destination qu'en cas d'erreur.

Contrairement à strncpy, strncpy_s ne remplit pas le tableau de destination avec des zéros, ce qui 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 s'adapter au tampon de destination soit un risque de sécurité et donc une violation de contrainte d'exécution pour strncpy_s, il est possible d'obtenir un comportement de troncature en spécifiant count égal à la taille du tableau de destination moins un : il 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 <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
}

Résultat possible :

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

Références

  • Norme C23 (ISO/IEC 9899:2024) :
  • 7.24.2.4 La fonction strncpy (p : TBD)
  • K.3.7.1.4 La fonction strncpy_s (p : TBD)
  • Norme C17 (ISO/IEC 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/IEC 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/IEC 9899:1999) :
  • 7.21.2.4 La fonction strncpy (p : 326-327)
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 4.11.2.4 La 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