Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce
sont des caractères étranges qui s'affichent.
J'ai réussi à afficher les caractères corrects, d'abord en appelant
SetConsoleOutputCP(1252), puis en changeant à la main la police utilisé
pour la console de "Police Raster" vers "Lucida Condole". Par contre, je
n'ai pas réussi à faire sélectionner cette police par programme.
Quelqu'un sait-il comment faire ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
jean dupont
----- Original Message ----- From: "Loïc Joly" Newsgroups: fr.comp.os.ms-windows.programmation Sent: Sunday, October 17, 2004 3:11 PM Subject: Affichage de caracères étendus dans la console.
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce sont des caractères étranges qui s'affichent.
J'ai réussi à afficher les caractères corrects, d'abord en appelant SetConsoleOutputCP(1252), puis en changeant à la main la police utilisé pour la console de "Police Raster" vers "Lucida Condole". Par contre, je n'ai pas réussi à faire sélectionner cette police par programme. Quelqu'un sait-il comment faire ?
Ou alors quelqu'un a-t-il une autre solution ?
-- Loïc
Les éditeurs de type GUI n'utilisent pas le même jeu de caractères (code ANSI ) que les applications en mode console(code OEM). Il y a deux façons de résoudre le problème soit on utilise un éditeur capable d'écrire en mode OEM pour écrire le fichier source (par exemple avec wordpad enregistrer en mode texte MS-DOS), soit on utilise la fonction CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
----- Original Message -----
From: "Loïc Joly" <loic.actarus.joly@wanadoo.fr>
Newsgroups: fr.comp.os.ms-windows.programmation
Sent: Sunday, October 17, 2004 3:11 PM
Subject: Affichage de caracères étendus dans la console.
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce
sont des caractères étranges qui s'affichent.
J'ai réussi à afficher les caractères corrects, d'abord en appelant
SetConsoleOutputCP(1252), puis en changeant à la main la police utilisé
pour la console de "Police Raster" vers "Lucida Condole". Par contre, je
n'ai pas réussi à faire sélectionner cette police par programme.
Quelqu'un sait-il comment faire ?
Ou alors quelqu'un a-t-il une autre solution ?
--
Loïc
Les éditeurs de type GUI n'utilisent pas le même jeu de caractères (code
ANSI ) que les applications en mode console(code OEM).
Il y a deux façons de résoudre le problème soit on utilise un éditeur
capable
d'écrire en mode OEM pour écrire le fichier source (par exemple avec wordpad
enregistrer en mode texte MS-DOS), soit on utilise la fonction
CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
----- Original Message ----- From: "Loïc Joly" Newsgroups: fr.comp.os.ms-windows.programmation Sent: Sunday, October 17, 2004 3:11 PM Subject: Affichage de caracères étendus dans la console.
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce sont des caractères étranges qui s'affichent.
J'ai réussi à afficher les caractères corrects, d'abord en appelant SetConsoleOutputCP(1252), puis en changeant à la main la police utilisé pour la console de "Police Raster" vers "Lucida Condole". Par contre, je n'ai pas réussi à faire sélectionner cette police par programme. Quelqu'un sait-il comment faire ?
Ou alors quelqu'un a-t-il une autre solution ?
-- Loïc
Les éditeurs de type GUI n'utilisent pas le même jeu de caractères (code ANSI ) que les applications en mode console(code OEM). Il y a deux façons de résoudre le problème soit on utilise un éditeur capable d'écrire en mode OEM pour écrire le fichier source (par exemple avec wordpad enregistrer en mode texte MS-DOS), soit on utilise la fonction CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
Loïc Joly
jean dupont wrote:
From: "Loïc Joly"
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce sont des caractères étranges qui s'affichent.
[...]
on utilise la fonction CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
std::streambuf* WinConsoleStreamBuf::setbuf(char_type* s, std::streamsize n) { // ne fait rien, ce qui est autorisé. Une version plus complète // devrait vraissemblablement utiliser setvbuf return NULL; }
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::overflow(int_type c) { if (traits_type::eq_int_type(c, traits_type::eof())) { // la norme ne le demande pas exactement, mais si on nous passe eof // la coutume est de faire la meme chose que sync() return (sync() == 0 ? traits_type::not_eof(c) : traits_type::eof()); } else { char charBuffer[2]; charBuffer[0] = static_cast<char>(c); charBuffer[1] = 0; char OEMBuffer[2]; CharToOem(charBuffer, OEMBuffer); //std::cout << OEMBuffer; myBuf->sputc(OEMBuffer[0]); return true; } }
int WinConsoleStreamBuf::sync() { return myBuf->pubsync(); }
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce
sont des caractères étranges qui s'affichent.
[...]
on utilise la fonction
CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai
finalement décidé de partir dans cette direction, mais en créant ma
propre classe qui fait ça tout seul. Je donne ici le code si certains en
veulent.
std::streambuf* WinConsoleStreamBuf::setbuf(char_type* s, std::streamsize n)
{
// ne fait rien, ce qui est autorisé. Une version plus complète
// devrait vraissemblablement utiliser setvbuf
return NULL;
}
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::overflow(int_type c)
{
if (traits_type::eq_int_type(c, traits_type::eof()))
{
// la norme ne le demande pas exactement, mais si on nous passe eof
// la coutume est de faire la meme chose que sync()
return (sync() == 0
? traits_type::not_eof(c)
: traits_type::eof());
}
else
{
char charBuffer[2];
charBuffer[0] = static_cast<char>(c);
charBuffer[1] = 0;
char OEMBuffer[2];
CharToOem(charBuffer, OEMBuffer);
//std::cout << OEMBuffer;
myBuf->sputc(OEMBuffer[0]);
return true;
}
}
int WinConsoleStreamBuf::sync()
{
return myBuf->pubsync();
}
Quand je fais dans mon code un cout<< "éùàç" << endl; par défaut, ce sont des caractères étranges qui s'affichent.
[...]
on utilise la fonction CharToOem(chaine_ansi,chaine_oem) et ensuite cout<<chaine_oem
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
std::streambuf* WinConsoleStreamBuf::setbuf(char_type* s, std::streamsize n) { // ne fait rien, ce qui est autorisé. Une version plus complète // devrait vraissemblablement utiliser setvbuf return NULL; }
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::overflow(int_type c) { if (traits_type::eq_int_type(c, traits_type::eof())) { // la norme ne le demande pas exactement, mais si on nous passe eof // la coutume est de faire la meme chose que sync() return (sync() == 0 ? traits_type::not_eof(c) : traits_type::eof()); } else { char charBuffer[2]; charBuffer[0] = static_cast<char>(c); charBuffer[1] = 0; char OEMBuffer[2]; CharToOem(charBuffer, OEMBuffer); //std::cout << OEMBuffer; myBuf->sputc(OEMBuffer[0]); return true; } }
int WinConsoleStreamBuf::sync() { return myBuf->pubsync(); }
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet qui s'occuperait de tout cela.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à savoir.
Loïc Joly <loic.actarus.joly@wanadoo.fr> wrote in
news:4174166a$0$31756$8fcfb975@news.wanadoo.fr:
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai
finalement décidé de partir dans cette direction, mais en créant ma
propre classe qui fait ça tout seul. Je donne ici le code si certains
en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet
qui s'occuperait de tout cela.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir
signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à
savoir.
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet qui s'occuperait de tout cela.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à savoir.
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet qui s'occuperait de tout cela.
Tiens, je n'ai pas regardé de ce côté.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à savoir.
En fait, je me suis rendu compte après que j'avais oublié la partie cin. Pour que ça marche, il faut aussi changer le buffer de cin, et ajouter une fonction underflow :
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::underflow() { // 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 (gptr() == NULL || gptr() >= egptr()) { int gotted = myBuf->sbumpc(); if (gotted == EOF) { return traits_type::eof(); } else { char OEMBuffer[2]; OEMBuffer[0] = static_cast<char>(gotted); OEMBuffer[1] = 0; OemToChar(OEMBuffer, myInputBuffer); setg(myInputBuffer, myInputBuffer, myInputBuffer+1); return traits_type::to_int_type(*myInputBuffer); } } else { return traits_type::to_int_type(*myInputBuffer); } }
-- Loïc
Luc Hermitte wrote:
Loïc Joly <loic.actarus.joly@wanadoo.fr> wrote in
news:4174166a$0$31756$8fcfb975@news.wanadoo.fr:
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai
finalement décidé de partir dans cette direction, mais en créant ma
propre classe qui fait ça tout seul. Je donne ici le code si certains
en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet
qui s'occuperait de tout cela.
Tiens, je n'ai pas regardé de ce côté.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir
signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à
savoir.
En fait, je me suis rendu compte après que j'avais oublié la partie cin.
Pour que ça marche, il faut aussi changer le buffer de cin, et ajouter
une fonction underflow :
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::underflow()
{
// 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 (gptr() == NULL || gptr() >= egptr())
{
int gotted = myBuf->sbumpc();
if (gotted == EOF)
{
return traits_type::eof();
}
else
{
char OEMBuffer[2];
OEMBuffer[0] = static_cast<char>(gotted);
OEMBuffer[1] = 0;
OemToChar(OEMBuffer, myInputBuffer);
setg(myInputBuffer, myInputBuffer, myInputBuffer+1);
return traits_type::to_int_type(*myInputBuffer);
}
}
else
{
return traits_type::to_int_type(*myInputBuffer);
}
}
Effectivement, mais ça me semblait assez lourd d'utilisation. J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip buffer filtrant]
Normalement, il faudrait plutôt imbuer cin et cout avec la code_cvt facet qui s'occuperait de tout cela.
Tiens, je n'ai pas regardé de ce côté.
Il y a pas mal de temps, j'avais posté une telle solution ici (voir signature), mais elle était imparfaite pour la partie lecture sous VC 6.
L'approche par buffer filtrant semble résoudre tout cela. C'est bon à savoir.
En fait, je me suis rendu compte après que j'avais oublié la partie cin. Pour que ça marche, il faut aussi changer le buffer de cin, et ajouter une fonction underflow :
WinConsoleStreamBuf::int_type WinConsoleStreamBuf::underflow() { // 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 (gptr() == NULL || gptr() >= egptr()) { int gotted = myBuf->sbumpc(); if (gotted == EOF) { return traits_type::eof(); } else { char OEMBuffer[2]; OEMBuffer[0] = static_cast<char>(gotted); OEMBuffer[1] = 0; OemToChar(OEMBuffer, myInputBuffer); setg(myInputBuffer, myInputBuffer, myInputBuffer+1); return traits_type::to_int_type(*myInputBuffer); } } else { return traits_type::to_int_type(*myInputBuffer); } }
-- Loïc
Aurélien REGAT-BARREL
> J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip]
class WinConsoleStreamBuf: public std::streambuf
J'avais tenté un truc du genre, mais en dérivant filebuf et en l'ouvrant sur CONOUT$. Ca marche pas pour des caractères simples (peut être que overflow en est la cause, je sais pas j'ai pas le niveau en C++ surtout pour les flux) et c'est pas tout à fait correct dans la mesure où si cout a été redirigé vers un fichier par exemple ça n'en tient pas compte à cause de CONOUT$ qui vaut toujours la sortie console. Peut être qu'il y a un moyen d'ouvrir un filebuf sur un HANDLE ?
#include <fstream> #include <iostream>
#define WIN32_LEAN_AND_MEAN #include <windows.h>
template<class Elem, class Traits> class oem_filebuf : public std::basic_filebuf<Elem, Traits> { protected: virtual std::streamsize xsputn(const Elem *Ptr, std::streamsize Count) { char * buff = new char[ Count + 1 ]; // copier avec le ' ' ::lstrcpy( buff, Ptr ); ::CharToOem( buff, buff ); std::streamsize count std::basic_filebuf<Elem, Traits>::xsputn( buff, Count ); delete [] buff; return count; } };
// object static utilisé pour modifier cout struct InitOemCout { // code de modif dans le constructeur InitOemCout() { // CONOUT$ = sortie console this->oem.open( "CONOUT$", std::ios_base::out ); std::cout.rdbuf( &oem ); } oem_filebuf<char, std::char_traits<char> > oem; };
static InitOemCout init_oem_cout;
int main() { std::cout << "ça màrche héhé!n"; std::cout << 'è' << 'n'; // marche pas :-( }
-- Aurélien REGAT-BARREL
> J'ai finalement décidé de partir dans cette direction, mais en créant ma
propre classe qui fait ça tout seul. Je donne ici le code si certains en
veulent.
[snip]
class WinConsoleStreamBuf: public std::streambuf
J'avais tenté un truc du genre, mais en dérivant filebuf et en l'ouvrant sur
CONOUT$. Ca marche pas pour des caractères simples (peut être que overflow
en est la cause, je sais pas j'ai pas le niveau en C++ surtout pour les
flux) et c'est pas tout à fait correct dans la mesure où si cout a été
redirigé vers un fichier par exemple ça n'en tient pas compte à cause de
CONOUT$ qui vaut toujours la sortie console. Peut être qu'il y a un moyen
d'ouvrir un filebuf sur un HANDLE ?
#include <fstream>
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
template<class Elem, class Traits>
class oem_filebuf :
public std::basic_filebuf<Elem, Traits>
{
protected:
virtual std::streamsize xsputn(const Elem *Ptr, std::streamsize Count)
{
char * buff = new char[ Count + 1 ];
// copier avec le ' '
::lstrcpy( buff, Ptr );
::CharToOem( buff, buff );
std::streamsize count std::basic_filebuf<Elem, Traits>::xsputn( buff, Count );
delete [] buff;
return count;
}
};
// object static utilisé pour modifier cout
struct InitOemCout
{
// code de modif dans le constructeur
InitOemCout()
{
// CONOUT$ = sortie console
this->oem.open( "CONOUT$", std::ios_base::out );
std::cout.rdbuf( &oem );
}
oem_filebuf<char, std::char_traits<char> > oem;
};
static InitOemCout init_oem_cout;
int main()
{
std::cout << "ça màrche héhé!n";
std::cout << 'è' << 'n'; // marche pas :-(
}
> J'ai finalement décidé de partir dans cette direction, mais en créant ma propre classe qui fait ça tout seul. Je donne ici le code si certains en veulent.
[snip]
class WinConsoleStreamBuf: public std::streambuf
J'avais tenté un truc du genre, mais en dérivant filebuf et en l'ouvrant sur CONOUT$. Ca marche pas pour des caractères simples (peut être que overflow en est la cause, je sais pas j'ai pas le niveau en C++ surtout pour les flux) et c'est pas tout à fait correct dans la mesure où si cout a été redirigé vers un fichier par exemple ça n'en tient pas compte à cause de CONOUT$ qui vaut toujours la sortie console. Peut être qu'il y a un moyen d'ouvrir un filebuf sur un HANDLE ?
#include <fstream> #include <iostream>
#define WIN32_LEAN_AND_MEAN #include <windows.h>
template<class Elem, class Traits> class oem_filebuf : public std::basic_filebuf<Elem, Traits> { protected: virtual std::streamsize xsputn(const Elem *Ptr, std::streamsize Count) { char * buff = new char[ Count + 1 ]; // copier avec le ' ' ::lstrcpy( buff, Ptr ); ::CharToOem( buff, buff ); std::streamsize count std::basic_filebuf<Elem, Traits>::xsputn( buff, Count ); delete [] buff; return count; } };
// object static utilisé pour modifier cout struct InitOemCout { // code de modif dans le constructeur InitOemCout() { // CONOUT$ = sortie console this->oem.open( "CONOUT$", std::ios_base::out ); std::cout.rdbuf( &oem ); } oem_filebuf<char, std::char_traits<char> > oem; };
static InitOemCout init_oem_cout;
int main() { std::cout << "ça màrche héhé!n"; std::cout << 'è' << 'n'; // marche pas :-( }