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

Signaler
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
-
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
-
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

Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
2
A la fin de sa(){} c'est un : return t; et non pas : return c; Excusez la faute ! Merci.
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
2
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.
Messages postés
3813
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
12 juin 2020
107
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
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
2
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;
}
Messages postés
3813
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
12 juin 2020
107
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
Messages postés
3813
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
12 juin 2020
107
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
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
2
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
Messages postés
180
Date d'inscription
mercredi 22 décembre 2004
Statut
Membre
Dernière intervention
16 août 2012
2
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 ?

@++
Messages postés
314
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
12 juin 2020
2
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.