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

SL & STL C++ Discussion :

Manipuler les std::string


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Manipuler les std::string
    J'aimerais faire des manipulations de toutes sortes de chaines de caractères.
    En utilisant les std::string (suivant votre conseil) et en évitant les fonctions C (vous me l'avez déconsillé).

    Par exemple, tronquer une sous-chaine d'une chaine, remplacer une sous-chaine par une autre, faire des comparaisons contextuelles (par exemple o O ò Ò ö Ö Ô etc étant tous équivalents à la simple lettre o), remplacer les espaces consécutifs par un seul espace (tab, cr, lf, #160), etc.

    J'en suis à "retomber" à utiliser strcmp(,) pour la plus basique des comparaison (ou strnicmp ou strncmp ou stricmp ou une fonction semblable perso), n'y a-t-il pas mieux avec la S(T)L ?
    Merci.

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

    Informations professionnelles :
    Activité : aucun

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

    Si, bien sur, il y a mieux

    Je te conseillerais volontiers de t'intéresser au fonction (r)find (r)replace, substr et autres de la classe std::string ainsi qu'à la valeur (constante et globale) std::string::npos
    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 Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Ben là, il me semble qu'il n'y ait pas d'autres solutionsque d'éplucher la doc. Les fonctions de base de std::string permettent déjà de faire pas mal de chose :

    std::string
    operator+=
    append
    push_back
    assign
    insert
    erase
    replace
    copy
    swap

    find
    rfind
    find_first_of
    find_last_of
    find_first_not_of
    find_last_not_of
    substr
    compare

    Si tu te sens à l'étroit, boost.string ouvrent des possiblités quasi infini :

    http://www.boost.org/doc/libs/1_37_0...ring_algo.html

    Case Conversion
    to_upper()
    to_lower()

    Trimming
    trim_left
    trim_left_if()
    trim_left_copy()
    trim_left()
    trim_right
    trim_right_if()
    trim_right_copy()
    trim_right()
    trim
    trim_if()
    trim_copy()
    trim()

    Predicates
    starts_with()
    istarts_with()
    ends_with
    iends_with()
    contains
    icontains()
    equals
    iequals()
    lexicographical_compare
    ilexicographical_compare()
    all

    Find algorithms
    find_first
    ifind_first()
    find_last
    ifind_last()
    find_nth
    ifind_nth()
    find_head
    find_tail
    find_token
    find_regex
    find

    Erase/Replace

    replace/erase_first
    replace_first_copy()
    ireplace_first()
    ireplace_first_copy()
    erase_first()
    erase_first_copy()
    ierase_first()
    ierase_first_copy()
    replace/erase_last
    replace_last_copy()
    ireplace_last()
    ireplace_last_copy()
    erase_last()
    erase_last_copy()
    ierase_last()
    ierase_last_copy()
    replace/erase_nth
    replace_nth()
    replace_nth_copy()
    ireplace_nth()
    ireplace_nth_copy()
    erase_nth()
    erase_nth_copy()
    ierase_nth()
    ierase_nth_copy()
    replace/erase_all
    replace_all()
    replace_all_copy()
    ireplace_all()
    ireplace_all_copy()
    erase_all()
    erase_all_copy()
    ierase_all()
    ierase_all_copy()
    replace/erase_head
    replace_head()
    replace_head_copy()
    erase_head()
    erase_head_copy()
    replace/erase_tail
    replace_tail()
    replace_tail_copy()
    erase_tail()
    erase_tail_copy()
    replace/erase_regex
    replace_regex()
    replace_regex_copy()
    erase_regex()
    erase_regex_copy()
    replace/erase_regex_all
    replace_all_regex()
    replace_all_regex_copy()
    erase_all_regex()
    erase_all_regex_copy()

    Split

    find_all()
    ifind_all()
    find_all_regex()
    split()
    split_regex()

    Join
    join
    join_if

    Predicates
    is_classified
    is_space
    is_alnum
    is_alpha
    is_cntrl
    is_digit
    is_graph
    is_lower
    is_print
    is_punct
    is_upper
    is_xdigit

    Si tu es vraiment insatiable, il y a encore boost.tokeniser :

    http://www.boost.org/doc/libs/1_37_0.../tokenizer.htm

    Et tout au sommet de l'Olympe boost.regex :

    http://www.boost.org/doc/libs/1_37_0...tml/index.html

    Bon ceci dit, pour ne pas te mentir, les fonctions offertes par std::string ne sont pas toujours d'une simplicité biblique. Il faut lire attentivement la doc car parfois leurs comportements ne sont pas entièrement intuitifs.

    Et pour la comparaison au fait ?
    Ben, moi je fais comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::string str = "toto";
    if(str == "toto")
    {
         std::cout << "Plus besoin de strcmp !" << std::endl ;
    }

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Ok, merci merci merci merci !!!

    Pour boost on verra un peu plus tard.

    Commençons donc avec std::string.
    Alors comparer "toto" avec "toto", ça ira merci

    Mais pour comparer "toto" avec "TötÔ", ou "strasse" avec "Straße", je fais comment ? (sachant bien sûr qu'il y a "égalité" dans ces deux exemples)

  5. #5
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par camboui Voir le message
    Mais pour comparer "toto" avec "TötÔ", ou "strasse" avec "Straße", je fais comment ? (sachant bien sûr qu'il y a "égalité" dans ces deux exemples)
    Ben là, typiquement, t'es mal

    Bon plus sérieusement, ça dépasse mes compétences. En C comme en C++ les problèmes d'internationalisation sont toujours une horreur.
    Désolé. Il va falloir attendre des avis plus qualifiés.

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Pour tout ce qui est lié à une gestion fine de l'internationalisation, il y a icu : http://www.icu-project.org/userguide/Collate_Intro.html
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    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 camboui Voir le message
    Ok, merci merci merci merci !!!

    Pour boost on verra un peu plus tard.

    Commençons donc avec std::string.
    Alors comparer "toto" avec "toto", ça ira merci

    Mais pour comparer "toto" avec "TötÔ", ou "strasse" avec "Straße", je fais comment ? (sachant bien sûr qu'il y a "égalité" dans ces deux exemples)
    Je suis loin d'etre sur qu'il y a egalite dans ces cas. La maniere de comparer en tenant compte des locales, c'est:

    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
     
    #include <locale>
    #include <string>
    int main()
    {
       // utilisons la locale definie par le contexte (on demarre en locale "C")
       std::locale::global(std::locale(""));
       ...
       // construisons deux chaines
       std::string l, r;
     
       // et comparons les
       if (std::locale()(l, r)) {
          // l < r
       } else {
          // l >= r
       }
    }
    Voir aussi les facets "collate" et "ctype" pour plus de fonctionalites.

  8. #8
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    J'ai fait un exercice simple.

    Dans la faq il y a un exemple, retirer un caractère d'une string:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char c='0';
    s.erase(std::remove_copy(s.begin(),s.end(),s.begin(),c),s.end());
    J'ai voulu l'étendre pour retirer un ensemble de caractères et j'obtiens ceci (du vrai code C++ pur et dur ):
    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
    struct IsCharList
    {
    	const char *s_cp;
    	size_t s_cplen;
    	IsCharList(const char *cp,size_t cplen)
    		:s_cp(cp),s_cplen(cplen) {}
    	bool operator()(char c)
    	{
    		return (std::char_traits<char>::find(s_cp,s_cplen,c)!=0);
    	}
    };
     
     
    s.erase(
    	std::remove_copy_if(s.begin(),s.end(),s.begin(),IsCharList("1234",4))
    	,s.end());
    En utilisant mes (mauvaises ?) habitudes, j'obtiens ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	std::string::iterator f,l,t;
    	for (f=t=s.begin(),l=s.end();f!=l;++f)
    	{
    		char c=*f;
    		if (memchr("1234",c,4)!=0)
    			*t++=c;
    	}
    	s.erase(t,l);
    Je me demande ce qui est le mieux... ou le moins pire...

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bah, tu pourrais encore abstraire IsCharList en 'templatisant' par rapport à char.

    [EDIT]: pour ce qui est le moins pire. Je préfère encore ta première solution. Même si certains reprochent aux foncteurs à tous crins de complexifier la lecture du code.

Discussions similaires

  1. Les nombres dans des std::string
    Par camboui dans le forum SL & STL
    Réponses: 41
    Dernier message: 11/02/2009, 17h55
  2. [Debutant] Manipuler les int dans un string
    Par mr_samurai dans le forum Débuter
    Réponses: 5
    Dernier message: 18/01/2008, 20h00
  3. Questions sur les std::string
    Par olive_le_malin dans le forum SL & STL
    Réponses: 6
    Dernier message: 23/02/2007, 08h44
  4. Pourquoi refuser les std::string
    Par dj.motte dans le forum SL & STL
    Réponses: 18
    Dernier message: 09/01/2007, 22h59
  5. [débutant] equivalent à sprintf pour les std::string
    Par Biosox dans le forum SL & STL
    Réponses: 22
    Dernier message: 26/08/2005, 12h46

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