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 et locale français ?


Sujet :

C++

  1. #1
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut toupper et locale français ?
    Bonjour à tous,

    Compilateur : Visual C++ 2005
    O.S : Windows XP


    J'ai un problème que je n'arrive pas à résoudre avec la mise en majuscule d'un mot contenant des accents.

    Voilà un code minimal qui reproduit le problème :

    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
     
    #include <iostream>
    #include <string>
    #include <algorithm>
     
    using namespace std;
     
    int main(void)
    {
        string first_name;
        cout << endl << "First Name : ";
        getline(cin, first_name);
     
        locale locl ("French_france");
        transform( first_name.begin(), first_name.end(), first_name.begin(), toupper );
     
         cout << endl << "First Name (uppercase) : " << first_name;
     
        return 0;
    }
    En débuggant, si j'entre "sébastien" je vois que le deuxième caractère de la string "first_name" vaut bien 0x82 (ASCII 'é'). Mais après le passage à la casse en majuscule, j'obtiens :

    S*BASTIEN

    Où '*' vaut toujours 0x82 et non 'E'.

    Coment utiliser convenablement les locales ?

    En vous remerciant.

  2. #2
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2006
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    toupper est une bonne vieille API C qui ne gère sans doute pas les locales. As-tu pensé à utilisé une librairie d'internationalisation ? Par exemple ICU : http://icu.sourceforge.net/

  3. #3
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3

  4. #4
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Merci à tout deux pour vos réponses

    toupper est une bonne vieille API C qui ne gère sans doute pas les locales.
    En fait la fonction std::toupper gère bien les locales :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<Class CharType>
       CharType toupper(
          CharType _Ch, 
          const locale& _Loc
       )
    
    En tout les cas merci Touco, je ne connaissais pas cette possibilité pour l'internationalisation. Toutefois il me semble que le C++ standard fourni cette possibilité et j'aimerais utiliser en premier lieu seulement celle-ci.


    J'ai ensuite essayé avec le code suivant, comme suggèré dans le lien fourni par Aurélien :

    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
     
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <locale>
     
    using namespace std;
     
    struct ToUpper
    {
       ToUpper(std::locale const& l) : loc(l) {;}
       char operator() (char c) const  { return toupper(c,loc); }
    private:
       std::locale const& loc;
    };
     
     
    int main(void)
    {
        string first_name;
        cout << endl << "First Name : ";
        getline(cin, first_name);
     
     
        locale lc("French_France.1252");
        ToUpper up(lc);
        transform( str.begin(), str.end(), str.begin(), up ); 
     
        cout << endl << "First Name (uppercase) : " << first_name;
     
        return 0;
    }
    Mais ca ne fonctionne toujours pas et je n'en comprend vraiment pas la cause...

    Même en utilisant le code ci-dessus, mes lettres accentuées restent accentuées après la conversion en majuscule.

    Quoi qu'il en soit, merci d'avoir pris le temps de me répondre

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Neitsa
    Compilateur : Visual C++ 2005
    O.S : Windows XP

    En débuggant, si j'entre "sébastien" je vois que le deuxième caractère de la string "first_name" vaut bien 0x82 (ASCII 'é'). Mais après le passage à la casse en majuscule, j'obtiens :

    S*BASTIEN

    Où '*' vaut toujours 0x82 et non 'E'.
    ASCII est un jeu 7 bits qui ne connait pas les accents. Il y a dans la meme serie de normes qu'ASCII(ISO-646-XX) des jeux 7 bits avec les accents, mais leur utilisation est rare de nos jours (la derniere fois que les les ai rencontre, c'etait il y a 10 ans avec une imprimante matricielle avec laquelle il fallait passer par eux pour imprimer les caracteres accentues).

    Il y a une serie de jeu 8 bits etendant l'ASCII. Je suspecte ici un conflit entre le jeu que tu utilises (apparemment CP437 ou CP850) et le jeu de Windows (CP1252, qui est une extension de ISO-8859-1). toupper devrait fonctionner correctement avec du , essaie d'avoir la majuscule de 0xE9; si c'est 0xC9 c'est bien ca le probleme.

    Une reference en passant http://czyborra.com/.

    Note: je ne suis pas du tout un connaisseur de Windows.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    ASCII est un jeu 7 bits qui ne connait pas les accents. Il y a dans la meme serie de normes qu'ASCII(ISO-646-XX) des jeux 7 bits avec les accents, mais leur utilisation est rare de nos jours (la derniere fois que les les ai rencontre, c'etait il y a 10 ans avec une imprimante matricielle avec laquelle il fallait passer par eux pour imprimer les caracteres accentues).
    Merci pour toutes ces précisions !

    essaie d'avoir la majuscule de 0xE9; si c'est 0xC9 c'est bien ca le probleme.
    BINGO ! Lors du toupper, 0xE9 devient bien 0XC9 !

    Une reference en passant http://czyborra.com/.
    Merci pour le lien ,très intéressant, c'est "bookmarké"

    Cela dit... je ne sais pas comment me sortir de ce problème de codepage à présent...

    Peut être aurais-je du mentionné que j'ai acheté ma version de Windows ... aux états-unis ? Je ne pensais pas que ca serait significatif...

    En regardant plus attentivement, le deuxième caractère de ma string est bien vu comme une virgule sous le débuggeur (avant le toupper) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            [1]    0x82 ''    char
    Donc en fait si je comprend bien, j'ai un problème entre ce que j'entre sous la console et ce que j'obtiens, en interne, dans le programme... (mon 'é' est convertit en 0x82, codepage 1252, ce qui correspond à une virgule).

    Je passe quand même le problème en résolu, puisque ca n'était que la phase de test en console (je passe au programme avec IHM ce qui résoud d'office le problème).

    Toutefois si quelq'un savait comment résoudre ce problème de codepage entre ce qui est entré et ce que le programme capte réellement, j'en serais très content (ce que je veux dire c'est "est-il possible de changer le codepage de la console windows ?")

    Merci Jean-marc pour ton aide !

    Merci à tous

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

Discussions similaires

  1. variables locales ou globales ???
    Par elvivo dans le forum C
    Réponses: 13
    Dernier message: 03/07/2002, 08h22
  2. Réponses: 2
    Dernier message: 13/06/2002, 14h50
  3. Existe-t-il un langage de prog "virtuel" en Français
    Par HRS dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 10/06/2002, 18h11
  4. Réponses: 0
    Dernier message: 07/05/2002, 12h58
  5. Peux t'on créer une copie locale de l'objet partagé?
    Par Anonymous dans le forum CORBA
    Réponses: 8
    Dernier message: 16/04/2002, 16h20

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