strcpy ... veulent remplacer par strcpy_mine qui strncpy et mettre fin à null
Question
l'indice est dans le titre, mais au fond, j'ai hérité du code qui a plus de 800 cas de strcpy. Je veux écrire une nouvelle fonction, puis de remplacer strcpy avec strcpy_mine.
Je suis en train de travailler sur ce que la liste des paramètres strcpy_mine aura.
J'ai essayé:
void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
strncpy( pTarget, pCopyMe, lenAlwaysFour );
//add extra terminator in case of overrun
pTarget[lenAlwaysFour] = 0;
}
mais le sizeof est toujours 4 pCopyMe est un pointeur
ce que je ne veux pas faire est de remplacer
strcpy (buf, pCopyMe);
avec
strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;
des idées? (Strcpy_l est non disponible)
hourras
La solution
Selon la façon dont les appels-sites ressemblent souvent majorité des cas peut être gérée par un modèle simple:
#include <string.h>
template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
strncpy( pTarget, pCopyMe, bufferSize-1 );
//add extra terminator in case of overrun
pTarget[bufferSize-1] = 0;
}
int main()
{
char buf[128];
strcpy_mine(buf,"Testing");
return 0;
}
Si vous utilisez Microsoft Visual Studio 2005 ou plus récent, voir
Autres conseils
renvoie la taille du type -. dans ce cas const char* const
qui sera 4 sur les machines 32 bits
Je pense que vous pensez que vous voulez strlen()
. Mais ce n'est pas la bonne façon d'utiliser les fonctions strncpy.
Vous avez besoin de la taille de la mémoire tampon sortie pour strncpy.
Pour corriger cela, vous devez examiner le code à chaque site d'appel, et le travail sur la taille de la mémoire tampon de sortie et passer que comme argument à strcpy_mine
. Si l'appel site pour strcpy (ou strcpy_mine) ne connaît pas la taille de la mémoire tampon de sortie, vous devez rechercher en arrière dans le code pour l'emplacement qui alloue la mémoire tampon, et passer la taille tout en bas du site strcpy .
Fondamentalement, vous ne pouvez pas écrire une baisse de remplacement pour strcpy qui prend les mêmes arguments et nous espérons éviter les problèmes qui ont produit strncpy en premier lieu (et meilleurs remplacements au-delà). Vous pouvez créer une fonction qui prend les mêmes arguments que strncpy, mais assure le résultat est nul terminé - regardez la mise en œuvre de la strlcpy OpenBSD () fonction. Mais la première étape doit être de changer les sites appelant à transmettre des connaissances de la taille de la mémoire tampon de sortie.
peut-être légèrement périphérique, mais comme mentionné Noone et il exhibait dans le titre:. Vous ne pouvez pas (légalement) écrire une fonction globale appelée strcpy_mine()
Le « espace de noms » des fonctions dont le nom commence par str
est réservé à la bibliothèque standard. Voir, par exemple, la réponse acceptée à cette question .
Vous pouvez utiliser la même liste de paramètres que strncpy pour votre strcpy_mine, mais écrire pour qu'il termine toujours le résultat nul. Ne devrait pas être très difficile à faire.
L'un des défis, cependant, est que certains de votre code existant qui appelle strcpy () peut ne pas connaître la taille du tampon, soit.
Vous pouvez aussi utiliser macroses pour éviter d'avoir plusieurs editings. Ou automatiser l'édition via un script.
Vous avez certainement besoin de passer de la taille de la mémoire tampon de destination en tant que paramètre, que d'autres personnes ont dit ci-dessus.
est un peu hors sujet, mais je veux juste souligner que, après avoir utilisé strncpy()
, vous devez définir null le dernier caractère de la mémoire tampon, qui a l'indice 1 moins à la longueur (pas la longueur de la mémoire tampon):
strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';
Ou bien, vous pouvez utiliser strncat()
sur une chaîne vide, en lui transmettant une longueur moins 1, et il garantit à nul mettre fin à votre chaîne:
buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);
Douglas Leeder a raison. Il y a une limite à l'utilité de remplacer strcpy à moins que vous êtes prêt à faire le travail grognement de passage dans une bonne longueur de tampon sain d'esprit à chaque instance. Cela fait beaucoup de travail!
Les bonnes nouvelles sont, il vaut la peine! Retour il y a quelques années, je suis venu sur plusieurs projets C ++ qui étaient en retard, buggy, et peu fiables. En déclarant strcpy et strlen interdit, et prendre 2-3 jours sur le projet de les remplacer par strncpy personnalisée / strnlen, dans tous ces projets, nous pourrions soudainement courir pendant des jours au lieu des heures. Nous avons vu aussi beaucoup de cordes tronquées sortent sur les écrans d'écran et les fichiers journaux. Cela nous a donné les indices nécessaires pour traquer les problèmes de troncature, les questions autrefois s'écraser.
Si vous ne voulez pas le faire, vous pouvez obtenir un avantage beaucoup plus petit en vérifiant simplement les paramètres de pointeur NULL, et de limiter la taille maximale d'une copie de chaîne et connecter tout le temps que la limite est atteinte. ne pas faire strlen de l'un des paramètres, comme strlen va se planter joyeusement sur vous si la chaîne est pas correctement null terminée.
De nos jours, de nouveaux projets utilisent des objets de bonne chaîne, mais il y a beaucoup de code existant là-bas qui ne fonctionne pas.