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

 C Discussion :

Manipulation des chaines de caractere


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 102
    Par défaut Manipulation des chaines de caractere
    Bonsoir a tous,

    voilà dans un projet que j'ai a faire j'ai besoin de copier et concaténer des chaines de tailles variable (chaine vide compris). Le problème c'est que j'ai du mal à utiliser strcpy et strcat.
    en fait le problème viens surtout du fait que je peux avoir dans strcpy et strcat 2 chaine vide ou même la chaine en premier argument de taille plus petite(voir vide) que la chaine en second argument. j'utilise des char *.

    J'aurais voulu savoir si c'est moi qui utilise mal ces fonctions, ou si il existe d'autre fonction pour pouvoir le faire sans itérations^^.

    Ha oui une dernière question : est il possible d'afficher avec printf une chaine vide? car j'ai essayé mais ça m'affiche des caractères blizzards^^

    voili voilu

    merci d'avance pour votre aide

    Yann

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Tu dois toujours t'assurer que les tampons que tu passes en 1er argument de strcat() ou strcpy() sont de taille suffisante pour l'opération recherchée. Pour éviter les débordements, il faut soit:
    • Utiliser l'allocation dynamique de mémoire pour t'assurer que le buffer cible possède la taille adéquate.
    • Si tu ne peux utiliser l'allocation dynamique, utilise de préférence les fonctions strncat() et strncpy() pour te protéger des débordements de mémoire (J'utilise personnellement strncat() pour la copie et la contanénation).


    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    On peut afficher une chaîne vide avec printf(), mais il faut respecter la notion standard de "chaîne vide" : Une chaîne vide n'est pas un tableau de caractères non-initialisé : C'est un tableau de caractères dont le premier est le caractère nul.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 102
    Par défaut
    merci pour vos reponse,

    donc si je comprend bien, pour strcpy(x,y) il faut que je fasse un malloc sur le x de la taille de y (en utilisant strlen ça doit passer non et de la somme des deux tailles pour strcat?)

    en ce qui concerne l'utilisation de strncat et strncpy je vais voir si ça me conviens.

    pour en revinir au chaine vide, quand je declare un char * x sans l'initialiser si je fais une concatenation, ça va marcher, ou j'ai besoin aussi de faire une initialisation?

    voili voilou, merci encore

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Pour appeler strcpy(x, y), le tampon x doit être de taille au moins égale à strlen(y) + 1. En ce qui concerne strcat(x, y), la taille de x doit être au moins égale à strlen(x) + strlen(y) + 1.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 102
    Par défaut
    donc si je comprend bien ça donen un truc comme ça

    pour strcpy(x,y)
    char * x;
    char *y --y recoit une valeur au cour du programme
    x=(char *)malloc((strlen(y)+1)*sizeof(char));
    strcpy(x,y);

    mais bon il me semble que j'ai testé sans le +1 et que ça marche.

    En tout cas merci pour la reponse, je me sui débloqué maintenant.

  7. #7
    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 Darksnakes Voir le message
    mais bon il me semble que j'ai testé sans le +1 et que ça marche.
    Hasard .....

    Mais non reproductible et potentiellement fatal....

    Il FAUT la place pour le '\0'...

    Maintenant sizeof(char) == 1 par defintion.


    Il faut tester si l'allocation s'est bien passee avant de copier dedans.


    Et pour finir ( aux autres) tu n'es pas oblige de caster le retour...

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    [*]Si tu ne peux utiliser l'allocation dynamique, utilise de préférence les fonctions strncat() et strncpy()
    Attention, elles sont toutes les deux piègeuses (strncpy(d, s, n) écrit toujours n caractères et le dernier n'est pas nécessairement \0; strncat(d, s, n) peut écrire n+1 caractères).

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Attention, elles sont toutes les deux piègeuses (strncpy(d, s, n) écrit toujours n caractères et le dernier n'est pas nécessairement \0; strncat(d, s, n) peut écrire n+1 caractères).
    Oui, j'aurais du le préciser. Personnellement, j'utilise tout le temps strncat(), même pour la copie, sous la forme suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char * str_n_cpy(char *dest, char const *src, size_t dest_size)
    {
        if (dest != NULL && src != NULL && dest_size > 0)
        {
            dest[0] = 0;
            strncat(dest, src, dest_size - 1);
        }
     
        return dest;
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char * str_n_cat(char *dest, char const *src, size_t dest_size)
    {
        if (dest != NULL && src != NULL && dest_size > 0)
        {
            strncat(dest, src, dest_size - strlen(dest) - 1);
        }
     
        return dest;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 102
    Par défaut
    Effectivement, sans le +1 je me suis aperçu que ça marchait pas . Maintenant ça marche parfaitement. Merci beaucoup pour cette aide précieuse.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Attention, elles sont toutes les deux piègeuses (strncpy(d, s, n) écrit toujours n caractères et le dernier n'est pas nécessairement \0; strncat(d, s, n) peut écrire n+1 caractères).
    Je ne comprends pas que le comité ai accepté de normaliser de telles fonctions (surtout strncpy).

    Peut-être, quelqu'un va me dire "certes, mais gets est pire".

    Réponse : non, pour moi, la présence de gets dans la norme n'est pas pire que celle de strncpy, parce qu'au moins gets ne prétend pas être la solution à un problème de dépassement de tampon. (De nombreux bouquins/sites présentent strncpy comme faisant partie de la solution et gets faisant partie du problème, aucun ne présente gets comme faisant partie de la solution.)

    Pour ce qui est de la relecture/vérification du code, l'usage de gets a le bon gout de (quasiment) toujours être un bug.

  12. #12
    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 : 48
    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 Darksnakes Voir le message
    Effectivement, sans le +1 je me suis aperçu que ça marchait pas . Maintenant ça marche parfaitement. Merci beaucoup pour cette aide précieuse.
    Tu peux aussi te fabriquer ton propres objet de gestion des chaînes de caractères, un peu comme ce qu'on retrouve sur les langage de plus haut niveau, surtout dans la POO plus particulièrement et cela fait un bon exercice. Puis ca te sera de toutes façon utile un jour ou un autre. Tu peux voir mon propre objet String ici
    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 !

  13. #13
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par corrector Voir le message
    Je ne comprends pas que le comité ai accepté de normaliser de telles fonctions (surtout strncpy).
    Il y a au moins trois tendances dans la normalisation de languages: décrire ce qui est commun dans les implémentations existantes, prescrire en disant ce qui est bon, inventer de qu'on considère utile. Les trois sont sensées mais entre en conflit. La présence de strncpy est visiblement le résultat de la première, tu t'en plains au nom de la seconde.

    Réponse : non, pour moi, la présence de gets dans la norme n'est pas pire que celle de strncpy, parce qu'au moins gets ne prétend pas être la solution à un problème de dépassement de tampon.
    strncpy n'est pas une solution à un problème de dépassement et n'a jamais été conçu pour. C'est une fonction très spécialisée, destinée au départ au remplissage de certaines structures de données d'unix qui a été utilisée ailleurs
    et s'est retrouvé dans la norme on ne sait pas trop comment.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Il y a au moins trois tendances dans la normalisation de languages: décrire ce qui est commun dans les implémentations existantes, prescrire en disant ce qui est bon, inventer de qu'on considère utile. Les trois sont sensées mais entre en conflit. La présence de strncpy est visiblement le résultat de la première, tu t'en plains au nom de la seconde.
    Décrire et normaliser ce qui existe et qui est utile, je préfèrerai.

    Je m'en plains parce que c'est inutile - sauf pour des choses comme écrire les noms de fichier dans les entrées de répertoires du système de fichier (aujourd'hui obsolète) ext -, et que c'est dangereux quand on l'utilise pour autre chose, où du moins ça complique le code, et surtout la relecture (et donc ça distrait le relecteur, et donc c'est dangereux indirectement).

    (Sur le fait que les utilisateurs n'ont qu'à pas être idiots et à utiliser les fonctions pour ce pour quoi elles sont faites, je réponds qu'il y a la racine "str" : c'est la seule fonction en str.* qui produise une sortie qui n'est pas NUL-terminée, il me semble.)

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    strncpy n'est pas une solution à un problème de dépassement et n'a jamais été conçu pour. C'est une fonction très spécialisée, destinée au départ au remplissage de certaines structures de données d'unix qui a été utilisée ailleurs
    et s'est retrouvé dans la norme on ne sait pas trop comment.
    D'autant que le comité n'a pas manqué d'excuses pour refuser strdup(), qui existe - quasiment - partout (il me semble), qui est parfois utile (pour garder le résultat de strerror, et compagnie), et qui ne présente pas réels dangers (savoir que la mémoire doit être libérée avec free, c'est un danger?).

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par corrector Voir le message
    D'autant que le comité n'a pas manqué d'excuses pour refuser strdup(), qui existe - quasiment - partout (il me semble), qui est parfois utile (pour garder le résultat de strerror, et compagnie),
    L'était-elle à l'époque (j'en sais rien, je n'y étais). Et son absence peut être un signe que la deuxième tendance était présente aussi.

    Il ne faut pas sacraliser les commités de normalisation. Ce n'est jamais qu'un rassemblement de personnes.

Discussions similaires

  1. Manipulation des chaines de caracteres
    Par hamidou sow dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 20/10/2014, 00h49
  2. [XL-2002] manipuler des chaines de caracteres en excel vb
    Par domes85 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 27/12/2011, 11h20
  3. manipulation des chaines de caractere
    Par elmo93 dans le forum Débuter
    Réponses: 1
    Dernier message: 17/11/2007, 17h53
  4. Manipulation des chaines de caracteres
    Par black-out dans le forum ASP
    Réponses: 3
    Dernier message: 12/08/2007, 15h11
  5. Fonctions de manipulation des chaines et des dates
    Par Fares BELHAOUAS dans le forum Débuter
    Réponses: 3
    Dernier message: 09/11/2002, 22h43

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