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 :

Utiliser du texte avec des accents


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut Utiliser du texte avec des accents
    Bonjour,

    Je débute en programmation cpp et j'ai un petit problème avec un tuto.

    Voilà ce qu'ils disent:
    Un mot sur Windows

    Si vous êtes sous Windows et que vous tentez d’afficher du texte avec des accents, vous allez obtenir des caractères bizarres. Pour afficher du code avec des accents, vous allez devoir ajouter les lignes 2, 3 et 8 dans votre code. Nous en reparlerons plus tard.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>
    #define NOMINMAX
    #include <Windows.h>
     
    int main()
    {
        // À utiliser avant d'afficher du texte.
        SetConsoleOutputCP(1252);
        std::cout << "Oui, je peux utiliser éèàï !" << std::endl;
    }
    Le problème c'est qu'après avoir compilé leur code, voilà ce que j'obtiens:
    Oui, je peux utiliser éèÃ*ï !

    Donc pas du tout la même phrase qu'eux..
    D'où vient le problème ?

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 746
    Points : 3 667
    Points
    3 667
    Par défaut
    Cela est très dépendant du format d'enregistrement des fichiers. J'ai l'impression que tu enregistres en utf-8, mais configure la console en ANSI Latin 1 -> les formats ne sont pas compatibles, l'affichage ne correspond pas. Il faudrait utiliser 65001 à la place de 1252.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Ah oui, ça fonctionne parfaitement avec 65001.
    2ème code que je teste dessus et 1er plantage..
    Jme demande si je ne dois pas changer de tuto, mais c'est difficile d'en trouver des récents..
    En tout cas merci pour ton aide..

    edit: Encore plus bizarre que personne ne leur ait signalé leur erreur depuis le temps, ce que je viens de faire.

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Le code marche parfaitement tel quel sur mon Windows 10 en compilant avec VS2019.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Le code marche parfaitement tel quel sur mon Windows 10 en compilsant avec VS2019.
    Ba moi aussi je suis sous Windows 10 avec vs2019 et ça ne fonctionne pas..

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Le code est tout de même bof et plein de valeurs magiques.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <iostream>
    #include <windows.h>
     
    int main()
    {
        SetConsoleOutputCP(CP_UTF8);
        std::cout << u8"Oui, je peux utiliser éèàï !";
    }
    Est plus lisible et montre clairement l'objectif.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Ouais c'est clair ^

  8. #8
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 580
    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 580
    Points : 7 712
    Points
    7 712
    Par défaut
    La gestion des accents dépend de beaucoup de choses :
    - le compilateur
    - l'éditeur de texte
    - le code page de la console.

    Sous Linux, les trois sont presque toujours en UTF-8, donc il y a rarement des problèmes.
    Sous Windows :
    - la plupart des fichiers textes sont au format : 1252 (Western European Windows appelé aussi ANSI) en Europe et Amérique.
    - la console est par défaut au format : 850 (Western European DOS) en Europe.
    - et chaque compilateur a sa propre gestion par défaut des charset.

    La séquence saisie dans un éditeur de code va traverser 4 étapes avant d'arriver à la console.
    a) stockage du fichier source dans un code-page donné (p.e.:1252)
    b) au moment de la compilation du fichier, le compilateur suppose que le fichier est dans un format donné (par défaut source-charset vaut .1252 avec MSVC) et le convertit dans le code dans un code-page donné (par défaut execution-charset vaut .1252 avec MSVC)
    c facultative) quand le code se déroule, il peut convertir ses chaînes (de UTF-8 vers un code-page ou inversement)
    d) le texte est émis vers la console, le texte et la console doivent utiliser le même code-page (la console Windows est par défaut en 850)

    D'où le conseil de la formation : sous Windows forcer la page code console à 1252, comme les autres étapes sont habituellement toutes à 1252, ça devrait fonctionner. Sauf qu'ici un des éléments n'a pas les valeurs auquel on s'attend sous Windows.
    Sous Windows, cette méthode a pas mal d'avantages si on ne veut pas utiliser des caractères exotiques. Par exemple dans une chaîne, chaque caractère correspond à un seul char. En utilisant l'UTF-8 on perd cette simplification.

    Sinon on peut facilement décider d'utiliser l'UTF-8 :
    - l'étape (a), on peut sauvegarder les fichiers sources au format UTF-8 avec BOM. Sans cela, il faut toujours s'assurer que le fichier est enregistré au format attendu par le compilateur, par exemple sous MSVC on a l'option /source-charset:.codepage.
    - Pour l'étape (b) on paramètre le compilateur, par exemple sous MSVC avec l'option /execution-charset:.65001.
    - Pas besoin d'étape (c)
    - Pour l'étape (d), on force la console en UTF-8 par la commande SetConsoleOutputCP( 65001 );.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 669
    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 669
    Points : 10 674
    Points
    10 674
    Par défaut
    Le mieux c'est d'échapper les caractères , même si tes chaînes de caractères sont moins exploitables/ lisibles

    C: échappement des caractères \n, \x, \u, \U (<- lien wiki en anglais)

    Mais dans mon code, sous Cygwin, l'ANSI et le wcout ne fonctionne pas bizarre

    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
    35
    36
    37
    38
    39
    40
    #include <iostream>
     
    #include <cstdlib>
    #include <windows.h>
     
     
    /*****************************************************************************/
    /***********************************  Main  **********************************/
    /*****************************************************************************/
     
    int main(int argc, char** argv)
    {
        const char ansi_str[]     =  "Oui, je peux utiliser \xE9\xE8\xE0\xEF !";
        const char UTF8_str[]     =  "Oui, je peux utiliser \xC3\xA9\xC3\xA8\xC3\xA0\xC3\xAF !";
        const wchar_t UTF16_str[] = L"Oui, je peux utiliser \u00E9\u00E8\u00E0\u00EF !";
     
        std::string ansi_std_str("Oui, je peux utiliser \xE9\xE8\xE0\xEF !");
        std::string UTF8_std_str("Oui, je peux utiliser \xC3\xA9\xC3\xA8\xC3\xA0\xC3\xAF !");
        std::wstring UTF16_std_str(L"Oui, je peux utiliser \u00E9\u00E8\u00E0\u00EF !");
     
        SetConsoleOutputCP(1252 /* windows-1252 */);
        std::cout << "ANSI:   Oui, je peux utiliser \xE9\xE8\xE0\xEF !" << std::endl <<
                     "        " << ansi_str << std::endl <<
                     "        " << ansi_std_str << std::endl;
     
     
        SetConsoleOutputCP(65001 /* utf-8 */);
        std::cout << "UTF-8:  Oui, je peux utiliser \xC3\xA9\xC3\xA8\xC3\xA0\xC3\xAF !" << std::endl <<
                     "        " << UTF8_str << std::endl <<
                     "        " << UTF8_std_str << std::endl;
     
     
        SetConsoleOutputCP(1200 /* utf-16 */);
        std::cout << "UTF-16: Oui, je peux utiliser \u00E9\u00E8\u00E0\u00EF !" << std::endl;
        std::wcout << L"        " << UTF16_str << std::endl
                   << L"        " << UTF16_std_str << std::endl;
     
     
        return EXIT_SUCCESS;
    }

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Le code est tout de même bof et plein de valeurs magiques.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <iostream>
    #include <windows.h>
     
    int main()
    {
        SetConsoleOutputCP(CP_UTF8);
        std::cout << u8"Oui, je peux utiliser éèàï !";
    }
    Est plus lisible et montre clairement l'objectif.
    J'ai testé ta solution, mais ça m'écrit encore: Oui, je peux utiliser éèÃ*ï !

    La police de ma console c'est consolas, je crois que c'est la police par défaut non ? (je ne me rappel plus si je l'ai changé)
    Je ne comprend pas ce qui bug sur mon pc qui a pourtant windows 10 et vs2019

    edit: J'ai testé avec d'autres polices ça donne le même résultat

  11. #11
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 580
    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 580
    Points : 7 712
    Points
    7 712
    Par défaut
    Bonjour,

    Utiliser les caractères d'échappement permet de gérer le problème du format de fichier. Mais il ne sert qui si on utilise les \u et \U, ainsi l'étape que j'ai appelée (a) est résolue (par besoin d'enregistrement particulier du fichier, et tous les textes sont en UTF)
    Mais l'utilisation des \x est plutôt une complication de portabilité, on force des caractères codé (la Cp1252 ou l'UTF-8 dans l'exemple de foetus) qui gérerait les étapes (a) et (b). J'utilise le conditionnel car le \x devient trop compliqué pour moi.
    Pour simplifier l'étape (b) on peut aussi utiliser les préfixes de chaîne u8, u ou U qui vont garantir que la chaîne concernée dans le code est au format UTF au lieu ce celui par défaut indiqué dans /execution-charset:. On a aussi le préfixe L qui utilise des chaînes standardisées, je ne sais pas s'il est configurable sous Windows, il correspond plutôt à l'UCS2.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Ok merci pour cette explication.
    Mais moi j'aimerais quand même comprendre pourquoi 1252 fonctionne chez Bousk et pas chez moi alors qu'on a la même config (win10+vs2019)

  13. #13
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 432
    Points : 1 128
    Points
    1 128
    Par défaut
    Bonjour


    Mais moi j'aimerais quand même comprendre pourquoi 1252 fonctionne chez Bousk et pas chez moi alors qu'on a la même config (win10+vs2019)
    Parce que chez toi, le texte de ton programme est sauvegardé en UTF8 et chez Bousk en ANSI 1252 (ça c'est souvent un paramètre de ton éditeur de texte (intégré ou pas à ton EDI))

    Cordialement

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Ok merci bien

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    J'ai même essayé avec Cygwin mais ça me retourne une erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $ gcc test.cpp -o test.exe
    /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld*: /tmp/ccdsi2jS.o:test.cpp:(.text+0x2a)*: référence indéfinie vers «*std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)*»
    /tmp/ccdsi2jS.o:test.cpp:(.text+0x2a): relocalisation tronquée pour concorder avec la taille*: R_X86_64_PC32 vers le symbole indéfini std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
    /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld*: /tmp/ccdsi2jS.o:test.cpp:(.text+0x5e)*: référence indéfinie vers «*std::ios_base::Init::Init()*»
    /tmp/ccdsi2jS.o:test.cpp:(.text+0x5e): relocalisation tronquée pour concorder avec la taille*: R_X86_64_PC32 vers le symbole indéfini std::ios_base::Init::Init()
    /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld*: /tmp/ccdsi2jS.o:test.cpp:(.rdata$.refptr._ZNSt8ios_base4InitD1Ev[.refptr._ZNSt8ios_base4InitD1Ev]+0x0)*: référence indéfinie vers «*std::ios_base::Init::~Init()*»
    /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld*: /tmp/ccdsi2jS.o:test.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0)*: référence indéfinie vers «*std::cout*»
    collect2: erreur: ld a retourné le statut de sortie 1
    Non sérieux, j'aimerais vraiment comprendre pourquoi ça fonctionne chez Bousk et pas chez moi...
    Je veux que ça fonctionne avec l'option 1252 chez moi, comment je dois faire ?
    edit: Et quand j'essaie de lancer mon programme compilé avec vs2019 via la fenêtre de Cygwin ça ne m'affiche rien du tout..

    Merci..

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 669
    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 669
    Points : 10 674
    Points
    10 674
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc test.cpp -o test.exe
    non je ne comprends pas ca ne compile pas

    • gcc : compilateur/ éditeur de liens C
    • g++ : compilateur/ éditeur de liens C++


    Et au passage, utilise "-Wall" pour activer tous les avertissements

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    A voilà ça fonctionne. Je suis désolé mais je suis tellement habitué à utiliser gcc sous Linux que je n'ai pas pensé qu'il fallait utiliser g++.
    Mais là ça fonctionne j'ai bien les caractères normal.

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Le problème d'affichage de caractères ne vient pas de mon éditeur de texte, c'est un problème de compilation.
    Car quand je compile mon programme.cpp dans cygwin, les caractères sont bons, mais quand j'essaie de lancer mon programme.cpp (qui a été compilé avec vs2019) dans cygwin, là ça ne fonctionne pas.. Ca me donne toujours ce résultat :

    $ ./ConsoleApplication1.exe
    Oui, je peux utiliser éèÃ*ï !

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/04/2011, 17h26
  2. [perl/Tk] inserer du texte avec des accents
    Par seben dans le forum Langage
    Réponses: 1
    Dernier message: 25/01/2008, 09h46
  3. Recherche avec des accents!?
    Par mona dans le forum Access
    Réponses: 3
    Dernier message: 14/06/2005, 20h36
  4. [Javascript] Afficher du texte avec des intervalles
    Par Invité4 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 02/01/2005, 21h29
  5. Réponses: 1
    Dernier message: 06/08/2003, 11h48

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