111 votes

Pourquoi devriez-vous utiliser strncpy au lieu de strcpy?

Edit: j'ai ajouté la source pour l'exemple.

Je suis tombé sur cet exemple:

char source[MAX] = "123456789";
char source1[MAX] = "123456789";
char destination[MAX] = "abcdefg";
char destination1[MAX] = "abcdefg";
char *return_string;
int index = 5;

/* This is how strcpy works */
printf("destination is originally = '%s'\n", destination);
return_string = strcpy(destination, source);
printf("after strcpy, dest becomes '%s'\n\n", destination);

/* This is how strncpy works */
printf( "destination1 is originally = '%s'\n", destination1 );
return_string = strncpy( destination1, source1, index );
printf( "After strncpy, destination1 becomes '%s'\n", destination1 );

Qui a produit ce résultat:

la destination est à l'origine = 'abcdefg'
Après strcpy, destination devient '123456789'

destination1 est à l'origine = 'abcdefg'
Après strncpy, destination1 devient "12345fg'

Ce qui me fait me demander pourquoi quelqu'un voudrait cet effet. Il semble qu'il serait source de confusion. Ce programme me fait penser que vous pourriez essentiellement de copier le nom de quelqu'un (par exemple. Tom Brokaw) avec Tom Bro763.

Quels sont les avantages de l'utilisation de strncpy() sur strcpy()?

210voto

caf Points 114951

L' strncpy() fonction a été conçue avec un très de problème particulier à l'esprit: manipulation de chaînes de caractères stockée dans la manière de l'UNIX d'origine des entrées du répertoire. Celles-ci ont utilisé un tableau de taille fixe, et un nul-terminator a été utilisé uniquement si le nom de fichier a été plus courte que la matrice.

Qu'est ce qui est derrière les deux bizarreries de l' strncpy():

  • Il ne met pas un nul-bouchon sur la destination si elle est complètement rempli; et
  • Il est toujours remplit complètement la destination, avec les nuls, si nécessaire.

Pour les plus sûrs strcpy()", vous êtes mieux d'utiliser strncat() comme:

if (dest_size > 0)
{
    dest[0] = '\0';
    strncat(dest, source, dest_size - 1);
}

Qui sera toujours nul à la fin de la raison, et de ne pas copier plus que nécessaire.

105voto

Eric Points 35647

strncpy combats de débordement de la mémoire tampon en vous demandant de mettre une longueur en elle. strcpy dépend d'un suiveur \0, qui peut ne pas toujours se produire.

Deuxièmement, pourquoi vous avez choisi de copier seulement 5 caractères sur 7 chaîne de caractères est au delà de moi, mais il s'agit de produire le comportement attendu. C'est la seule copie au cours du premier n personnages, où n est le troisième argument.

L' n fonctions sont utilisés comme défensive de codage contre les dépassements de tampon. Veuillez les utiliser en lieu et place des anciennes fonctions, telles que l' strcpy.

39voto

Sinan Ünür Points 76179

Bien que je sache l'intention derrière strncpy , ce n'est pas vraiment une bonne fonction. Évitez les deux. Raymond Chen explique .

Voir aussi Pourquoi strncpy n'est pas sécurisé?

28voto

David Cournapeau Points 21956

strncpy n'est PAS plus sûr que la fonction strcpy, il vient de métiers un type de bugs avec l'autre. En C, lors de la manipulation de chaînes C, vous devez connaître la taille de vos tampons, il n'y a pas moyen de contourner cela. strncpy était justifiée par le répertoire chose mentionné par d'autres, mais sinon, vous devriez ne jamais les utiliser:

  • si vous connaissez la longueur de votre chaîne et de la mémoire tampon, pourquoi utiliser strncpy ? C'est une perte de puissance de calcul au mieux (ajout inutile 0)
  • si vous ne connaissez pas les longueurs, alors vous risquez d'en silence tronquer vos chaînes, ce qui n'est pas beaucoup mieux qu'un dépassement de la mémoire tampon

23voto

tristopia Points 5074

Ce que vous cherchez est la fonction strlcpy qui arrête toujours de la chaîne de 0 et de ne procéder à l'initialisation de la mémoire tampon. Il est également capable de détecter les débordements. Seul problème, il n'est pas (vraiment) portable et n'est présent que sur certains systèmes (BSD, Solaris). Le problème avec cette fonction, c'est qu'il ouvre une autre boîte de pandore comme on peut le voir par les discussions sur http://en.wikipedia.org/wiki/Strlcpy

Mon opinion personnelle est qu'il est beaucoup plus utile que d' strncpy et strcpy. Il a un meilleur rendement et est un bon compagnon pour snprintf. Pour les plates-formes qui ne l'ont pas, il est relativement facile à mettre en œuvre. (pour la phase de développement d'une application-je remplacer ces deux fonction (snprinf et strlcpy) avec un piégeage version qui s'interrompt brutalement le programme sur les dépassements de tampon ou de troncatures. Cela permet de rattraper rapidement les pires contrevenants. Surtout si vous travaillez sur une base de code de quelqu'un d'autre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X