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 :

strncmp dans le cas de noms trop courts


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut strncmp dans le cas de noms trop courts
    Bonjour tous,

    il y a un truc que je n'arrive pas à faire C++ :
    => je lis un fichier et j'ai une "case" dans mon fichier qui contient soit un mot du genre "treatment" soit un nombre. (je ne vérif que les 5premiers caractères car c'est treat qui m'intéresse).

    du coup j'ai fais ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (strncmp(_arg[2].c_str(),"treatment",5)==0) {
            myBool=true;
        }
        else {save=atoi(_arg[2].c_str());}
    ça marche très bien mais

    si l'utilisateur rentre un mot trop cours comme "tr" (moins de 5lettres) alors mon code va passer dans le else mais comme ce n'est pas un chiffre que j'ai alors ça va planter.

    Du coup ce que j'aimerai :


    j'aimerai différencier 3 cas :

    1°) si j'ai quelque chose qui commence par "treat" alors OK
    2°) si j'ai un nombre OK
    3°) si j'ai pas un nombre ou un mot plus petit que 5 lettre alors je plante.

    pourriez vous me dire comment faire ?

    merci d'avance

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Déjà, vu que tu travailles visiblement avec une std::string, pourquoi donc te faire ch...r à travailler avec strcpm

    La classe std::string fournit toutes les méthodes qui pourraient t'intéresser, comme :
    • size() qui indique la taille de la chaine de caractère
    • substr(size_t pos = 0, size_t n = std::string::npos) qui renvoie la sous chaine commençant à la position pos et de taille n de la chaine en cours
    • l'opérateur de comparaison == qui renvoie true si l'opérande de gauche est égal à l'opérande de droite


    La question qu'il serait plus qu'utile de se poser ensuite, c'est, très certainement
    ne risque-t-on pas d'avoir des valeurs numérique qui fassent moins de 5 chiffres
    En effet, les nombres inférieurs à 10000 ne sont généralement pas représentés avec 5 caractères, vu que les 0 non significatifs ne sont, d'habitudes, pas affichés (ni sauvegardés, d'ailleurs).

    Quoi qu'il en soit, j'envisagerais bien d'inverser la logique, en commençant par tenter de convertir (à la manière C++!! ) la chaine en entier et, si ca ne se passe pas bien, en vérifiant la longueur de la chaine récupérée avant de vérifier enfin si la chaine récupérée correspond à la partie adéquate du mot "treatment"

    En gros, nous aurions un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    std::stringstream ss;
    ss<< arg_[2];
    if(!(ss>>save))
    {
        if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        std::string waited("treatment");
        if(waited.substr(0,5) == arg[2]_)
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    }
    Au passage, avoir une variable dont le nom est "myBool" n'est pas ce que l'on peut considérer comme le plus efficace...

    Il serait pas mal de lui trouver un nom qui corresponde un peu mieux à ce qu'elle est sensée représenter
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci beaucoup pour ton aide, j'ai bien compris tout ce que tu voulais dire, ton message est très clair

    par contre j'ai un petit soucis avec ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
    on ne va prendre en compte que les nombre qui ont au minimum 5 chiffres ?
    les nombres qui peuvent être utilisés dans ce fichiers texte peuvent avoir une taille quelconque, la seul restriction c'est qu'il faut que ça soit un entier...

    je n'aurais pas plutôt intérêt à faire quelque chose dans ce genre :
    et si je me rends compte après vérification que ce n'est pas un entier alors je regarde si c'est le string que je cherche et sinon je fais une erreur ?

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    regarde bien le code, tu verras que non, et ce, dès la lecture.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    Citation Envoyé par leternel Voir le message
    regarde bien le code, tu verras que non, et ce, dès la lecture.
    franchement je ne vois pas du tout, il y a quelque chose qui doit m'échapper dans le code de "koala01", d'ailleurs je me rend compte que je n'ai pas compris le premier if avec la variable "save" que je n'ai pas vu définie quelque part...

    voici ce que j'aurais fait plutôt en m'inspirant de "koala01" et en
    codant plutôt à mon niveau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    std::stringstream ss; ss<< arg_[2];
    if (arg_[2].size() < 5 ){
        ss<<arg_[2];
        int monEntier=atoi(ss.c_str());
        maFonction1(monEntier);
    }
    else {
        std::string waited("treatment");
        if(waited.substr(0,5) == arg[2]_)    {
             myBool=true;
        }
        else   {
             myBool=false;
        }
        maFonction2(myBool);
    }
    le soucis est qu'il y a deux choses qui ne sont pas prises en compte :
    1°) si j'ai un string mais avec moins de 5 lettres il va rentrer dans ce if :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (arg_[2].size() < 5 ){ss<<arg_[2];}
    mais je ne veux pas forcement

    2°) si j'ai un nombre genre 10000000 il va pas rentrer dans le if
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (arg_[2].size() < 5 ){ss<<arg_[2];}
    mais dans le else et sera donc traité comme un string et non comme un entier...

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Dans ce cas, un peu d'explication du code de Koala01:

    Quelque part dans la portée, il doit y avoir une déclaration de save: int save;.

    Déclaration et initialisation d'un flux sur chaine de caractères, utilisable en entrée (lecture) comme en sortie (écriture).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::stringstream ss;
    ss<< arg_[2];
    j'aurais personnellement préféré un std::ostringstream ss(arg_[2]);

    lecture de save depuis ss, exactement comme cin >> save, sauf que cin lit depuis l'entrée standard (le clavier, sauf redirection)

    istream::operator>>(…) renvoie le flux lui-même.
    istream::operator!() renvoie true si le flux a subit une erreur (ici de lecture)

    Donc le test tente de définir save, et execute quelque chose si ce fut impossible. pour plus d'information, vois cette question de la faq.

    soit la lecture réussit, donc on ne rentre pas dans le if (a cause du !) et save est l'entier lu.
    soit la lecture échoue, donc save n'est plus valable (ou est définit à son ancienne valeur, je n'ai jamais testé), et on entre dans le if en sachant que le stream n'a pas pu fournir d'entier, donc que arg_[2] ne commence pas par un nombre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize();
        }
    Si arg_[2] est trop court, lever une exception (throw) qui est le résultat de l'expression badArgumentStringSize().
    Attention, il s'agit de l'appel d'une fonction libre, pas du constructeur d'une class ou struct nommée badArgumentStringSize, sinon, ca aurait été throw badArgumentStringSize;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        std::string waited("treatment");
        if(waited.substr(0,5) == arg[2]_)
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Tu as besoin d'aide pour celui ci?

    finalement, fermeture du test de lecture

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    En fait, pour save, je me suis basé sur ton propre code d'origine, qui nous montrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (strncmp(_arg[2].c_str(),"treatment",5)==0) {
            myBool=true;
        }
        else {save=atoi(_arg[2].c_str());}
    et pour laquelle j'en avais déduis que c'était un entier

    Mon idée est que tu ne peux pas savoir à l'avance le nombre de caractères qui représentent une valeur numérique entière.

    En effet, tu peux avoir 1 ou 1 586 974.

    Il est donc important de définir dés le départ si tu es face à un entier ou face à une chaine de caractères

    si la conversion en entier se passe bien on passe tout ce qui a trait à la gestion des chaines de caractères, mais si elle échoue, c'est que l'on a une chaine de caractères et qu'il faut donc voir si elle est bien formatée

    On sait ensuite qu'il faut que la chaine de caractères ait au minimum 5 caractères, si ce n'est pas le cas, on lance une exception (qu'il te faut créer et gérer dans l'une des fonctions qui ont mené à ce code) parce que tu le dis toi-même, c'est une erreur

    Par contre, j'ai fait une erreur pour la vérification du contenu de la chaine.

    J'ai déterminé, par le if(arg_[2].size() <5) que la chaine de caractères est composée d'au minimum cinq caractères, mais elle pourrait très bien (à moins que cela n'ait été vérifié ou fixé par ailleurs) etre composée de plus de caractères que cela.

    la question sera donc
    que se passe-t-il s'il y a, mettons, 7 caractères
    1. doit-on prendre les 5 premiers et vérifier s'ils vallent "treat", ce qui aura comme résultat d'accepter "treatBD" comme valide
    2. doit on considérer qu'une chaine de plus de 5 caractères est tout aussi fausse qu'une chaine de moins de 5 caractères
    3. ou doit-on, considérer l'intégralité de la chaine pour voir si cela correspond à "treatment" (ce qui aurait pour résultat de considérer "treatDB" comme étant une erreur) Mais dans ce cas là,
    4. quid des chaines de caractères plus longues que "treatment" faut il, par exemple, considérer que "treatmentDB" sera correcte, ou incorrecte
    Chaque cas de figure impliquera une réaction différente, mais il t'appartient de trouver celui qui convient

    Ainsi, dans le premier cas, nous pourrions comparer une chaine composée uniquement de "treat" avec... la sous-chaine composée des cinq premier caractères de la chaine représentée par arg_[2].

    Cela prendrait une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        /* ca, ca ne change pas ;) */
        if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        if(arg_[2].substr(0,5)== "treat" )
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Dans le deuxième cas, il faudra modifier le test de manière à ce qu'il refuse toute chaine de caractères qui n'est pas composée de 5 caractères précisément.

    Mais, à partir du moment où nous savons que arg_[2] est composé précisément de 5 caractères, nous pourrions nous contenter de comparer "treat" à arg_[2] car la première condition pour que deux chaines soient égales, c'est... qu'elle soient de taille identique

    Le code serait alors proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
        /* on refuse toute taille différente de 5 */
        if (arg_[2].size() != 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        /* on peut directement comparer arg_[2] à "treat", grace à la conversion
         * implicite d'un const char *  en std::string
         */
        if(arg_[2] == "treat")
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Dans le troisième cas, il faudrait prendre une sous-chaine issue de "treatment" dont la taille serait celle de arg_[2].

    Nous n'aurions aucun problème si arg_[2] fait plus que 9 lettres (la taille de "treatment" car substr renvoie... la chaine complète (donc les 9 lettres) si on lui demande une taille supérieure à celle de la taille d'origine.

    Le code prendrait alors la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        /* ca, ca ne change pas ;) */
        if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        /* on n'a pas besoin de "treatment" en entier ;) */
        std::string waited("treatment");
        if(waited.substr(0,arg_[2].size())== arg_[2] )
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Pour le quatrième cas, je vais devoir envisager les deux solutions de manière distinctes:
    Si l'on considère que "treatmentDB" (ou que "treatDB") est invalide, nous pouvons définir directement une "limite haute" dans la taille de arg_[2] et le code pourrait devenir quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
       /* on refuse toute taille inférieure à 5 et supérieure à 9 */
        if ( arg_[2].size() < 5 
            ||  arg_[2].size() >9 ) // 9 est la taille de "treatment"
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        std::string waited("treatment");
        if(arg_[2] == waited.substr(0,arg_[2].size()) 
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Si l'on considère que "treatmentDB" est valide (mais que "treatDB ne l'est pas ), nous devrons utiliser la taille de la plus petite des deux chaines comme nombre de caractères pour les sous-chaines, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        /* ca, ca ne change pas ;) */
        if (arg_[2].size() < 5 )
        {
            throw badArgumentStringSize(); // à définir par toi meme ;)
        }
        /* on n'a pas besoin de "treatment" en entier ;) */
        std::string waited("treatment");
        /* et l'on doit avoir la taille la plus petite */
        size_t size = std::min(arg_[2].size(), waited.size()) // nécessite l'inclusion de <algorithm>
        if(waited.substr(0,size)== arg_[2].substr(0,size) )
        {
            myBool=true;
        }
        else
        {
            /* à toi de voir que faire  ;) */
        }
    Maintenant, c'est à toi de voir dans quelle situation tu te trouves exactement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Citation Envoyé par koala01
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        /* on peut directement comparer arg_[2] à "treat", grace à la conversion
         * implicite d'un const char *  en std::string
         */
        if(arg_[2] == "treat")
    Tu es sûr de toi? à ma connaissance, il faut au moins une string pour que ce soit vrai. Si jamais arg_[2] est un char*, je ne pense pas que cela soit valable.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par leternel Voir le message
    Tu es sûr de toi? à ma connaissance, il faut au moins une string pour que ce soit vrai. Si jamais arg_[2] est un char*, je ne pense pas que cela soit valable.
    Héhé...

    1. Tu as un constructeur implicite de std::string qui prend... un const char *.
    2. l'opérateur == de std::string est une fonction dont le prototype est bool operator==( std::string const & second) const

    Comme l'argument de l'opérateur == est une référence constante, il y a moyen d'utiliser ce que l'on appelle des variable anonymes temporaires, c'est à dire que, si l'on trouve un moyen de convertir implicitement l'argument en std::string, la conversion sera effectuée et le résultat de cette conversion sera utilisé en interne

    Et comme le 1 nous indique qu'il existe un moyen de convertir implicitement un const char * en std::string (c'est ce que tu fais lorsque tu écris std::string str("salut") ), il y a bel et bien moyen d'obtenir une telle variable anonyme temporaire

    donc, oui, je suis sur de moi
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Justement, "treatment" est un const char*, si argv_[2] est un char*, il y a seulement une comparaison de pointeurs.

    De même qu'il est possible de comparer deux int* avec == pour savoir s'ils contiennent la même adresse (ont la même valeur), == compare les adresses contenues dans les deux const char*.

    Au dernière nouvelles, le programme suivant ne retourne jamais 1, malgré la présence de std::string.
    #include <string>
    int main(int argc, char** argv){
    return argc>1 ? (argv[1]=="truc" ? 1 : 0 ) : -1;
    }

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par leternel Voir le message
    Je ne suis pas d'accord avec toi.

    std::string str("salut") appelle explicitement le constructeur std::string(const char*).
    C'est la possibilitié d'appeler implicitement ce constructeur qui rend la conversion const char* => string possible.

    De même qu'il est possible de comparer deux int* avec == pour savoir s'ils contiennent la même adresse (ont la même valeur), == compare les adresses contenues dans les deux const char*.

    essaye le programme suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include <string>
    int main(int argc, char** argv){
    return argc>1 ? (argv[1]=="truc" ? 1 : 0 ) : -1;
    }
    Tu n'auras normalement jamais le statut 1, malgré la présence de std::string.
    Sauf que argv[1] est de type const char * et non de type std::string

    ici, l'opérateur == utilisé est donc l'opérateur de comparaison entre deux pointeurs "classiques".

    Je t'ai parlé de la fonction membre de std::string operator==(), qui doit donc, fatalement, être utilisé avec une std::string comme opérande de gauche.

    Il n'y a que l'opérande de droite, quant à lui, qui peut etre implicitement converti si, d'une manière ou d'une autre, il existe un mécanisme de conversion implicite

    Et le mécanisme de conversion implicite est, en l'occurrence, le constructeur de std::string qui prend un const char * , parce que c'est un constructeur qui n'est pas déclaré explicite

    Le code qui mettrait cela en évidence est beaucoup plus proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(int argc, char** argv)
    {
        std::string str("truc");
        if(str== argv[1])
            std::cout<<"c'est pareil"<<std::endl;
        else
            std::cout<<"c'est différent"<<std::endl;
        return 0;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu me fais douter…

    Ah bah oui, j'ai zappé un détail.
    _arg[2] est bien une string, vu le .c_str() initial.

    Donc oui, c'est tout à fait exact.

    Nous sommes donc bien d'accord.

  13. #13
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Ceci dit, avant de me faire pendre haut et court, je dois quand meme rectifier une erreur...

    L'opérateur == est une fonction amie de std::string dont le prototype est bool operator ==(std::string const & , std::string const &) afin d'assurer la réciprocité.

    C'est ce qui permet au code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(int argc, char** argv)
    {
        std::string str("truc");
        if(argv[1]==str)
            std::cout<<"c'est pareil"<<std::endl;
        else
            std::cout<<"c'est différent"<<std::endl;
        return 0;
    }
    de fournir exactement le même résultat que dans mon intervention précédente

    Cependant, s'il a le choix entre deux opérateur de comparaison, le compilateur choisira, sa fainéantise naturelle aidant, celui qui occasionne le moins de conversions.

    C'est ce qu'on appelle le "best match"

    s'il se trouve en présence de deux const char *, il aurait le choix entre l'opérateur prenant deux références constantes sur des std::string, mais cela impose deux conversion et celui prenant... deux pointeurs sur char, qui ne demande aucune conversion.

    Il choisira donc celui qui convient le mieux, à savoir... celui qui utilise les deux pointeurs, simplement, parce que c'est celui qui demande le moins de travail (aucune conversion contre deux )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Par défaut
    merci tous !
    avec votre aide j'ai pu définitivement boucler mon problème
    => tout fonctionne et c'est validé

    je suis très content, je vous remercie du fond du coeur pour votre aide !

    A bientôt

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. UML : Qui s'en sert ? Pourquoi ? Dans quels cas ? Où ?
    Par Matthieu Brucher dans le forum UML
    Réponses: 83
    Dernier message: 10/06/2013, 16h13
  2. [Débutant][JList] Comment ça marche dans mon cas ?
    Par gcore dans le forum Composants
    Réponses: 31
    Dernier message: 28/06/2004, 10h45
  3. Quel type de BDD dans mon cas
    Par zoubidaman dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 10/06/2004, 18h00
  4. [corba] débutant : dans quels cas l'utiliser
    Par jmturc dans le forum CORBA
    Réponses: 2
    Dernier message: 10/10/2002, 08h58

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