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 :

Unicode


Sujet :

C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut Unicode
    Bonjour , voilà je rencontre un problème lorsque je veux afficher un caractère spécial à partir de son unicode par exemple, j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    using namespace std;
     
    #include <iostream>
     
     
    int main ()
    {
       char f = '\u0023';     //en base 16
       cout << f << endl;
       cout<<"#"<<endl;
     
       return 0;
    }
    ici pour afficher #, mon programme fonctionne.

    En revanche, lorsque je veux essayer avec un autre caractère par exemple ê j'écris f='\u00ea' et là rien...c'est un symbole bizarre qui s'affiche (même chose pour d'autres symboles...)
    Mais si je marque cout<<"ê"; l'affichage se fait correctement...

    Je ne comprends pas... Pourquoi certains caractères ne fonctionnent pas ?
    Je ne sais pas si cela peut aider mais j'utilise codeblocks sous linux.
    En vous remerciant par avance de votre aide.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    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 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Je pense que c'est normal Regarde bien: en plus de créer une variable (certes locale) qui ne sert à rien, elle est de type char.

    Tu demandes à cout d'afficher un caractère ascii supérieur à 127

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    parce que cout n'affiche pas les caractères ascii supérieur à 127 dans ce cas comment faire?

  4. #4
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    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 : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Cout peut le faire, mais tu vas avoir beaucoup de mal à faire rentrer un caractère unicode de 2 octets dans un type char qui n'en fait que 1...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    test.cpp:6:13: warning: multi-character character constant [-Wmultichar]
        char c = '\u00ea';
                 ^
    Le plus simple est de passer par des chaînes de caractères pour afficher un caractère: std::cout << "\u00ea";.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Merci effectivement je vois que ça fonctionne mais je ne comprends pas pourquoi 00ea fait 2 octets en effet ça fait 11101010 en binaire (donc ça devrait pouvoir rentrer dans 1o) ?

  6. #6
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 694
    Points : 2 425
    Points
    2 425
    Par défaut
    Salut.

    Savoir combien il y a d'octets dans un nombre hexadécimal est simple, il suffit de découper le nombre hexa en paquets de deux chiffres, puis de compter le nombre de paquets.
    Donc 00 ea est bien sur deux octets (0000 0000 1110 1010 en big-endian), le 00 compte aussi.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Merci, d'accord mais dans ce cas le caractère unicode 0023 est également sur 2o et pourtant il s'affiche correctement dans un type char (ça doit faire alors 0000 0000 0010 0011) ? Pourquoi cela marche pour l'un et pas pour l'autre?

  8. #8
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 694
    Points : 2 425
    Points
    2 425
    Par défaut
    C'est quelque chose qui ne doit normalement pas marcher, un char a une taille de 1 byte, soit 1 octet sur nos systèmes.
    Comme l'a montré jo_link_noir, le compilateur te dira que ça n'est pas bon.

    Comment est-ce que tu compiles ton programme ?
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    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 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Il faut passer par un wchar_t c = '\u0023'; (<- mais pas testé )

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Pour compiler le programme, j'utilise g++ de GNU GCC Compiler, j'ai essayé d'utiliser le type wchar_t mais alors là pour le caractère 0023 j'obtiens le numéro 35 lors de l'affichage...

    De plus, même en utilisant un type string ce n'est pas tout les caractères unicodes qui fonctionnent...

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    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 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par crabenfolie Voir le message
    pour le caractère 0023 j'obtiens le numéro 35 lors de l'affichage...
    0x23 == 35


    Citation Envoyé par crabenfolie Voir le message
    De plus, même en utilisant un type string ce n'est pas tout les caractères unicodes qui fonctionnent...
    std::wstring (ici) et std::wcout (ici)

    De plus, tu as le choix entre %s, %ls, %hs et %S et printf/ wprintf

    Mais je ne suis jamais arrivé à faire fonctionner le %ls pour l'Unicode UTF-16

  12. #12
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 562
    Points : 7 628
    Points
    7 628
    Par défaut
    Bonjour,

    Quand on écrit un simple caractère entre les apostrophes :
    * si ce caractère est représentable sous la forme d'un octet, on aura un char qui contient cet octet, char x = 'a'; // ok 'a'.
    * sinon le caractère nécessite plusieurs octets (dans le format d'édition du code source), et donc un U.B.
    char x = 'β'; // => warning '\u03B2' ne peut pas être représenté dans la page de codes actuelle (1252).

    Si on place une séquence escape \u ou \U entre les apostrophes :
    * si le caractère correspondant peut être codé en un octet utf8, on aura un char qui contient cet octet, char x = 'u00C0'; // ok 'À'.
    * sinon le caractère nécessite plusieurs octets, on a un Undefined.Behavior.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char x = '\u03B2'; // => warning '\u03B2' ne peut pas être représenté dans la page de codes actuelle (1252)
    char y = '\u00C0'; // ok
    char z = 'é';
    // Si essaie d'afficher ces caractères dans un flux CP1252
    cout << x; // => caractère quelconque p.e '?'
    cout << y; // => À
    cout << z; // => é
    Si on est dans un flux UTF-8, aucun des trois caractères ne pourra être géré (tous sont supérieurs à 128)

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Savoir aussi que sous Windows, la console n'utilise pas le même jeu de caractères que le reste (pour des raisons historiques): Windows est généralement en encodage Windows-1252 en occident, mais la console utilise l'encodage IBM-850 (en europe) ou IBM-437 (aux USA) à la place.
    Et selon les versions de la C Run-Time Library, diverses fonctions d'écriture gèrent ou non la conversion UTF-16 -> IBM-850 correctement. Il y en a plein qui font un bête cast du wchar_t en char, résultat ça ne marche pas. D'autres encore affichent des points d'interrogation pour tout ce qui n'est pas déjà un caractère supporté par IBM-850...

    Résultat, on a souvent besoin de faire la conversion soi-même, ou de passer par des fonctions Windows (comme WriteConsoleW()) pour écrire. Et si l'on ajoute la possibilité de rediriger la sortie d'un programme vers un fichier (exemple: monProgramme.exe >sortie.Txt), c'est encore pire! Notamment parce que WriteConsoleW() ne le supporte pas.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    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 : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    J'ai lu sur h-deb que l'utilisation de locale::global(locale{""}); sur Windows permet de passer la console au format OEM, ce qui permet d'afficher les accents. Et probablement d'autres caractères.

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    D'accord merci pour vos réponses j'affiche à afficher presque tous les caractères à présent et je comprends un peu mieux le fonctionnement de l'unicode...
    Par contre, une dernière question concernant les types j'ai du mal à comprendre les différences entre char et wchar_t (c'est pour afficher des caractères plus grands )de même pour string et wstring et cout et wcout.
    Quelles sont les différences?Comment fonctionne ces types?

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    La théorie originelle (avant la généralisation d'UTF-8), c'est que le type char ne peut représenter que 256 caractères différents (on appelle ça un jeu de caractères). Ce qui est trop peu pour les différents pays, évidemment, c'est pour ça que les ordinateurs supportaient plusieurs jeux (mais selon l'os, pas forcément en même temps).

    Unicode a été créé pour faire un jeu de caractère "global" contenant tous les caractères possibles. À l'origine, Unicode fut créé avec 65536 caractères possibles: C'est là que furent nés les wchar_t de Windows, les char de Java... Ainsi, on pouvait directement tout afficher sans avoir à changer de jeu de caractères en cours de route!

    Depuis, le jeu de caractère Unicode a été agrandi, et supporte maintenant 65536×17 possibles caractères (20.1 bits, il faut donc 21 bits par caractère). Problème: Ça ne tient plus sur 16 bits! Alors il a fallu créer des encodages d'unicode, pour représenter un caractère unicode en plusieurs char ou wchar_t: UTF-8 (qui utilise jusqu'à 4 char pour un caractère Unicode) ou UTF-16 (qui utilise jusqu'à deux wchar_t pour un caractère unicode).

    De nos jours, la plupart des Linux utilisent UTF-8 comme encodage, ce qui veut dire qu'on n'a plus vraiment besoin de wchar_t pour afficher des caractères élaborés. Ce n'est pas le cas sous Windows: le support sur Console est compliqué comme je l'ai mentionné, et l'affichage dans des fenêtres utilise UTF-16 sans vraiment supporter UTF-8 (les fonctions comme DrawTextA() peuvent convertir automatiquement depuis un ancien jeu de caractères vers UTF-16, mais ne peuvent pas convertir automatiquement depuis UTF-8: Il faut faire la conversion manuellement).


    *Note: Je suis sûr qu'il y a plein d'inexactitudes au niveau historique dans ce que je dis, mais c'est ce qui explique le plus facilement.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 826
    Points : 218 287
    Points
    218 287
    Billets dans le blog
    117
    Par défaut
    Bonjour,

    Cette ressource peut aider à comprendre les problématiques : http://www.utf8everywhere.org/ (et se rappeler de l'histoire).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup c'est plus clair

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

Discussions similaires

  1. Comment insérer de l'unicode dans un Richedit ?
    Par DanaKil dans le forum C++Builder
    Réponses: 6
    Dernier message: 30/03/2004, 01h43
  2. Utilisation de l'unicode dans un algo de cryptage
    Par Zazeglu dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 28/10/2003, 15h38
  3. [Unicode] Internationalisation d'une application
    Par Thierry Laborde dans le forum Langage
    Réponses: 4
    Dernier message: 21/10/2003, 21h15
  4. conversion Unicode -> ASCII
    Par juzam dans le forum C
    Réponses: 8
    Dernier message: 24/07/2003, 11h07
  5. [debutant] unicode
    Par dadou91 dans le forum XML/XSL et SOAP
    Réponses: 7
    Dernier message: 23/05/2003, 11h12

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