Afficher les caractères accentués sous Windows en mode console

pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 - 13 déc. 2011 à 08:38
pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 - 14 déc. 2011 à 10:44
Bonjour,
Pour afficher correctement les caractères accentués sous Windows en mode console il faut utiliser le codage ASCII étendu OEM. Pour faire la conversion automatiquement je propose :
/**************** fichier oem.h ****************/
#include <windows.h>
char* ca(const char* s) { // pour convertir en code ASCII OEM
char* c = new char[strlen(s)+1]; // une chaine de caractères
CharToOem(s,c);
return c;
}
std::string sa(const std::string &s) { // pour convertir en code
char* c = new char[s.size()+1]; // ASCII OEM une string
CharToOem(s.c_str(),c);
std::string t = c;
delete [] c;
return c;
}
/**************** fichier main.cpp ****************/
#include
#include <string>
#include "oem.h"
int main () {
char caf[] = "Les caractères français doivent être convertis";
std::string str = "Cet été fut chaud";
std::cout << std::endl << ca("Démo de ca() n° 1 : ") << ca(caf) << std::endl;
std::cout << std::endl << ca("Démo de ca() n° 2 : ") << ca("Noëlle aperçut là-bas l'âne bâté") << std::endl;
std::cout << std::endl << sa("Démo de sa() n° 1 : ") << sa(str) << std::endl;
std::cout << std::endl << "Le texte ci-dessus a : " << sa(str).size() << ca(" caractères") << std::endl;
std::cout << std::endl << sa("Démo de sa() n° 2 : ") << sa("C'est bientôt fini !") << std::endl;
std::cout << std::endl << std::endl << "Au revoir !" << std::endl << std::endl;
getchar();
return 0;
}
Ce problème a déjà été traité, exemple : http://www.cppfrance.com/code.aspx?ID=29633
Mais ici c'est une solution plus spécialisée et plus simple. J'ai toutefois une question :
dans oem.h il y a : char* c = new char[...]; mais il n'y a nulle part un : delete [] c;
s'il en faut un, où le programmer ? Merci.

9 réponses

pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 7
13 déc. 2011 à 09:00
A la fin de sa(){} c'est un : return t; et non pas : return c; Excusez la faute ! Merci.
0
pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 7
13 déc. 2011 à 09:08
Le : char* c = new char[...]; qui n'a pas un : delete [] c; et qui pose le problème c'est celui du ca(){}. En faut-il un ? où ? Merci.
0
cptpingu Messages postés 3835 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 1 novembre 2022 124
13 déc. 2011 à 11:16
Bonjour pgl10.

Et bien, il faut récupérer ce que te renvoie "ca", et te charger toi même de la suppression:
Ex:
// [...]
char* tmp = ca(caf);
std::cout << tmp << std::endl;
delete [] tmp;
// [...]


PS: Pense aux balises de code :)

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 7
13 déc. 2011 à 12:08
Merci CptPingu.

Oui bien sûr. Je comprends bien ta réponse qui est tout à fait correcte. Merci. Mais mon objectif était de remplacer l'exemple suivant où il y a un problème d'accents :

std::cout << std::endl << "Démo de ca() n° 1 : " << caf << std::endl;

par quelquechose de très voisin. Je préfère encore, faute de mieux, faire :

/**************** fichier oem.h ****************/
#include
#include <windows.h>
void ca(const char* s) {
char* c;
c = new char[strlen(s)+1];
CharToOem(s,c);
std::cout << c;
delete [] c;
}
/**************** fichier main.cpp ****************/
#include
#include "oem.h"
int main () {
char caf[] = "Les caractères français doivent être convertis";
std::cout << std::endl; ca("Démo de ca() n° 1 : "); ca(caf); std::cout << std::endl;
std::cout << std::endl; ca("Démo de ca() n° 2 : "); ca("Noëlle aperçut là-bas l'âne bâté"); std::cout << std::endl;
std::cout << std::endl << std::endl << "Au revoir !" << std::endl << std::endl;
getchar();
return 0;
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3835 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 1 novembre 2022 124
13 déc. 2011 à 12:44
Il est possible de garder le même affichage, mais c'est plus compliqué. Une bonne connaissance de la STL interne est nécessaire :p

#include 
#include <sstream>
#include <cstring>

struct SetOEM
{
  SetOEM(const char* s)
    : _oem(s)
  {
  }
  const char* _oem;
};

inline SetOEM
OEM(const char* s)
{
  return SetOEM(s);
}

template <class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& out, SetOEM oem)
{
  char* s;
  s = new char[strlen(oem._oem) + 1];
  strcpy(s, oem._oem); //Remplace par CharToOem(oem, s);
  out << s;
  delete [] s;
  return out;
}

int main ()
{
  char caf[] = "Les caractères français doivent être convertis";
  std::cout << std::endl
            << OEM("Démo de ca() n° 1 : ")
            << OEM(caf)
            << std::endl
            << OEM("Démo de ca() n° 2 : ")
            << OEM("Noëlle aperçut là-bas l'âne bâté")
            << std::endl
            << std::endl << std::endl
            << "Au revoir !" << std::endl
            << std::endl;
  //getchar();
  return 0;
}



________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
cptpingu Messages postés 3835 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 1 novembre 2022 124
13 déc. 2011 à 13:39
Simplifions un petit peu :)

#include 
#include <sstream>
#include <cstring>

struct SetOEM
{
  SetOEM(const char* s)
    : _s(s)
  {
  }
  const char* _s;
};

inline SetOEM
OEM(const char* s)
{
  return s;
}

std::ostream&
operator<<(std::ostream& out, const SetOEM& oem)
{
  char* s = new char[strlen(oem._s) + 1];
  strcpy(s, oem._s); //CharToOem(oem._s, s);
  out << s;
  delete [] s;
  return out;
}

int main ()
{
  char caf[] = "Les caractères français doivent être convertis";
  std::cout << std::endl
            << OEM("Démo de ca() n° 1 : ")
            << OEM(caf)
            << std::endl
            << OEM("Démo de ca() n° 2 : ")
            << OEM("Noëlle aperçut là-bas l'âne bâté")
            << std::endl
            << std::endl << std::endl
            << "Au revoir !" << std::endl
            << std::endl;
  //getchar();
  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 7
13 déc. 2011 à 13:58
CptPingu,

Formidable ! C'est exactement ce que je souhaitais ! Je vais m'efforcer de bien comprendre le fonctionnement cette solution. Je viens de vérifier que cela marche très bien même avec mon vieux Visual C++ 6.0 Alors je dis : bravo et merci. Logiquement, cela vaudrait d'être bien ou mieux connu. Il n'y a plus de fuite mémoire et l'utilisation est bien ce qui est souhaitable. Il y a sûrement beaucoup de visiteurs qui seront heureux de le noter, même si cela ne concerne que les programmeurs sous Windows en mode console. pgl10
0
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 2
14 déc. 2011 à 05:57
Bonjour,

J'évite comme la peste les chaînes accentuées. Mais lorsque je n'ai pas le choix, j'utilise la snippet suivante :

#include 
#include <clocale>

int main (int argc, char* argv[])
{
setlocale( LC_CTYPE , "fra" ) ;
std::cout << "Noëlle aperçut là-bas l'âne bâté"" << std::endl ;
}


Ce code à l'avantage d'être concis et ne dépend pas de "windows.h".
En revanche, sous windows xp, ce code ne fonctionnait pas toujours : il semblait dépendre de la police de caractères affectée à la console. Sous windows 7, ça semble fonctionner correctement.

Qu'en pensez-vous ?

@++
0
pgl10 Messages postés 353 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 8 février 2023 7
14 déc. 2011 à 10:44
Merci Lucky92.
C'est une information complémentaire qui intéressera de nombreux visiteurs. A noter que dans http://www.cppfrance.com/code.aspx?ID=53813 fredg19 a écrit dans jour_naissance.cpp : #include <clocale> ... setlocale(LC_ALL, "french"); pour le même besoin. Mais chez moi chacune de ces deux solutions voisines se compile bien mais ne fonctionne pas. Je suppose que d'autres auraient le même résultat que moi.
0
Rejoignez-nous