strncpy()
ne fait pas ce que vous pensez probablement qu'il fait.
strncat()
est une version «plus sûre» de strcat()
qui vous permet de spécifier la taille de la matrice cible.
strncpy()
est n'est pas la version "plus sûre" correspondante de strcpy()
. Si le tableau cible est trop grand, strncpy()
le remplira par des caractères nuls; 99% du temps, cela est inutile, car vous n'avez besoin que d'un seul '\0'
pour marquer la fin d'une chaîne. Pire, si le tableau cible est trop petit, strncpy()
va copier autant de caractères qu'il le peut et laisser la cible non terminée.
strncpy()
a été conçu pour une structure de données obscure utilisée par les premiers systèmes Unix pour stocker les noms de fichiers. Un nom de fichier était stocké dans une mémoire tampon de 14 octets de longueur fixe complétée par des octets nuls. Si le nom de fichier avait exactement 14 caractères, il n'y aurait pas de terminateur nul. Ce n'est pas une chaîne.
Dans le cas peu probable que ce soit le type de structure de données que vous voulez, alors strncpy()
est juste l'affaire. Sinon, ne l'utilisez pas; il suffit d'utiliser strcpy()
après avoir confirmé que la cible est assez grande.
Voilà comment je pourrais écrire cette fonction:
void function(char *a, char *b)
{
char newStr[100];
/* Make newStr an empty string so you can concatenate onto it */
newStr[0] = '\0';
strncat(newStr, a, sizeof newStr - 1); /* edited */
strncat(newStr, b, sizeof newStr - strlen(newStr) - 1); /* edited */
/* Presumably you do something with newStr here */
}
Notes:
- Déclare le type de retour de la fonction. Si vous ne le déclarez pas explicitement, votre compilateur sera probablement
int
par défaut, mais c'est un mauvais style et une fonctionnalité de langage obsolète.
- Évitez
strncat()
.
- J'ai utilisé
'\0'
, et non NULL
, pour mettre fin à la chaîne. NULL
est un zéro pointeur constante; ne l'utilisez pas pour indiquer un caractère nul .
Il y a une inefficacité importante ici: la deuxième strncat()
doit re-numérisation depuis le début de newStr
. Pour un petit nombre de chaînes courtes, ce n'est pas une grosse affaire, mais pour un grand nombre de chaînes qui sont converties en un grand tableau cible, cela peut causer de sérieux ralentissements. Il existe des moyens de contourner ce problème, mais ils sont soit non standard (strlcpy()
, strlcat()
) ou incommodes.
EDIT: Merci à Matthew d'avoir signalé des erreurs dans mon code. Je pense Je les ai fixés; Je suis sûr que je peux compter sur quelqu'un pour me frapper au-dessus de la tête si j'ai remplacé les vieilles erreurs par de nouvelles.
Une alternative est:
snprintf(newStr, sizeof newStr, "%s%s", a, b);
Ce doit être l'un des griefs les plus ennuyeux avec C - le fait que 'strncpy' ne * pas * retourner le nombre d'octets écrits ou un pointeur vers la fin, mais plutôt un pointeur vers le début (que nous connaissons déjà, puisque c'est l'un des arguments) ... –
Même si vous avez besoin de mettre fin à la chaîne vous-même, 'NULL' est la mauvaise chose à utiliser. C'est une constante null * pointeur *. Un caractère nul est ''\ 0'' (ou juste' 0'). –
@KerrekSB: 'strncpy' est une relique d'une autre époque - elle n'a jamais été utilisée pour remplacer' strcpy'. Utilisez 'strlcpy' à la place, bien qu'il ne soit pas disponible partout. –