Pour afficher les caractères accentués sous windows en mode console

Soyez le premier à donner votre avis sur cette source.

Vue 10 911 fois - Téléchargée 945 fois

Description

Le code ASCII de base a été mis au point pour la langue anglaise, il ne contient donc pas de caractères accentués, ni de caractères spécifiques à une langue. Il a été ensuite étendu pour apporter des solutions à ce besoin. Deux codages particuliers ont été ainsi définis : le code ASCII étendu OEM, défini aux débuts des PC IBM, c'est celui qui est encore utilisé pour les affichages en mode console sous Windows, et le code ASCII étendu ANSI utilisé par les autres systèmes d'exploitation. C'est pourquoi il est très utile de pouvoir afficher correctement des mots ayant des caractères accentués de manière très voisine et avec très peu de changement en passant d'une environnement à l'autre. C'est ce que s'efforce de faire la solution ci-jointe construite grâce à plusieurs échanges avec CptPingu. L'explication est la suivante. En C++, il n'est pas possible de redéfinir l'opérateur << pour un type pod (plain old data, type classique comme int, double, char, etc.). L'opérateur << pour les std::string existant déjà, il y aurait eu ambiguïté. La solution consiste en une astuce simple : on définit une classe d'encapsulation pour les std::string, ce qui permet d'avoir un nouveau type. La surcharge n'existant pas pour ce type, on peut donc redéfinir l'opérateur << pour ce type équivalent au std::string. Et comme le std::string convertit le char*/char[] reçu en entrant cela fonctionne aussi pour le type char*/char[]. Merci CptPingu.

Source / Exemple :


//------------------------   fichier oem.hpp   ---------------------------
#ifndef OEM_HPP
#define OEM_HPP
#include <windows.h>
   
struct SetOEM 
{ 
explicit SetOEM(const std::string& s) 
    : _s(s) 
  { 
  } 
  const std::string _s; 
}; 
    
inline SetOEM 
OEM(const std::string& s) 
{ 
  return s; 
} 
    
std::ostream& 
operator<<(std::ostream& out, const SetOEM& oem) 
{ 
  char* s = new char[oem._s.size() + 1]; 
  CharToOemA(oem._s.c_str(), s); 
  out << s; 
  delete [] s; 
  return out; 
} 
   
#endif // OEM_HPP
//------------------------   fichier main.cpp   --------------------------
#include <iostream>
#include <string>
#include "oem.hpp"
int main()
{ 
  const char caf[] = "Les caractères français doivent être convertis"; 
  const std::string str = "Noëlle aperçut là-bas l'âne bâté"; 
  std::cout << std::endl; 
  std::cout << OEM("Démo de OEM() n° 1 : ") << OEM(caf) << std::endl << std::endl 
            << OEM("Démo de OEM() n° 2 : ") << OEM("Cet été fut très chaud !") << std::endl << std::endl 
            << "Mais sans OEM()    : " << "Cet été fut très chaud !" << std::endl << std::endl 
            << OEM("Démo de OEM() n° 3 : ") << OEM(str) << std::endl  << std::endl 
            << "Mais sans OEM()    : " << str << std::endl << std::endl 
            << std::endl << "Au revoir !" << std::endl << std::endl; 
  getchar(); 
  return 0; 
}

Conclusion :


Comme le montre le main() on peut afficher en C++ sous Windows en mode console avec l'ASCII étendu OEM des mots ayant des caractères accentués d'une manière très voisine de ce qui serait fait si ce mode utilisait l'ASCII étendu ANSI. Et de cette manière la portabilité éventuelle dans un autre environnement est extrêmement facile à effectuer. On peut aussi noter que par rapport à la solution utilisant setlocale on a ici la possibilité de mélanger les caractères spéciaux de plusieurs langues et de plus c'est compatible avec les compilateurs et systèmes anciens.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
326
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
5 janvier 2021
2
Renfield et FraGag,
Merci beaucoup d'avoir indiqué comment on peut éviter le problème ou comment le traiter autrement. Il y a probablement encore d'autres solutions ( Unicode ... ). Et celle-ci peut admettre des variantes. A chacun de faire son choix.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
67
vues les manipulations requises, ca tend a me rassurer dans mes choix: ne pas mettre d'accent dans mes consoles ^^
Messages postés
6
Date d'inscription
vendredi 8 juin 2012
Statut
Membre
Dernière intervention
8 juin 2012

Cette réponse me satisfait, en effet, mieux que la précédente. J'en avais conçu le principe, mais, devant la première réponse, j'avais craint d’être importun.
Avec ce nouveau code, le résultat devient vraiment parfait.
Messages postés
326
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
5 janvier 2021
2
Jojo Lancien,
Je reprends ici ma réponse faite trop rapidement.
C'est tout à fait exact, si on fait ici : main.exe > texte.txt
On obtient un fichier texte.txt inutilisable.
Mais on peut le corriger facilement avec un montrer.bat : montrer.exe texte.txt console.txt
et le fichier simplifié montrer.cpp suivant :
#include 
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[]) {
ifstream ifs(argv[1]);
ofstream ofs(argv[2]);
string s;
while (getline(ifs, s)) {
char* buf;
buf = new char[s.size()+1];
OemToChar(s.c_str(), buf);
s = buf;
delete [] buf;
ofs << s << endl;
}
return 0;
}

Le fichier console.txt obtenu est conforme à l'affichage ayant été envoyé dans texte.txt
Merci d'avoir indiqué un complément pouvant être utile à certains besoins.
Messages postés
326
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
5 janvier 2021
2
Merci Jojo Lancien. L'objectif ici est seulement d'avoir facilement un affichage correct en mode console sous Windows. Convertir les lignes d'un fichier texte.txt serait assez facile. Mais dans quel but ? A quoi servirait le fichier converti ? Le programme Convhtml à : http://www.cppfrance.com/code.aspx?ID=53789 effectue un autre type de conversion pour tous les fichiers .htm ou .html d'un dossier. On pourrait l'adapter facilement avec ou sans appel à CharToOemA().
Afficher les 10 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.