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

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

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.