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 :

String, char et accent


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut String, char et accent
    Bonsoir,

    Je débute en C++ (exercice Mot Mystère sur OC) et malgré mes nombreuses recherches sur internet, je ne comprends pas.

    Je voudrais supprimer les accents d'une chaîne. Ci dessous un extrait de code qui fonctionne, si j'indique dans le code : mot="été"

    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
    int main()
    {
        string mot;
        mot = "été";
     
        cout << "Mot avant : " << mot << endl;
     
        for (int i = 0; mot[i] != '\0'; i++) {
            if (mot[i] == 'é') {
                mot[i] = 'e';
            }
        };
        cout << "Mot apres : " << mot << endl;
        return 0;
    }
    Ca fonctionne, le résultat est :
    Mot avant : ÚtÚ
    Mot apres : ete

    Maintenant, si je demande une saisie du mot :

    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
     
    int main()
    {
        string mot;
        cin >> mot;
     
        cout << "Mot avant : " << mot << endl;
     
        for (int i = 0; mot[i] != '\0'; i++) {
            if (mot[i] == 'é') {
                mot[i] = 'e';
            }
        };
        cout << "Mot apres : " << mot << endl;
        return 0;
    }
    Ca ne fonctionne pas :
    Mot avant : été
    Mot apres : été


    J'ai essayé différentes solutions proposées sur le web, transformer en tableau de char, les pointeurs, utilisation de c_str()... : je n'y arrive pas... Et surtout, il y a un truc qui m'échappe...
    Merci pour vos éléments d'explication...

    Nb : en fait, je m'en sort avec les codes ascii

    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
     
    int main()
    {
        string mot;
        int x;
     
        cin >> mot;
        cout << "Mot avant : " << mot << endl;
     
        for (int i = 0; mot[i] != '\0'; i++) {
            x = mot[i];
            if (x == -126) {
                mot[i] = 'e';
            }
        };
        cout << "Mot apres : " << mot << endl;
        return 0;
    }
    Mais là encore, le é avec cin a une valeur -126; en l'affectant à la variable dans le code : -23 avec un caractère Ú ?!?!

    Merci

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Il faut que tu comprennes la différence entre ASCII - MBCS (latin-1, shift-js, ...) - Unicode (UTF-8, UTF-16, UTF-32)

    Ensuite, il faut que tu contrôles/ maîtrises tes chaînes de caractères, parce que ta chaîne "été", quel est son encodage ?


    Bonus : C/ C++ a le support de l'ASCII (avec le type char) mais aussi de l'UTF-16 avec le type wchar_t et en mettant un L majuscule devant les chaînes de caractères (L"été")

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut
    Bonjour,

    Je te remercie pour ces réponses mais je ne sais pas trop quoi en faire.

    J'utilise C::B.
    J'ai été voir dans Settings/Editor/General settings/Encoding settings. L'encodage était WINDOWS-1252.
    J'ai changé en UTF8, UTF16, ISO-8859, recompilé : c'est toujours pareil.

    As tu des conseils ou un site qui traite de la question ?

    Merci

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par cc85 Voir le message
    J'utilise C::B.
    J'ai été voir dans Settings/Editor/General settings/Encoding settings. L'encodage était WINDOWS-1252.
    J'ai changé en UTF8, UTF16, ISO-8859, recompilé : c'est toujours pareil.
    Ceci c'est l'encodage de tes fichiers sources et non pas de tes chaînes de caractères [constantes]


    Citation Envoyé par cc85 Voir le message
    Je te remercie pour ces réponses mais je ne sais pas trop quoi en faire.
    • été -> ASCII n'existe pas
    • été -> UTF-8 - "\uC3\uA9\u74\uC3\uA9" ou "\uC3\uA9t\uC3\uA9"
    • été -> UTF-16 - L"été" ou "\U00E9\U0074\U00E9"
    • été -> latin-1 - "\xE9t\xE9"


    Si tu ne vois pas des différences, va à l'ophtalmologue
    Tu ne peux pas comparer \xE9 avec \U00E9 avec \uC3 avec \uA9.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut
    Merci encore d'avoir répondu, mais ce n'est pas un ophtalmo qu'il me faut mais des conseils pour débutant.
    Pas grave, je vais faire autrement.
    Bonne journée.

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Pour être gérés par un logiciel les caractères doivent être encodés. Quand on utilise la touche 'é', l'éditeur de texte va reconnaître la touche, et va afficher un 'é'. Comme un fichier c'est fait d'octets, au moment de la sauvegarde, l'éditeur va stocker un nombre équivalent à ce caractère. La correspondance entre tous les caractères possibles et leur nombre associé est ce que l'on appelle un codepage.
    1. Dans un octet, on ne peut stocker qu'un nombre compris entre 0 et 255. Dans certaines langues c'est suffisant, mais on doit choisir un codepage compatible avec la langue. par exemple Wndows1252 ou IBM850 ou ISO-8859-1 sont compatibles avec les caractères français.
    2. On peut sinon utiliser 4 octets pour un caractère, et dans ce cas tous les caractères du monde tiennent dans cette table. La norme ISO-10646 défini ces codes que l'on retrouve sous le nom UTF-32.
    3. on peut aussi utiliser des encodages dont la taille est variable, par exemple :
      1. L'UTF-8 code tous les caractères sur 1, 2, 3 ou 4 octets
      2. L'UTF-16 code tous les caractères sur 2 ou 4 octets.
    Revenons à notre programme. Les fichiers sources utilisent un encodage. Le fichier compilé aura lui aussi des encodages internes. Quand le programme se déroule, va devoir s'adapter aux périphériques avec lequel il communique (les fichiers, la console, un driver graphique). Si tout le monde utilise le même encodage, il n'y aura aucun problème, sinon il faut que le programme s'adapte.
    1. On écrit dans le code source "été"
    2. l'éditeur va stocker cette séquence en utilisant un encodage. p.e Windows1252 => <E9 74 E9>
    3. le compilateur va lire la séquence (il doit connaître l'encodage du fichier)
      et ce qu'il va mettre dans le code dépend du préfixe :
      • u8"été" ===> 5 char UTF-8 : <C3 A9 74 C3 A9>
      • u"été" ===> 3 char16_t UTF-16: <00E9 0074 00E9>
      • U"été" ===> 3 char32_t UTF-32: <000000E9 00000074 000000E9>
      • L"été" ===> 3 wchar_t (dépend du compilateur souvent UTF-16 ou UTF-32)
      • "été" ===> dépend de la pagecode de compilation (vraisemblablement Windows1252 chez toi) <E9 74 E9>
    4. le programme se déroule, il veut transmettre la chaîne à la console <E9 74 E9>
    5. la console reçoit les caractères (sous windows elle est souvent en codepage IBM850)
      elle interprète les caractère comme E9->Ú 74->t E9->Ú ==> "ÚtÚ"
    Ton problème donc est que la console n'a pas le même pagecode que ton programme.

    Des solutions possibles :
    • prévenir le compilateur pour qu'il utilise la pagecode IBM850 pour les chaînes sans préfixe comme "été"
      (la méthode dépend du compilateur utilisé pour gcc : -fexec-charset , pour visualstudio : #pragma execution_character_set)
    • demander à la console d'utiliser la pagecode Windows-1252
      (exécuter un system("chcp 1252"); au début du programme peut fonctionner)
    • faire que ton programme traduise de sa pagecode vers celle de la console, et inversement au retour. C'est très lourd si un des 2 n'est pas en UTF.
    • utiliser un des encodages UTF8, UTF16 ou UTF32 pour lesquels les conversions éventuelles sont plus simple. Mais il faudra aussi s'assurer que la console utilise le même encodage ou effectuer les conversions nécessaires.

    Sous Windows la dernière est la plus compliquée, sous Linux c'est la plus simple. Indispensable surtout si on souhaite écrire un programme internationalisable.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Conseil pour débutant : n'utilise pas d'accents, et encore moins en console.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 42
    Points : 38
    Points
    38
    Par défaut
    Bonjour,

    Merci Bousk pour ta réponse et je suis ok.
    Je me suis sans doute mal exprimé mais le but de mon programme est justement que si l'utilisateur saisi des accents dans la réponse, le programme enlève les accents pour un affichage correct.
    Le problème est que lorsque je mets la chaîne dans le programme, if (mot[i] == 'é') fonctionne. Quand je saisi avec un cin, ça ne fonctionne pas.

    Merci Dalfab pour ta réponse très pédagogique. J'ai tout compris ! Enfin presque...
    J'ai ajouté :
    et
    Et tout fonctionne à merveille, à la fois pour l'affichage et pour la suppression des accents : if (mot[i] == 'é') fonctionne.

    Il me reste à bosser la question des wchar_t et cie...

    Merci encore et bon dimanche !

  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    A priori, il vaudrait mieux utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #if defined WIN32
    system("chcp 1252");
    #endif
    En effet, cette fonctionalité n'est disponible que dans les consoles Windows, il ne sert à rien de l'invoquer sur un Linux ou autre.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

Discussions similaires

  1. replaceAll(String, Char) problème
    Par SheikYerbouti dans le forum Langage
    Réponses: 8
    Dernier message: 05/03/2007, 17h20
  2. Réponses: 3
    Dernier message: 25/10/2006, 22h54
  3. map<string,char,ConvOrdre>
    Par Stany dans le forum SL & STL
    Réponses: 6
    Dernier message: 03/05/2006, 14h30
  4. Problème avec fonctions et string/char
    Par vdumont dans le forum C++
    Réponses: 6
    Dernier message: 08/04/2006, 16h54
  5. Mauvais tri des String avec des accents
    Par lbreuillard dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 23/09/2005, 12h21

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