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 :

ToUpper pour un string


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Mai 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 9
    Par défaut ToUpper pour un string
    Bonjour,

    Dans le cadre d'un de mes cours, je dois convertir un string en miniscule à des majiscules. J'ai de la difficulté a utiliser correctement la fonction toupper. Je n'ai pas pu avoir la synthaxe exact de cette fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <string>
     
    using namespace std;
    void main(void)
    {
     
    string Majuscule, 
           Minuscule="Je suis malade";
     
    Majuscule=toupper(Minuscule);
    cout<<Majuscule<<endl;
     
    }

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    et tant que tu es dans tes cours, commence directement à aller regarder du coté de la Boost, www.boost.org , qui te fera avancé à pas de géant.

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Centabarnak Voir le message
    Bonjour,

    Dans le cadre d'un de mes cours, je dois convertir un string en miniscule à des majiscules. J'ai de la difficulté a utiliser correctement la fonction toupper. Je n'ai pas pu avoir la synthaxe exact de cette fonction.
    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
     
    #include <iostream>
    #include <string>
     
    using namespace std;
    void main(void)
    {
     
    string Majuscule, 
           Minuscule="Je suis malade";
     
    Majuscule=toupper(Minuscule);
    cout<<Majuscule<<endl;
     
    }
    toupper() prend en paramètre un charactère et non pas une string - et renvoie ce charactère. Pour transformer une chaine de caractère, il faut appliquer cette fonction pour chaque caractère de la chaine. On peut le faire dans une boucle ou bien utiliser les algorithmes de la CSL (et notamment std::transform):

    Pour une version grosso-modo standard, on utilisera quelque chose comme:

    std::string majuscule = minuscule;
    std::transform(majuscule.begin(), majuscule.end(), majuscule.begin(), ::toupper);

    Idem pour tolower().

    En utilisant ta propre boucle, ça donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::string majuscule = minuscule;
    for (int i=0; i<majuscule.length(); ++i)
    {
      majuscule[i] = ::toupper(majuscule[i]);
    }
    Attention à resister à la tentation d'utiliser std::toupper, qui est d'une utilisation beaucoup plus complexe (puisque cette fonction de la CSL fonctionne en conjonction avec la librairie <locale> et les "facet" définis par le standard C++. J'utilse l'opérateur de portée sur toupper() pour rendre explicite le fait que je souhaite utiliser la version C standard de cette fonction.

    Avec std::toupper(), la seconde version (la boucle) devient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <locale>
     
    std::string majuscule = minuscule;
    for (int i=0; i<majuscule.length(); ++i)
    {
      // on a besoin de construire une locale globale
      majuscule[i] = std::toupper(majuscule[i], std::locale());
    }
    La version std::transform(), par contre, n'est paspiquée des hannetons: il faut prendre l'adresse de la fonction std::toupper, construire un objet encapsulant un pointeur sur fonction, et forcer le second paramètre à une valeur spécifique. Le problème est que le second argument est une référence - et que binder2nd<> (la classe que nous souhaiterions utiliser pour forcer le second paramètre) n'accepte que les passages d'argument par valeur - sous peine de créer une référence de référence, ce qui n'est pas encore autorisé par le standard C++.

    Pour régler le problème, certains passent par boost (bien, mais ajoute une dépendance), d'autres ont ajouté une spécialisation de std::binary_function (PAS BIEN), d'autres utilisent directement std::facet<> pour faire le travail, etc. Ce thread sur gamedev.net donne un certain nombre de solutions viables.

    Bon courage
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    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
    Juste pour dire qu'une telle transformation exacte est en règle générale impossible, puisque dans certaines langues il n'y a pas correspondance unique majuscule/minuscule.

    Je ne connais pas d'exemple où ça bloque de minuscules vers majuscule, mais dans l'autre sens, l'allemand est typique, 'SS' devant selon les cas devenir 'ss' ou bien 'ß'.

    Et même dans le sens où ça marche, on voit bien qu'un seul caractère en minuscule se traduit par deux en majuscule, et donc une simple boucle ne marche pas dans tous les cas.

    La question devient alors : Quel est le but de l'opération de transformation, et les approximations sont-elles gênantes ?

    Autrement, j'ai entendu parler de la lib ICU, spécialisée pour gérer les cas d'internationalisation, mais je ne sais pas ce qu'elle fait en l'occurrence.
    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.

  6. #6
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 966
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 966
    Par défaut
    Koi,
    Citation Envoyé par JolyLoic Voir le message
    Juste pour dire qu'une telle transformation exacte est en règle générale impossible, puisque dans certaines langues il n'y a pas correspondance unique majuscule/minuscule.
    ...
    La question devient alors : Quel est le but de l'opération de transformation, et les approximations sont-elles gênantes ?
    Il s'agit d'un exercice dans le cadre d'un cours, je ne pense pas que le problème se pose.

    Citation Envoyé par JolyLoic Voir le message
    ...
    Je ne connais pas d'exemple où ça bloque de minuscules vers majuscule, mais dans l'autre sens, l'allemand est typique, 'SS' devant selon les cas devenir 'ss' ou bien 'ß'.

    Et même dans le sens où ça marche, on voit bien qu'un seul caractère en minuscule se traduit par deux en majuscule, et donc une simple boucle ne marche pas dans tous les cas.
    Un cas minuscules vers majuscules est allemand aussi : 'ß' devient 'SS'.

  7. #7
    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
    Citation Envoyé par droggo Voir le message
    Koi,

    Un cas minuscules vers majuscules est allemand aussi : 'ß' devient 'SS'.
    Oui, mais de de manière non équivoque. La transformation est pénible, car elle ne conserve pas le nombre de caractères, mais est possible. C'est dans l'autre sens que ça ne l'est plus.
    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.

  8. #8
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 966
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 966
    Par défaut
    Jei,
    Citation Envoyé par JolyLoic Voir le message
    Oui, mais de de manière non équivoque. La transformation est pénible, car elle ne conserve pas le nombre de caractères, mais est possible. C'est dans l'autre sens que ça ne l'est plus.
    Si en plus tu veux faire joujou avec Unicode, ça devient encore pire, certains caractères ayant plusieurs formes tout à fait légales, et le tout dépend en plus du type d'Unicide utilisé (UTF8, 16, ...).

    Faire un vrai tri alphabétique au sens habituel (pas tenir compte des symboles diacritiques [accents,cédille]) avec ces bestioles n'est plus du tout trivial.

  9. #9
    Membre du Club
    Inscrit en
    Mai 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 9
    Par défaut
    Merci Emamanuel pour ta réponse. Par contre je ne comprend pas la premiere ligne du code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::string majuscule = minuscule;
    for (int i=0; i<majuscule.length(); ++i)
    {
      majuscule[i] = ::toupper(majuscule[i]);
    }
    Pourquoi donner la valeur de minuscule à majuscule ?

  10. #10
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Par fainéantise - je dois créer une chaine de la même taille (modulo les remarques sur le double S allemand et sur d'autres problèmes de ce type). Plutôt que de passer par un stringstream pour créer ma chaine ou d'utiliser une autre technique, je travaille directement sur mon résultat.

    Ca fonctionne (dans ce cas), et c'est probablement une des meilleures solutions (étant donné qu'au final, je dois quand même créer une chaine de caractère de la taille souhaitée) mais ça n'en reste pas moins de la fainéantise. J'aurais pu aussi construire une chaine de la bonne taille mais composée de caractères blancs.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  11. #11
    Membre du Club
    Inscrit en
    Mai 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 9
    Par défaut
    J'ai finalement utilisé le code fourni dans la faq.
    Ca fonctionne parfaitement.
    Effectivement, on ne peut convertir un string directement en majuscule contrairement à ce qu'on mon prof nous a dit. On est obliger d'utiliser une alternative pour convertir lettre par lettre.

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include <cctype>    // pour tolower et toupper
    #include <string>    // pour string
    #include <iostream>  // pour cout
    #include <algorithm> // pour transform
     
    struct my_tolower
    { 
        char operator()(char c) const 
        {
            return std::tolower(static_cast<unsigned char>(c));
        } 
    };
     
    struct my_toupper
    { 
        char operator()(char c) const 
        {
            return std::toupper(static_cast<unsigned char>(c));
        } 
    };
     
    int main()
    {
        std::string s("ABCDEF");
     
        std::transform(s.begin(), s.end(), s.begin(), my_tolower());
        std::cout << s; // affiche "abcdef"
     
        std::transform(s.begin(), s.end(), s.begin(), my_toupper());
        std::cout << s; // affiche "ABCDEF"
     
        return 0;
    }

Discussions similaires

  1. Quel parseur XML pour des Strings ?
    Par krokmitaine dans le forum XML
    Réponses: 13
    Dernier message: 19/12/2006, 21h01
  2. Taille max pour un String
    Par arasium dans le forum Langage
    Réponses: 9
    Dernier message: 16/06/2006, 08h14
  3. Aide pour un String
    Par Kpone dans le forum Langage
    Réponses: 2
    Dernier message: 21/03/2006, 12h25
  4. Réponses: 2
    Dernier message: 23/01/2006, 15h51
  5. [C#] Fonction pour convertir string[] vers ArrayList
    Par luimême dans le forum Windows Forms
    Réponses: 6
    Dernier message: 07/04/2005, 13h25

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