Guide

Guide complet : Comparaison entre strcpy et strncpy

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, \0 n’est pas ajouté automatiquement.
  • Prototype : char *strncpy(char *destination, const char *source, size_t n);

2. Différences fondamentales

Aspectstrcpystrncpy
Copie complèteCopie 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.
PerformanceLégèrement plus rapide (moins de vérifications).Légèrement plus lente (vérification de limite).
Utilisation typiqueCopie 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 destination est 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 \0 manuellement 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 n caractères, mais n’ajoute pas automatiquement le caractère nul.

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).

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.

5. Bonnes pratiques

5.1 Quand utiliser strcpy

  • La taille de destination est garantie suffisante pour contenir source.
  • 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 destination est 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èrestrcpystrncpy
Terminaison par \0ToujoursNon garanti si la source dépasse la limite
Gestion de dépassementNon sécurisé, dépassement possibleLimite la copie
Remplissage restantAucun remplissageRemplit les caractères restants avec \0
PerformancePlus rapideLégèrement plus lent
Utilisation idéaleCopie complète lorsque la taille est sûreCopie 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 strncpy pour éviter les dépassements de mémoire.
  • Ajoutez systématiquement \0 après une copie partielle avec strncpy.
  • Pour une sécurité accrue, utilisez des alternatives comme snprintf ou strlcpy si disponibles.

Autres articles

Fiche Ressources : Méthode de Lecture Paul...
La méthode de lecture Paul et Suzanne est une méthode...
Read more
Rédiger un Rapport d’Activité avec un Plan...
Le rapport d’activité avec un plan thématique est une méthode...
Read more
Guide : Les Différents Plans d'un Rapport...
Un rapport d'activité est un document clé pour présenter les...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *