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

Boost C++ Discussion :

[Boost.Tokenizer] Utiliser le caractère de séparation NULL


Sujet :

Boost C++

  1. #1
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut [Boost.Tokenizer] Utiliser le caractère de séparation NULL
    Bonjour,

    Durant mon projet, j'aurais besoin de séparer une multistring (tableau de char, instauré par Microsoft, représentant plusieurs chaînes de caractères séparées par un caractère NULL, selon : "String1\0String2\0String3\00" [deux caractères NULL finaux]) en plusieurs strings. J'ai donc pensé à boost::tokenizer, mais en faisant le test suivant :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //#define MAX_PATH 260
     
    char temp[MAX_PATH] = "YOUHOU;\0SALUT\0TOP";
     
    boost::tokenizer<boost::char_separator<char> > tok(std::string(temp), boost::char_separator<char>("\0"));
    for (boost::tokenizer<boost::char_separator<char> >::const_iterator i = tok.begin(); i != tok.end(); ++i )
        MessageBox(hwnd, i->c_str(), "Test", MB_ICONINFORMATION);
    Je n'ai que la première string, ce qui paraît logique du fait que le caractère NULL finit en principe les strings.

    Seulement voilà, je dois faire cette séparation, et j'aimerais vraiment utiliser Boost.Tokenizer pour cela (j'aurais aussi l'alternative STL avec des istream_iterator<>, mais je risque d'avoir le même problème) ; par conséquent, sauriez-vous comment remédier à ce problème (une astuce quelconque) ?

    Merci d'avance.
    Vive l'embarqué.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Et pourquoi n'utiliserais tu, tout simplement, pas un simple vecteur de chaines tant que tu n'a pas réellement besoin du multistring

    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::vector<std::string> tab;
    tab.push_back("chaine 1");
    tab.push_back("chaine 2");
    /*....*/
     
    et une fonction qui irait bien avec:
    std::string AllInOne( const std::vector<std::string>& tab)
    {
        std::string ret=""
        for(size_t i=0;i<tab.size();i++)
        {
            ret+=tab[i];
            /*éventuellement */
            if(i!=tab.size()-1)
                ret+="caractere de separation";
        }
        return ret;
    }
    D'un autre coté, si le but est de séparer une chaine en plusieurs selon un séparateur donné, rien ne t'oblige à utiliser une multistring...
    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 régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    rien ne t'oblige à utiliser une multistring...
    Si, l'API Windows elle-même... GetOpenFileName() permet d'afficher une boîte de dialogue de sélection de fichiers à ouvrir, dont les chemins constituent au retour la multi-string.

    Aucun moyen ?
    Vive l'embarqué.

  4. #4
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Up
    Vive l'embarqué.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Mais, alors, et ce n'est finalement qu'une question (étant pour le moins allergique à l'API windows...), es-tu sur qu'il n'existe aucune méthode dans la multistring qui permette d'obtenir les chaines de manière séparées

    Il me semblerait quelque peu idiot, meme venant de microsoft, qu'ils n'aient pas prévu un moyen pour le faire...

    Je ne sais pas, moi, peut etre, tout simplement l'opérateur []

    Cela *pourrait* donner un truc du genre 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
     
    /* considérons que ms soit une variable de type multistring ;) */
    std::string s1=ms[0];
    std::string s2=ms[1];
    /*...*/
    /* Voir, peut etre encore mieux: récupérer simplement les chaines dans un
     * tableau (en adaptant à la fonction qui permet de récupérer le nombre de
     * chaines dans la multistring (j'ai mis ici size(), mais c'est peut etre autre
     * chose ;) ) ) */
    std::vector<std::string> tab;
    for(size_t i=0;i<ms.size();i++)
    {
        tab.push_back(ms[i]);
    }
    La =>doc msdn<= semble parler d'une fonction qui devrait déjà te permettre d'avancer un peu: ToString

    A partir de là, tu devrais pouvoir envisager de travailler plus sereinement
    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

  6. #6
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Ils fournissent le format, à nous de coder une fonction (ou alors je ne connais pas celle fournie) permettant d'extraire les chaines.

    J'en ai une pareille, en C, mais j'aurais aimé simplifier au maxi le code source en introduisant le plus possible de concepts apportés par Boost (ou la STL, GLib etc.). Après, si ce n'est pas possible, tant pis, mais j'aurais aimé...
    Vive l'embarqué.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Ce que je voulais dire, c'est que d'après la msdn, il y a une méthode ToString qui permet de transformer ta multistring en String...

    Pour autant que la classe String soit compatible avec la std::string, voire, même plutôt avec la std::istringstream, tu pourrais envisager de travailler 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
     
    std::istringstream iss(GetOpenFileName().ToString());
    /* ne reste plus qu'à gérer cette chaine en utilisant le back slach comme
     * séparateur... Pour la facilité, autant les placer tous dans un tableau ;) */
    std::vector<std::string> tab;
    std::string str;
    while (std::getline(iss,str,'\\'))
        tab.push_back(str);
    /* récupération du lecteur logique */
    std::cout<<"le lecteur logique est "<<tab[0]<<std::endl;
    /* la liste des sous dossiers
    for(size_t i=1;i<tab.size()-1;i++)
        std::cout<<" sous dossier "<<i<<" :"<<tab[i]<<std::endl;
    std::cout<<" nom du fichier :"<<tab[tab.size()-1]<<std::endl;
    Toute la difficulté étant d'être sur du fait que ToString renvoie quelque chose qui soit compatible avec la std::string, ou, au pire, avec la std::wstring
    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
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Le problème, c'est que je ne travaille pas en MFC (j'ai omis de le dire). J'ai donc juste la fonction BOOL GetOpenFileName(LPOPENFILENAME), et c'est tout. Donc à part si il y a effectivement une autre fonction pour récupérer les éléments d'une multistring, j'aimerais utiliser un tokenizer pour récupérer les éléments séparés par le caractère NULL, ce que je ne peux apparemment pas, puisque -je suppose- la conversion en std::string tronque d'ores et déjà la multistring en monostring...
    Vive l'embarqué.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut correction d'une coquille dans le code
    Reste peut être alors la méthode "bourine"...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    size_t i=0;
    std::string str;
    std::vector<std::string> tab;
    while(ms[i]!='\0' && ms[i+1]!='\0')
    {
        str+=ms[i];
        if (ms[i]='\0')
        {
            tab.push_back(str);
            str="";
        }
        ++i;
    }
    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
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    A part la méthod ebourrine, point de salut...
    La raison est simple : tokenizer prend un string en paramètre. Or lors de la transformation char* vers string, la chaîne considérée s'arrête au premier '\0', car on considère qu'on transforme une chaîne C. Dans le cas contraire, il n'y a aucun moyen de savoir quand on doit s'arrêter.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    C'est bien pour cela que, avant d'envisager une méthode "bourine", j'ai essayé de savoir s'il n'y avait pas moyen d'obtenir quelque chose qui soit compatible avec les chaînes de caractères (mais en avouant bien fort mon aversion pour l'API utilisée )

    Et du coup, m$ redescend de nouveau d'un cran dans mon estime...
    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
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Dans une string, il est possible d'avoir des \o, mais une fois qu'on récupère un char* ou un const char*, la chaîne est supprosée s'arrêter au premier '\0' rencontré. Donc c'est dommage de ne pas retourner la chaîne à la place du char*.

  13. #13
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    A part la méthod ebourrine, point de salut...
    La raison est simple : tokenizer prend un string en paramètre. Or lors de la transformation char* vers string, la chaîne considérée s'arrête au premier '\0', car on considère qu'on transforme une chaîne C. Dans le cas contraire, il n'y a aucun moyen de savoir quand on doit s'arrêter.
    A vrai dire, je m'en doutais, mais j'espérais une sorte de style ou autre, pour me permettre cette manipulation... enfin, puisqu'il n'y a pas de solution, je clos le topic.

    Merci à vous.
    Vive l'embarqué.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Note que, réflection faite, n'y aurait-il pas moyen de le transtyper brutalement

    Je ne sais pas, quelque chose du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    std::string str=static_cast<std::string&> (ms);
    std::istringstream iss(str);
    /* "plus qu'à récupérer les chaines séparées :D */
    (c'est la réflextion de miles concernant les \0 qui m'a mis sur la voie )
    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

  15. #15
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Ca ne marche pas comme ça, cil y a pleins d'autres infos dans un string qui ne sont pas dans un char*. Quand on transforme un char* en string, il s'arrête au premier '\0', il n'y a rien qu'on puisse faire pour l'en empêcher. Et un cast brutal tel que celui-ci va faire soit une erreur de compilation soit un seg fault (plutôt une erreur de compilation).

  16. #16
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Oui, c'est ça que j'aimerais faire : es-tu sûr que le cast (ou similaire) n'est pas envisageable ?

    Au pire, je peux toujours (à l'aide d'une bête fonction de recherche perso, pour passer outre les caractères NULL) transformer les caractères NULL en ';' (par exemple), et les deux NULL finaux en un pour ensuite effectuer mon découpage tranquillement...
    Vive l'embarqué.

  17. #17
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par kidpaddle2
    Oui, c'est ça que j'aimerais faire : es-tu sûr que le cast (ou similaire) n'est pas envisageable ?
    Certain.

  18. #18
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Bon, je déclare donc ce topic Résolu.

    Merci à vous.
    Vive l'embarqué.

  19. #19
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    Dans la classe std::basic_string (dont std::string est un typedef) on a le constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    basic_string(const basic_string& __str, size_type __pos, size_type __n = npos);
    • __str : chaîne
    • __pos : index du premier caractère
    • __n : nombre de caractères

    Normalement, il supporte les multi-string. Pour récupérer la valeur, on utilise std::string::data() à la place de c_str() (c_str() donne une chaîne C terminée par '\0').
    Donc on a : std::string multi_string('ma\0multi\0string\00', 0, 17);
    Ensuite, on utilise boost::tokenizer avec cette string.

  20. #20
    Provisoirement toléré
    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
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par kidpaddle2 Voir le message
    les caractères NULL
    Petite correction : les caractères NUL, par opposition aux "null pointers" = pointeurs nuls, et à la macro NULL.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [MySQL] Utilisation de la valeur SQL NULL
    Par pierre50 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 17/03/2006, 14h22
  2. [MySQL] Utilisation du caractère "`" dans les requêtes
    Par PeZ dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 07/03/2006, 16h01
  3. [BOOST]Comment utiliser la lib boost.python
    Par Invité dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 30/01/2006, 11h35
  4. [XML]caractère de séparation des contenus des éléments
    Par ep31 dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 13/12/2005, 11h07
  5. [C#] Caractère de séparation
    Par borgfabr dans le forum Windows Forms
    Réponses: 2
    Dernier message: 03/03/2005, 11h51

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