7
votes

Strncpy et en utilisant Taillef pour copier des caractères maximaux

J'utilise le code ci-dessous

call[strlen(call) - 1] = '\0'; /* insert a null at the last element.*/


0 commentaires

7 Réponses :


4
votes

Votre idée:

call[strlen(call) - 1] = '\0';


0 commentaires

7
votes

Si la longueur de la source est moins que le numéro maximum passé sous la forme du troisième paramètre Strncpy sera null-terminer la destination, sinon, pas.

Si la source est égale ou supérieure à celle du Destination - C'est votre problème de faire face à cela. Faire comme vous le suggérez - appeler Strlen () - ne fonctionnera pas car le tampon ne sera pas résilié de manière null et vous rencontrerez un comportement indéfini.

Vous pouvez attribuer un plus grand tampon: < Pré> xxx


0 commentaires

15
votes

strncpy sera pas NULL-Terminez la destination si elle tronque la chaîne. Si vous devez utiliser strncpy , vous devez vous assurer que le résultat est terminé, quelque chose comme: xxx

strlcpy () , parmi d'autres, est généralement considérée comme supérieure:

http: / /wwww.openbsd.org/cgi-bin/man.cgi?query=strlcpy


6 commentaires

Un moyen simple d'assurer la destination est nul terminé ici est d'appeler [Tailleof Call -1] = 0;


Je ne pensais pas que Strncpy mettrait fin à la chaîne. En ne terminant pas la chaîne. Cela pourrait-il conduire à un vrai problème? Aussi, en faisant cet appel [Strlen (info.called - 1] = '\ 0'; ce que c'est la bonne façon de terminer si la source est supérieure ou inférieure à la destination? Merci.


Oui, une chaîne non détermine provoquera Strlen () , strcat () , etc., soit faux, mémoire corrompu et / ou crash. Réglage du dernier octet du tampon à zéro ne fait rien endommager lorsque la chaîne est plus courte que la destination, il n'y a donc vraiment aucune raison de le rendre conditionnel.


Si vous utilisez VC ++, je recommanderais d'utiliser StrncPy_s, ce qui garantit que les chaînes sont toujours terminées.


+1 pour la comptabilisation de la résiliation, mais je pense que la fin de la chaîne est une mauvaise idée. Considérons (un exemple artificiel) de cette chaîne finale utilisée ultérieurement pour supprimer récursivement un arbre de répertoire ...


L'autre astuce de Strncpy () est que cela est toujours complètement nul-patins la chaîne cible à la longueur spécifiée lorsque la source est plus courte que la cible. Cela compte si vous copiez 32 octets de données dans un tampon de 4 Ko; Outre les 32 octets de données, il copiera 4064 caractères «\ 0» - qui peuvent devenir un problème. À mon avis, Strncpy () a été conçu pour copier des composants de nom de fichier comptant jusqu'à 14 caractères dans la partie de nom de fichier d'une ancienne entrée de répertoire UNIX. La partie de nom de fichier comptait jusqu'à 14 caractères, NULL rembourré mais non terminé NULL (et les deux octets précédents étaient un numéro d'inode de 2 octets).



1
votes

Mais je me demande maintenant s'il sera null terminer la destination. P>

Non, Strncpy ne promet pas que la chaîne cible serait null terminée. p>

strncpy(traget,string,sizeof(target)-1);
target[sizeof(target)-1]=0

2 commentaires

Je me demande simplement. Y a-t-il une réelle différence d'utiliser Strlen ou Taillef?


Taillef est constante, il renvoie la taille de l'objet, lorsque Strlen calcule en réalité en exécution de la longueur de la chaîne. Par exemple pour char goudron [2] = {0,0}; tailleof (goudron) == 2 mais SHLEN (goudron) == 0;



1
votes

1) de Cplusplus.com : "Pas de caractère null est implicitement ajouté à la fin de la destination, la destination ne sera donc terminée que si la longueur de la chaîne C dans la source est inférieure à Num. " Donc, si vous avez besoin de votre chaîne pour que votre chaîne soit résiliée, vous devez le faire:

call[sizeof(call) - 1] = '\0';


0 commentaires

1
votes

Utilisez simplement strlcpy () au lieu de Strncpy (). Vous devrez vérifier s'il est disponible sur toutes les plateformes. Les premières versions de Linux ne l'ont probablement pas.


1 commentaires

Ce n'est pas une fonction standard. Ce n'est peut-être pas disponible.



1
votes

Utilisez Strlcpy de la même manière que Strncpy. Pas besoin de faire la taille-1 en 3ème paramètre

I.e: Strncpy (appel, info.Called, taille de (appel) -1); ou strlcpy (appel, info.Called, taille de (appel));


2 commentaires

Qu'est-ce que -1 est censé faire ici? Il ne changera que le problème par un octet. Si la chaîne ne correspond pas à Tailleof (appel) -1 octets, le dernier élément restant ne sera toujours pas rempli avec 0 . L'utilisation de strlcpy a également été suggérée il y a 6 ans.


Cela ne fonctionne que si le tampon de destination a été effacé à 0 avant l'appel. Pas très utile pour l'utilisation générale.