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

Windows Discussion :

Accents dans une console windows [Sources]


Sujet :

Windows

  1. #1
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut Accents dans une console windows
    J'ai un post qui n'est pas à 100% du C++, mais qui est je pense utile pour des débutants en C++ sous windows (mais la faq windows n'a pas l'air orientée programmation).

    Un des problèmes de programmes console est les accents. En effet, pour de sombres histoires d'encodage différent sous windows et en mode console, du code aussi simple que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << "Bonjour à tous !" << endl;
    Ne donnera pas à l'écran le résultat escompté.

    J'ai fait un petit programme qui corrige ça. Un exemple d'utilisation :
    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
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include "WinConsoleStreamBuf.h"
    
    using namespace std;
    
    int main&#40;&#41;
    &#123;
    	cout << "Test &#58; éàùçï" << endl; // Pas bon
    	&#123;
    		loic&#58;&#58;AccentsInMsWindowsConsoleHandler toto;
    		cout << "Test &#58; éàùçï" << endl; // Bon
    		cout << "Bonjour à toi, quel est ton nom ? "; // Bon
    		string nom;
    		cin >> nom; // Bon
    		cout << "\nBonjour, " << nom << " !" << endl; // Bon
    	&#125;
    	cout << "Test &#58; éàùçï" << endl; // Pas bon
    	cin.ignore&#40;&#41;;
    &#125;
    Voici les fichiers nécessaires si ça intéresse quelqu'un (code placé dans le domaine public, testé avec Visual C++, mais qui devrait marcher avec Borland ou autre...) :

    WinConsoleStreamBuf.h
    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
    #include <streambuf>
    #include <ostream>
    
    #ifndef _WIN32
    	#error This file is only designed &#40;and useful&#41; on MsWindows
    #endif
    
    namespace loic
    &#123;
    
    class WinConsoleStreamBuf&#58; public std&#58;&#58;streambuf
    &#123;
    public&#58;
    	explicit WinConsoleStreamBuf&#40;std&#58;&#58;streambuf *buf&#41;;
    	~WinConsoleStreamBuf&#40;&#41;;
    	std&#58;&#58;streambuf *setUnderlyingBuffer&#40;std&#58;&#58;streambuf *newBuf&#41;;
    
    private&#58;
    	WinConsoleStreamBuf&#40;WinConsoleStreamBuf &&#41;;
    	WinConsoleStreamBuf& operator=&#40;WinConsoleStreamBuf&&#41;;
    	virtual std&#58;&#58;streambuf* setbuf&#40;char_type* s, std&#58;&#58;streamsize n&#41;;
    
    	virtual int_type overflow&#40;int_type c&#41;;
    	virtual int      sync&#40;&#41;;
        virtual int_type underflow&#40;&#41;;
    
    
    	std&#58;&#58;streambuf *myBuf;
    	char myInputBuffer&#91;2&#93;;
    &#125;;
    
    /**
     * This class is aimed to be used following the RAII idiom
     */
    
    struct AccentsInMsWindowsConsoleHandler
    &#123;
    	AccentsInMsWindowsConsoleHandler&#40;&#41;;
    	~AccentsInMsWindowsConsoleHandler&#40;&#41;;
    &#125;;
    &#125; // namespace loic
    Et WinConsoleStreamBuf.cpp
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    #include "WinConsoleStreamBuf.h"
    #include <iostream>
    #include <ios>
    #include <windows.h>
    
    namespace loic
    &#123;
    
    WinConsoleStreamBuf&#58;&#58;WinConsoleStreamBuf&#40;std&#58;&#58;streambuf *buf&#41;&#58;
    	myBuf&#40;buf&#41;
    &#123;
    &#125;
    
    WinConsoleStreamBuf&#58;&#58;~WinConsoleStreamBuf&#40;&#41;
    &#123;
    	delete myBuf;
    &#125;
    
    std&#58;&#58;streambuf* WinConsoleStreamBuf&#58;&#58;setbuf&#40;char_type* s, std&#58;&#58;streamsize n&#41;
    &#123;
    	// ne fait rien, ce qui est autorisé.  Une version plus complète
    	// devrait vraissemblablement utiliser setvbuf
    	return NULL;
    &#125;
    
    WinConsoleStreamBuf&#58;&#58;int_type WinConsoleStreamBuf&#58;&#58;overflow&#40;int_type c&#41;
    &#123;
    	if &#40;traits_type&#58;&#58;eq_int_type&#40;c, traits_type&#58;&#58;eof&#40;&#41;&#41;&#41; 
    	&#123;
    		// la norme ne le demande pas exactement, mais si on nous passe eof
    		// la coutume est de faire la meme chose que sync&#40;&#41;
    		return &#40;sync&#40;&#41; == 0
    			? traits_type&#58;&#58;not_eof&#40;c&#41;
    			&#58; traits_type&#58;&#58;eof&#40;&#41;&#41;;
    	&#125;
    	else 
    	&#123;
    		char charBuffer&#91;2&#93;;
    		charBuffer&#91;0&#93; = static_cast<char>&#40;c&#41;;
    		charBuffer&#91;1&#93; = 0;
    		char OEMBuffer&#91;2&#93;;
    		CharToOem&#40;charBuffer, OEMBuffer&#41;;
    		//std&#58;&#58;cout << OEMBuffer;
    		myBuf->sputc&#40;OEMBuffer&#91;0&#93;&#41;;
    		return true;
    	&#125;
    &#125;
    
    WinConsoleStreamBuf&#58;&#58;int_type WinConsoleStreamBuf&#58;&#58;underflow&#40;&#41;
    &#123;
    	// Assurance contre des implementations pas strictement conformes à la
    	// norme qui guaranti que le test est vrai.  Cette guarantie n'existait
    	// pas dans les IOStream classiques.
    	if &#40;gptr&#40;&#41; == NULL || gptr&#40;&#41; >= egptr&#40;&#41;&#41; 
    	&#123;
    		int gotted = myBuf->sbumpc&#40;&#41;;
    		if &#40;gotted == EOF&#41; 
    		&#123;
    			return traits_type&#58;&#58;eof&#40;&#41;;
    		&#125;
    		else
    		&#123;
    			char OEMBuffer&#91;2&#93;;
    			OEMBuffer&#91;0&#93; = static_cast<char>&#40;gotted&#41;;
    			OEMBuffer&#91;1&#93; = 0;
    			OemToChar&#40;OEMBuffer, myInputBuffer&#41;;
    			setg&#40;myInputBuffer, myInputBuffer, myInputBuffer+1&#41;;
    			return traits_type&#58;&#58;to_int_type&#40;*myInputBuffer&#41;;
    		&#125;
    	&#125; 
    	else
    	&#123;
    		return traits_type&#58;&#58;to_int_type&#40;*myInputBuffer&#41;;
    	&#125;
    &#125;
    
    
    int WinConsoleStreamBuf&#58;&#58;sync&#40;&#41;
    &#123;
    	return myBuf->pubsync&#40;&#41;;
    &#125;
    
    std&#58;&#58;streambuf* WinConsoleStreamBuf&#58;&#58;setUnderlyingBuffer&#40;std&#58;&#58;streambuf* newBuf&#41;
    &#123;
    	std&#58;&#58;swap&#40;newBuf, myBuf&#41;;
    	return newBuf;
    &#125;
    
    
    AccentsInMsWindowsConsoleHandler&#58;&#58;AccentsInMsWindowsConsoleHandler&#40;&#41;
    &#123;
    	std&#58;&#58;cout.rdbuf&#40;new WinConsoleStreamBuf&#40;std&#58;&#58;cout.rdbuf&#40;&#41;&#41;&#41;;
    	std&#58;&#58;cin.rdbuf&#40;new WinConsoleStreamBuf&#40;std&#58;&#58;cin.rdbuf&#40;&#41;&#41;&#41;;
    &#125;
    
    namespace
    &#123;
    void restoreDefaultBuffer&#40;std&#58;&#58;basic_ios<char> &s&#41;
    &#123;
    	WinConsoleStreamBuf *oldBuf = dynamic_cast<WinConsoleStreamBuf*>&#40;s.rdbuf&#40;&#41;&#41;;
    	if &#40;oldBuf&#41;
    	&#123;
    		s.rdbuf&#40;oldBuf->setUnderlyingBuffer&#40;NULL&#41;&#41;;
    		delete oldBuf;
    	&#125;
    &#125;
    &#125;
    
    AccentsInMsWindowsConsoleHandler&#58;&#58;~AccentsInMsWindowsConsoleHandler&#40;&#41;
    &#123;
    	restoreDefaultBuffer&#40;std&#58;&#58;cout&#41;;
    	restoreDefaultBuffer&#40;std&#58;&#58;cin&#41;;
    &#125;
    
    &#125; // namespace loic
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  2. #2
    HRS
    HRS est déconnecté
    Membre confirmé
    Avatar de HRS
    Inscrit en
    Mars 2002
    Messages
    677
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 677
    Points : 638
    Points
    638
    Par défaut
    n'oubliez pas qu'il existe une API Windows qui fait cela : CharToOem()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    #include <windows.h>
    using namespace std;
    char dst&#91;80&#93;, src&#91;&#93; = "à bientôt pépé";
    int main &#40;&#41; &#123;
        CharToOem &#40;src,dst&#41;;
          cout << dst << endl;
          cin.ignore&#40;&#41;;
          return 0;	
    &#125;

  3. #3
    Membre à l'essai
    Inscrit en
    Septembre 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 18
    Points : 18
    Points
    18
    Par défaut Re: Accents dans une console windows
    Citation Envoyé par JolyLoic
    J'ai un post qui n'est pas à 100% du C++, mais qui est je pense utile pour des débutants en C++ sous windows (mais la faq windows n'a pas l'air orientée programmation).

    Un des problèmes de programmes console est les accents. En effet, pour de sombres histoires d'encodage différent sous windows et en mode console, du code aussi simple que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << "Bonjour à tous !" << endl;
    Ne donnera pas à l'écran le résultat escompté.
    Pourquoi ne pas utiliser CHCP dans la console ? J'ai oublié le nombre à 3 chiffres qui définit le code page latin. Je regarde ça ce soir.

  4. #4
    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
    Par défaut
    Parce que ça marche pas :-)
    http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx
    Only the original equipment manufacturer (OEM) code page installed with Windows XP appears correctly in a command prompt window that uses Raster fonts. Other code pages appear correctly in full-screen mode or command prompt windows that use TrueType fonts
    En fait il faut en plus changer la font pour Lucida console dans les propriétés de la console. Et je crois que chcp c'est WinXP only. Mais on peut faire la même chose depuis le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetConsoleOutputCP&#40; 1252 &#41;;
    Je sais pas comment changer la font de la console depuis le code, je pense que c'est un peu de bidouille et non documenté.
    La solution Win32 c'est d'utiliser UNICODE et WriteConsole. Là ça marche direct.

  5. #5
    Membre à l'essai
    Inscrit en
    Septembre 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Si, cela marche ! Je l'utilise parfois ! J'ai effectivement oublié de préciser que le mode opératoire est un peu tortueux, et qu'il faut modifier la fonte dans les settings de la console.

    Autre chose : je ne l'ai jamais testé sur WinXP. Seulement Windows 2000 et NT. Ceci dit, cela doit bien se passer aussi.

  6. #6
    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
    Par défaut
    Oui, c'est une opération nécessaire au fonctionnement, mais insuffisante. J'aurais dû dire "Ca ne suffit pas"
    Le truc c'est que le + important c'est la font, vu que le chcp on peut le faire depuis le code.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    windows-1252 n'est pas latin1 (ISO-8859-1)
    Sinon, le plus simple est tout simplement d'écrire ton source directement en CP850.
    Boost ftw

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Je sais pas comment changer la font de la console depuis le code, je pense que c'est un peu de bidouille et non documenté.
    La seule chose que j'ai vu, c'est comment interroger la fonte courant, mais rien pour la modifier. Je ne sais pas trop pourquoi rien n'est publié pour ça.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    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
    Par défaut
    Après recherche kernel32 exporte une fonction SetConsoleFont depuis pas mal de temps, peut être depuis Win95.
    http://www.geocities.com/jadoxa/misc/cs.c.txt

Discussions similaires

  1. Afficher les accent dans une console
    Par arnaud036 dans le forum C
    Réponses: 11
    Dernier message: 18/01/2008, 12h43
  2. Réponses: 5
    Dernier message: 07/06/2006, 12h11
  3. Réponses: 21
    Dernier message: 07/05/2006, 17h27
  4. Ne pas tenir compte des accents dans une requete
    Par zamanika dans le forum Installation
    Réponses: 8
    Dernier message: 08/11/2004, 19h49
  5. [VB.NET] Tabulation dans une console
    Par jacma dans le forum Windows Forms
    Réponses: 5
    Dernier message: 30/09/2004, 09h50

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