IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèque standard C Discussion :

Utilité de strncpy


Sujet :

Bibliothèque standard C

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 100
    Par défaut Utilité de strncpy
    Bonjour

    je ne vois spas l'utilite de strncpy
    puisque a chaque fois que j el'utilise j'ai besoin de mettre le dernier caracter a '\0'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char buffer [10];
     
    strncpy(buffer, "bonjour Les Amis", 10);
    buffer[9] = '\0';
    je pense que c'est equivalent a

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char buffer [10];
     
    memcpy(buffer, "bonjour Les Amis", 10);
    buffer[9] = '\0';
    et enplus rapide
    car je pense que strncpy fait copie caractere par caractere tout en testant a chaque fois si le caracter = '\0'


    Tout commentaire est le bienvenu

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char buffer[10] = {0};
    strncat (buffer, "chaine", 9);
    Mais de toute façon, on a trop vite fait de faire des erreurs avec ces fonctions, l'idéal est d'avoir un système ou une bibliothèque qui implémente strlcpy/strlcat et là le comportement est sûr.

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut la doc dit...
    The strncpy() function copies at most n characters from s2 into s1. If
    s2 is less than n characters long, the remainder of s1 is filled with
    `\0' characters. Otherwise, s1 is not terminated.

    => Ca termine 'bien' la chaine de destination lorsque 'n' est >strlen(s2).
    Et quelque part c'est bien ce qu'on veut non?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    The strncpy() function copies at most n characters from s2 into s1. If
    s2 is less than n characters long, the remainder of s1 is filled with
    `\0' characters. Otherwise, s1 is not terminated.

    => Ca termine 'bien' la chaine de destination lorsque 'n' est >strlen(s2).
    Et quelque part c'est bien ce qu'on veut non?
    - W
    http://www.developpez.net/forums/sho...32#post3383032

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    => Ca termine 'bien' la chaine de destination lorsque 'n' est >strlen(s2).
    Et quelque part c'est bien ce qu'on veut non?
    - W
    Généralement ce que l'on veut avec des fonctions de manipulation de chaînes c'est obtenir une chaîne valide au final. Ce qui n'est pas le cas avec strncpy() si la chaîne d'origine est plus longue que n (il n'y a pas la \0 terminal dans ce cas).

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut
    Citation Envoyé par gl Voir le message
    Généralement ce que l'on veut avec des fonctions de manipulation de chaînes c'est obtenir une chaîne valide au final. Ce qui n'est pas le cas avec strncpy() si la chaîne d'origine est plus longue que n (il n'y a pas la \0 terminal dans ce cas).
    Certes mais lorsqu'on demande de recopier une chaine de caractères dans un buffer plus petit, tronquer est une option et il faut bien que le codeur précise d'une façon ou d'une autre ce qu'il veut.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Les chaînes de caractères en C sont terminées par un NUL byte, la fonction strncpy dans certain cas comme ceux exposés juste avant, ne rend pas une chaîne valide (i.e terminé par un NUL byte), il y a donc bien un bug.

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Certes mais lorsqu'on demande de recopier une chaine de caractères dans un buffer plus petit, tronquer est une option
    C'est plus qu'une option. Dans ce cas de figure il faudra forcement tronquer la chaîne.

    Citation Envoyé par wiztricks Voir le message
    et il faut bien que le codeur précise d'une façon ou d'une autre ce qu'il veut.
    Justement, s'il utilise une fonction str...() c'est bien dans le but d'obtenir une chaîne valide et donc terminée par un \0 terminal.

    Si le but recherche est simplement de copier des octets d'un tableau dans un autre, sans se préoccuper de la notion de chaîne de caractère, strncpy() n'est pas un bon choix, memcpy() ou memmove() sont prévus pour de telles opérations.

    En outre, ce qui est clairement problématique, c'est d'avoir des comportements différents selon la fonction utilisée (strncpy() n'ajoute pas toujours le \0 terminal, strncat() ou snprintf() si).

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut strlcpy tronque et retourne une 'chaine' de caractère terminée par 0
    strncpy fait ce qu'il est supposé faire...
    Si vous voulez que la chaine soit tronquée, vous pouvez utiliser "strlcpy".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Le but de strncpy n'est pas de tronquer une chaîne mais bien de limiter la longueur de la copie (éviter un buffer overflow).
    strlcpy n'est malheureusement pas standard... mais facilement implantable.

  11. #11
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD Voir le message
    ...
    car je pense que strncpy fait copie caractere par caractere tout en testant a chaque fois si le caracter = '\0'


    Tout commentaire est le bienvenu
    Quelques détails sur les deux fonctions (et les autres si tu veux également) :

    memcpy
    strncpy

    Le mieux bien entendu et comme ca l'a déjà été dit, c'est de se construire sa propre bibliothèque (comme la mienne: http://franckh.developpez.com/cstr/) de gestion de chaîne pour éviter certaines erreurs récurrentes comme des buffer overflow (entre autres).
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Le mieux bien entendu et comme ca l'a déjà été dit, c'est de se construire sa propre bibliothèque (comme la mienne: http://franckh.developpez.com/cstr/) de gestion de chaîne pour éviter certaines erreurs récurrentes comme des buffer overflow (entre autres).
    La vie est trop courte pour refaire ce qui a déjà été fait et est disponible.
    Si on souhaite de meilleurs 'types', C++ a été fait pour cela et contient les libraries qui vont bien prêtes à l'emploi.
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    La vie est trop courte pour refaire ce qui a déjà été fait et est disponible.
    Si on souhaite de meilleurs 'types', C++ a été fait pour cela et contient les libraries qui vont bien prêtes à l'emploi.
    -W
    Premièrement, il existe un tas de bibliothèques en C pour la gestion des chaînes,
    secondement, le C++ n'est pas disponible partout.

  14. #14
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 676
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Premièrement, il existe un tas de bibliothèques en C pour la gestion des chaînes, secondement, le C++ n'est pas disponible partout.
    Ce que je voulais dire est préférable d'utiliser des 'standards' quand ils existent quitte à changer de langage de programmation.

    Sans critiquer leurs qualités, les bibliothèques 'non standards' ont rarement été portées, testées et utilisées 'partout' - excepté peut être la Glib -.
    Dans ces conditions, 'choisir' et maintenir peut devenir embarrassant.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Sans critiquer leurs qualités, les bibliothèques 'non standards' ont rarement été portées, testées et utilisées 'partout' - excepté peut être la Glib -.
    Dans ces conditions, 'choisir' et maintenir peut devenir embarrassant.
    globalement, avec les fonctions standards (strcpy, strcat, et strdup) et un algo correct, cela suffit.

    A quelques exceptions d'optimisation près, je n'ai jamais eu à utiliser autre chose.

    Je pense que la plupart des besoins de choses non-standard provient d'une mauvaise analyse/conception...

  16. #16
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD Voir le message
    je ne vois spas l'utilite de strncpy
    Moi non plus. J'utilise strncat().

  17. #17
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 100
    Par défaut
    je pense qu'une bonne utilisation de strncpy est la suivante

    initialiser toujours la tableau de caracteres a '\0'
    pusi faire un strncpy avec une taille max = taille du tableau -1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    memset(buffer, 0, sizeof(buffer));
    strncpy (buffer, "bonjour les amis", MAX_BUFFER -1 );

    par contre la question que je me pose est Est-ce que c'est plus interessant que le code suivants ( de point de vue performance)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    memset(buffer, 0, sizeof(buffer));
    memccpy(buffer, "bonjour les amis", 0, MAX_BUFFER -1);

  18. #18
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD Voir le message
    je pense qu'une bonne utilisation de strncpy est la suivante

    initialiser toujours la tableau de caracteres a '\0'
    pusi faire un strncpy avec une taille max = taille du tableau -1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    memset(buffer, 0, sizeof(buffer));
    strncpy (buffer, "bonjour les amis", MAX_BUFFER -1 );

    par contre la question que je me pose est Est-ce que c'est plus interessant que le code suivants ( de point de vue performance)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    memset(buffer, 0, sizeof(buffer));
    memccpy(buffer, "bonjour les amis", 0, MAX_BUFFER -1);
    C'est quand même super compliqué...

    Personnellement, soit j'utilise ma fonction STR_safecopy()

    http://emmanuel-delahaye.developpez....theque-clib-c/
    Module STR

    soit strncat() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       char buffer[10] ;
       *buffer = 0;
        strncat (buffer, "bonjour les amis", sizeof buffer - 1);

  19. #19
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    memset(buffer, 0, sizeof(buffer));
    strncpy (buffer, "bonjour les amis", MAX_BUFFER -1 );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #define MAX_BUFFER 10
    
    char buffer[MAX_BUFFER ] = {0}; /* memeset inutile */
    strncpy (buffer, "bonjour les amis", MAX_BUFFER -1 );
    mais ça n'est pas optimal puisqu'on affecte des caractères pour rien ...
    un code pas très élégant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define MAX_BUFFER 10
     
    char buffer[MAX_BUFFER ] ;
    strncpy (buffer, "bonjour les amis", sizeof buffer -1 );
    buffer[sizeof buffer - 1] = 0;
    évidemment la solution proposer par Emmanuel est la meilleure.

  20. #20
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 98
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    globalement, avec les fonctions standards (strcpy, strcat, et strdup) et un algo correct, cela suffit.

    A quelques exceptions d'optimisation près, je n'ai jamais eu à utiliser autre chose.

    Je pense que la plupart des besoins de choses non-standard provient d'une mauvaise analyse/conception...
    Non. Les fonctions de la lib C standard pour la manipulation de chaînes de caractères sont dangereuses. Elles sont l'une des plus grande source de bugs et de trous de sécurité dans les loigiciels créés dans ce langage, c'est un fait connu et mesuré. Microsoft, depuis qu'ils ont mis la sécurité comme priorité dans leurs logiciels, a viré tous les appels à ces fonctions dans leurs logiciels.
    Le conseil d'utiliser strlcpy/strlcat à la place de strcpy/strncpy strcat/strncat est pour moi un bon conseil. Mais encore bcp mieux est effectivement d'écrire ou d'utiliser une classe du style C_str citée ci-dessus, qui non seulement sécurise le code, mais simplifie et éclaircit considérablement le codage, car on n'a plus jamais à faire de calculs de longueurs. Si on crée une classe similaire pour les buffers de chars (tableaux non terminés par '\0'), un avantage supplémentaire est que dans un certains nombre de cas, on n'a plus besoin de passer de longueurs dans les interfaces, qui sont ainsi considérablement simplifiées. Cela simplifie aussi le code, car nombre de vérifications que l'on fait dans le code du style if (machaine == NULL) { ... erreur ... } et autres if(strlen(machaine > MAXLEN)) peuventnt être directement gérées par la classe elle-même.

Discussions similaires

  1. Utilité d'un pointeur vers une fonction ?
    Par Nasky dans le forum C
    Réponses: 10
    Dernier message: 20/03/2010, 19h54
  2. [J2EE] Utilité de la J2EE de SUN ?
    Par PeteMitchell dans le forum Java EE
    Réponses: 4
    Dernier message: 14/05/2004, 10h29
  3. [LG]Utilité du type enuméré ?
    Par tarbala dans le forum Langage
    Réponses: 2
    Dernier message: 10/12/2003, 16h20
  4. Le BIOS et son utilité
    Par le mage tophinus dans le forum Assembleur
    Réponses: 75
    Dernier message: 21/11/2003, 15h37
  5. utilité du binaire et hexadecimaux?
    Par souris78 dans le forum C
    Réponses: 9
    Dernier message: 01/07/2003, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo