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 :

Affichage de caractères latins et non latins


Sujet :

C++

  1. #1
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut Affichage de caractères latins et non latins
    Bonjour !

    Je me permets de poster un sujet ici concernant l'affichage simultané de caractères latins et non latins en c++, en console (sous windows); problème devant lequel je bute et dont les multiples solutions trouvées ne convenaient pas jusqu'à maintenant.

    Voici le code:
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <limits>
    #include <cstdlib>
     
     
    int main()
    {
    	std::string name, lang, line;
    	bool is_lang = false;
     
    //A_LISTER LES FICHES
        std::cout << "Здравствуйте !" << std::endl;
    	std::cout << "FICHIERS DISPONIBLES EN LECTURE:" << '\n' << '\n' << std::endl;
    	system( "dir c:\temp /A /B /O:GEN" );
     
    //B_SAISIR NOM DE FICHE
    	std::cout << '\n' << "Entrer le nom de fichier:" << std::endl;
    	std::getline( std::cin, name );
     
    //C_SAISIR LA LANGUE D'AFFICHAGE
    	std::cout << '\n' << "Choix de la langue: [FR|RU]" << '\n' << std::endl;
    	std::getline( std::cin, lang );
     
    //D_AFFICHER LES MOTS DE LA PARTIE "LANGUE" A "FIN_LANGUE"
        // le constructeur de ifstream permet d'ouvrir un fichier en lecture
        std::ifstream File( name.c_str() ); //nécessité de convertir le string en char
     
        if ( File ) // ce test échoue si le fichier n'est pas ouvert
        {
            // cette boucle s'arrête dès qu'une erreur de lecture survient ou qu'on arrive à la fin de la section
            while ( std::getline( File, line ) && line != "END_"+lang)
            {
                if(is_lang)
    			{
    				// afficher la ligne à l'écran
    				std::cout << line;
    			}
    			if(line == lang) {is_lang=true;}
            }
    		//pause:
    		std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    		//nettoyage du buffer et rembobinage au début
    		File.clear();
    		File.seekg(0, std::ios::beg);
     
    //E_A CHAQUE FOIS QU'ON APPUIE SUR ENTREE, AFFICHER LA REPONSE
     
    		std::cout << '\n' << "Appuyer sur entrée pour afficher la correction" << '\n' << std::endl;
    		if(lang == "RU")
    		{
    			lang = "FR";
    		}
    		else
    		{
    			lang = "RU";
    		}
    		while ( std::getline( File, line ) && line != "END_"+lang)
            {
    			if(is_lang)
    			{
    				// afficher la ligne à l'écran
    				std::cout << line;
    				//pause:
    				std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    			}
    			if(line == lang) {is_lang=true;}
            }
    		File.clear();
    		File.seekg(0, std::ios::beg);
        }
     
    //F_APPUYER SUR X TOUCHE POUR REVENIR AU MENU
     
    	std::cout << '\n' << "Appuyer sur entrée pour revenir au menu" << std::endl;
    	std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
     
    	return 0;
     
    }
    En cours de confection donc, mais le problème est là: impossible d'afficher ce "Здравствуйте !", j'ai utilisé plusieurs propositions de plusieurs autres forums, (ex: setlocale), mais, dans l'échec, je viens donc demander de l'assistance ici.

    Une solution à proposer ?

    EDIT:
    NB: il semble que sur les forums de developez, la balise code convertisse automatiquement les caractères cyrilliques; dans mon code il s'agit bien d'un std::cout << "Здравствуйте !" << std::endl; tel quel.

  2. #2
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Ca semble fonctionner avec un std::setlocale et std::wcout.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
    #include <clocale>
     
    int main(int, char**) {
    	std::setlocale(LC_ALL, "russian_russia.866");
    	std::wcout << L"Здравствуйте !" << std::endl;
     
    	return 0;
    }


    L'affichage dans la console devrait fonctionner aussi, à condition d'avoir une police gérant ces caractères.

  3. #3
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Dans ce but j'avais déjà changé la police pour Lucida Console, or voilà le résultat avec le code donné ci-dessus:

    Nom : console.png
Affichages : 264
Taille : 19,3 Ko
    Images attachées Images attachées  

  4. #4
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Du coup, ce serait un problème non lié au code ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Commande à taper: chcp 65001

  6. #6
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Merci beaucoup foetus, pour ce qui est du texte russe, il s'affiche maintenant: j'avais tenté la commande auparavant mais sans le wcout en même temps. Toutefois dans mon programme maintenant l'erreur vient ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if(is_lang)
    {
    // afficher la ligne à l'écran
    		std::wcout << line;
    }
    Je ne dois pas employer correctement wcout mais j'avoue ne pas bien comprendre la page de c++ reference.

  7. #7
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    wcout affiche des caractères larges. "foo" ne convient pas, il faut utiliser L"foo".

    De même si tu utilises desstd::string il seront à remplacer par des std::wstring.

  8. #8
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    En fait tu ne comprends pas ce que tu fais

    Tu as passé ta console de MBCS à UTF-8
    Mais wcout dois te sortir de l'UTF-16

    Donc il faut faire printf("\xD0\x97\xD0\xB4\xD1\x80\xD0\xB0\xD0\xB2\xD1\x81\xD1\x82\xD0\xB2\xD1\x83\xD0\xB9\xD1\x82\xD0\xB5 !");.


  9. #9
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    wcout affiche des caractères larges. "foo" ne convient pas, il faut utiliser L"foo".

    De même si tu utilises desstd::string il seront à remplacer par des std::wstring.
    D'accord mais par contre getline ne prend pas de wstring, par quoi remplacer du coup ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( std::getline( File, line ) && line != "END_"+lang)
    Et si je peux demander, qu'est-ce qu'un caractère large, en fait ?

  10. #10
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Citation Envoyé par Io-EE Voir le message
    Et si je peux demander, qu'est-ce qu'un caractère large, en fait ?
    Il faut te documenter caractères larges -> UTF-16 [on met un L majuscule devant les chaînes de caractères]
    Sinon c'est de l'ASCII ou de l'UTF-8.

    Microsoft a 2 jeux de fonctions: celles qui finissent par W et celles par A.

  11. #11
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Citation Envoyé par foetus Voir le message
    Il faut te documenter caractères larges -> UTF-16 [on met un L majuscule devant les chaînes de caractères]
    Sinon c'est de l'ASCII ou de l'UTF-8.

    Microsoft a 2 jeux de fonctions: celles qui finissent par W et celles par A.
    C'est clair, se documenter est indispensable mais je dois avouer prendre un plaisir particulier lorsque mon interlocuteur partage ses connaissances -selon son bon vouloir c'est sûr !

    Et le printf, j'espère que c'était un trait d'humour (je pensais en avoir fini avec le c++ de printf -malgré son utilité) ou il y a vraiment un intérêt ?

  12. #12
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Mais le domaine est trop large et trop piégeux pour être partagé. Et en plus le C/ C++ gère très mal les encodages. [le C++ 11 améliore les choses]

    Lorsque je dis "très mal", ce n'est pas vraiment vrai: cela dépend si tu vois le verre à moitié plein ["c'est fonctionnel"] ou à moitié vide ["c'est à toi de faire attention à l'encodage même de tes fichiers source et à faire les conversions"].

    Sinon, le print n'est pas une blague: cout est tellement mauvais en formatage et conversion (*)
    Mais tu peux le remplacer par un cout.



    * -> J'ai même vu sur stackoverflow que endl était très lent parce qu'il vidait le tampon d'écriture

  13. #13
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Mettons que j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s", line.c_str());
    Le problème que j'ai mentionné plus haut persiste:

    Citation Envoyé par Io-EE Voir le message
    D'accord mais par contre getline ne prend pas de wstring, par quoi remplacer du coup ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( std::getline( File, line ) && line != "END_"+lang)
    ?

  14. #14
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Ton fichier est en ASCII, en UTF-8 ou en UTF-16?

    Il faut ouvrir ton fichier en binaire

    Si c'est de l'ASCII ou de l'UTF-8, ce sont des char classiques.

    Si c'est de l'UTF-16: je pense qu'il faut lire un tableau (<- A.K.A. chaîne de caractères) de char et le caster/ copier/ reinterpret_cast dans une chaîne UTF-16 [un wchar_t* ou wchar_t[] ]

    Maintenant que tu travailles en C++ avec la STL et non pas en pur C avec les API natives (*), il faut que tu lises la documentation pour ne pas te faire avoir : char ou wchar_t? Ouverture binaire ou pas? Interprétation du caractère '\0' (en UTF-16 tu en as pleins) ...


    * -> L'avantage de l'API Windows c'est de gérer les chemins en Unicode

  15. #15
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Citation Envoyé par foetus Voir le message
    * -> J'ai même vu sur stackoverflow que endl était très lent parce qu'il vidait le tampon d'écriture
    Tout à fait (en).

  16. #16
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    La taille du wchar_t peut être 32 bits, c'est le cas sur ma machine. Il vaut mieux éviter de le traiter comme étant d'une taille fixe et juste le considérer comme pouvant accueillir un caractère large, quel qu'il soit.

  17. #17
    Membre régulier
    Femme Profil pro
    Ludocrate
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ludocrate

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut
    Citation Envoyé par foetus Voir le message
    Ton fichier est en ASCII, en UTF-8 ou en UTF-16?

    Il faut ouvrir ton fichier en binaire

    Si c'est de l'ASCII ou de l'UTF-8, ce sont des char classiques.

    Si c'est de l'UTF-16: je pense qu'il faut lire un tableau (<- A.K.A. chaîne de caractères) de char et le caster/ copier/ reinterpret_cast dans une chaîne UTF-16 [un wchar_t* ou wchar_t[] ]

    Maintenant que tu travailles en C++ avec la STL et non pas en pur C avec les API natives (*), il faut que tu lises la documentation pour ne pas te faire avoir : char ou wchar_t? Ouverture binaire ou pas? Interprétation du caractère '\0' (en UTF-16 tu en as pleins) ...


    * -> L'avantage de l'API Windows c'est de gérer les chemins en Unicode
    Je vais prendre ça en compte pour la suite, s'il y a un souci je reposterai. Merci en tout cas

  18. #18
    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 prgasp77 Voir le message
    Ce qui, en fait, ne pose pas de problème puisque printf() fait la même chose. printf() et std::cout sont une interface bufferisée au device "console". De fait, à un moment donné, il faut bien vider le tampon - sinon, rien n'est jamais écrit.

    Prétendre que le vidage du tampon sur std::cout (qui se fait, au final, via un appel système write()) est plus lent que celui de printf() (qui se fait, au final, via un appel système write()) est à peu près aussi pertinent que de se demander quel animal saute plus haut qu'une maison (vue que, dans mon monde au moins, les maisons ne sautent pas).
    [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.

  19. #19
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Bonjour Emmanuel,

    si j'ai inclus un lien en plus de mon approbation, c'était justement pour nuancer mon propos. La totalité de ce qui est balancé sur stdout devra, in fine, être détamponisé () via quelque(s) appel(s) à write(). Mais cette fonction a un coût statique, si bien qu'un bon gros writede deux mile caractères vaut mieux que deux cents writes de dix caractères. Et justement, il me semble que printf() flush à chaque '\n' alors que std::cout laisse à l'utilisateur un peu plus de contrôle là dessus.

Discussions similaires

  1. Réponses: 72
    Dernier message: 07/05/2010, 16h09
  2. XML-Flash - caractères non-latin
    Par heyax dans le forum Flash
    Réponses: 2
    Dernier message: 26/02/2008, 18h12
  3. Problème de caractères non latin dans un formulaire
    Par Huntress dans le forum Langage
    Réponses: 3
    Dernier message: 31/01/2006, 13h34

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