Guide complet : Comparaison entre strcpy et strncpy
Recommandés
En C, les fonctions strcpy et strncpy servent à copier des chaînes de caractères d’une source à une destination. Bien qu’elles soient similaires, elles diffèrent en termes de fonctionnement, sécurité, et cas d’utilisation. Ce guide explique leurs différences et propose des exemples pratiques.
1. Introduction
1.1 strcpy
- But : Copier une chaîne entière, y compris le caractère nul (
\0), d’une source vers une destination. - Limitation majeure : Ne vérifie pas si la destination a suffisamment d’espace pour contenir la source, ce qui peut entraîner un buffer overflow.
- Prototype :
char *strcpy(char *destination, const char *source);
1.2 strncpy
- But : Copier un nombre spécifié de caractères d’une source vers une destination, limitant ainsi la quantité de données copiées.
- Limitation majeure : Si la source dépasse la taille spécifiée,
\0n’est pas ajouté automatiquement. - Prototype :
char *strncpy(char *destination, const char *source, size_t n);
2. Différences fondamentales
| Aspect | strcpy | strncpy |
|---|---|---|
| Copie complète | Copie toute la chaîne jusqu’à \0. | Copie jusqu’à n caractères maximum. |
Caractère nul (\0) | Toujours ajoute \0. | N’ajoute pas \0 si la source dépasse n. |
| Sécurité | Ne vérifie pas la taille de destination. | Limite la copie pour éviter les dépassements. |
| Performance | Légèrement plus rapide (moins de vérifications). | Légèrement plus lente (vérification de limite). |
| Utilisation typique | Copie complète d’une chaîne connue pour être sûre. | Copie partielle ou sécurisée avec limite de taille. |
3. Comparaison pratique
Exemple avec strcpy
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Bonjour";
char destination[10];
strcpy(destination, source); // Copie toute la chaîne
printf("Source : %s\n", source);
printf("Destination : %s\n", destination);
return 0;
}
- Avantage : Simple, copie toute la chaîne.
- Risque : Si
destinationest trop petite, il y a un buffer overflow.
Exemple avec strncpy
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Bonjour";
char destination[5];
strncpy(destination, source, sizeof(destination) - 1); // Limite à 4 caractères
destination[sizeof(destination) - 1] = '\0'; // Ajouter manuellement `\0`
printf("Source : %s\n", source);
printf("Destination : %s\n", destination);
return 0;
}
- Avantage : Empêche les dépassements de mémoire en limitant la copie.
- Risque : L’utilisateur doit ajouter
\0manuellement si nécessaire.
4. Cas particuliers
4.1 Si destination est trop petite
- Avec
strcpy:- Provoque un dépassement de mémoire (buffer overflow), écrasant potentiellement d’autres données.
- Avec
strncpy:- Copie uniquement les premiers
ncaractères, mais n’ajoute pas automatiquement le caractère nul.
- Copie uniquement les premiers
Solution pour strncpy :
Toujours ajouter \0 après la copie :
destination[n - 1] = '\0';
4.2 Si la source est plus courte que la limite spécifiée
- Avec
strcpy:- Fonctionne correctement.
- Avec
strncpy:- Copie toute la chaîne, mais remplit les caractères restants de la destination avec des zéros (
\0).
- Copie toute la chaîne, mais remplit les caractères restants de la destination avec des zéros (
Exemple :
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "C";
char destination[5];
strncpy(destination, source, sizeof(destination)); // Remplit le reste avec `\0`
printf("Destination : ");
for (int i = 0; i < sizeof(destination); i++) {
printf("%c ", destination[i] == '\0' ? '_' : destination[i]); // Affiche `_` pour les zéros
}
printf("\n");
return 0;
}
4.3 Si la chaîne source est vide
- Avec
strcpy:- Copie simplement le caractère nul.
- Avec
strncpy:- Même comportement si
n >= 1.
- Même comportement si
5. Bonnes pratiques
5.1 Quand utiliser strcpy
- La taille de
destinationest garantie suffisante pour contenirsource. - Vous êtes certain que les données sont sûres (pas de risque de dépassement).
Exemple sécurisé :
char destination[50];
char source[] = "Texte sûr";
if (strlen(source) < sizeof(destination)) {
strcpy(destination, source);
}
5.2 Quand utiliser strncpy
- Lorsque la taille de
destinationest limitée ou doit être respectée. - Pour copier uniquement une partie de
source.
Astuce pour éviter les erreurs :
Ajoutez toujours \0 après une copie partielle avec strncpy.
6. Alternatives modernes
6.1 snprintf
Offre une sécurité accrue en limitant la taille de la chaîne copiée tout en s’assurant qu’elle est terminée par \0.
Exemple :
#include <stdio.h>
int main() {
char source[] = "Bonjour";
char destination[5];
snprintf(destination, sizeof(destination), "%s", source);
printf("Destination : %s\n", destination);
return 0;
}
6.2 strlcpy (non standard, disponible sur certains systèmes)
Limite la taille copiée tout en garantissant la terminaison par \0.
Exemple :
#include <bsd/string.h>
char destination[5];
strlcpy(destination, source, sizeof(destination));
7. Tableau comparatif
| Critère | strcpy | strncpy |
|---|---|---|
Terminaison par \0 | Toujours | Non garanti si la source dépasse la limite |
| Gestion de dépassement | Non sécurisé, dépassement possible | Limite la copie |
| Remplissage restant | Aucun remplissage | Remplit les caractères restants avec \0 |
| Performance | Plus rapide | Légèrement plus lent |
| Utilisation idéale | Copie complète lorsque la taille est sûre | Copie partielle ou sécurisée |
8. Exercices corrigés
Exercice 1 : Copie sécurisée avec strncpy
Allouez un tableau dynamique pour copier une chaîne de manière sécurisée avec strncpy.
Solution :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char source[] = "Programmation C";
size_t max_size = 10;
char *destination = (char *)malloc(max_size);
if (destination == NULL) {
printf("Erreur d'allocation mémoire.\n");
return 1;
}
strncpy(destination, source, max_size - 1);
destination[max_size - 1] = '\0'; // Assurez la terminaison
printf("Destination : %s\n", destination);
free(destination);
return 0;
}
Exercice 2 : Différences entre strcpy et strncpy
Copiez une chaîne de 15 caractères dans une destination de 10 caractères. Comparez le comportement de strcpy et strncpy.
Solution :
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Chaîne très longue";
char destination1[10];
char destination2[10];
// Utilisation de strcpy (comportement indéfini)
// strcpy(destination1, source); // Peut causer un buffer overflow
// Utilisation de strncpy
strncpy(destination2, source, sizeof(destination2) - 1);
destination2[sizeof(destination2) - 1] = '\0';
printf("Avec strncpy : %s\n", destination2);
return 0;
}
9. Conclusion
Résumé
strcpy: Rapide et simple, mais non sécurisé.strncpy: Plus sûr, mais nécessite une gestion manuelle de\0.
Recommandations
- Préférez
strncpypour éviter les dépassements de mémoire. - Ajoutez systématiquement
\0après une copie partielle avecstrncpy. - Pour une sécurité accrue, utilisez des alternatives comme
snprintfoustrlcpysi disponibles.



