Accents sur la Console

Soyez le premier à donner votre avis sur cette source.

Vue 4 143 fois - Téléchargée 410 fois

Description

Bonjour,

Cet article peut être considéré comme un complément du snipet "Afficher des caractères spéciaux(accents, ...)", déposé par capoueidiablo en 2011 (lien ci-dessous).

Les 5 fonctions présentées ici transforment un texte ANSI en OEM pour l'afficher le mieux possible sur la console.

Le tableau unsigned char cod[128] n'est utilisé qu'avec les caractères ANSI de 128 à 255.
const unsigned char Imp='?'; // Impossible
unsigned char cod[128]=
{Imp,Imp,Imp,159,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp
,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp,Imp
,255,173,189,156,207,190,221,245,249,184,166,174,170,240,169,238
,248,241,253,252,239,230,244,250,247,251,167,175,172,171,243,168
,183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216
,209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225
,133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139
,208,164,149,162,147,228,148,246,155,151,163,150,129,236,231,152};
Certains caractères sont impossible à traduire, car ils n'ont pas de représentant en OEM: ils sont remplacés par Imp (ici '?').

Les 5 routines qui suivent utilisent le tableau unsigned char cod[128].
Choisissez celle qui vous convient le mieux.



ToOEM(char txt[])

Le texte txt[] est transformé sur lui-même:
char *ToOEM(char txt[]) { // txt modified
  int n = strlen(txt);
  for (int i = 0; i < n; ++i) if (txt[i]<0) txt[i] = cod[127&txt[i]];
  return txt;
}

// Utilisations:

char txt[]="Raphaël, Éric, Aloïs et Benoît";
printf("%s",txt); // mauvais affichage
printf("%s",ToOEM(txt)); // txt est transformé sur lui-même
Comme txt[] doit être (une) variable, on ne peut pas écrire printf("%s",ToOEM("Interdit")); !



ToOEMfix(const char txt[])

On peut réserver un array de caractères de longueur donné et y copier le texte traduit:
const int MaxLen = 256;
char txtFix[MaxLen+1];
char *ToOEMfix(const char txt[]) {
  int n = strlen(txt);
  if (n > MaxLen) n = MaxLen;
  for (int i = 0; i < n; ++i) txtFix[i] = (txt[i]>=0) ? txt[i] : cod[127&txt[i]];
  txtFix[n] = 0;
  return txtFix;
}

// Utilisation:

printf("%s",ToOEMfix("De Genève à Düsseldorf à vélo"));
Un text trop long sera tronqué à MaxLen.



ToOEMnew(const char txt[])

Une autre possibilté est de copier le texte traduit dans un nouveau texte:
char *ToOEMnew(const char txt[]) { // txt no modified
  int n = strlen(txt);
  char *t = new char[n+1];
  for (int i = 0; i <=n; ++i) t[i] =(txt[i]>=0) ? txt[i] : cod[127&txt[i]];
  return t;
}

// Utilisations:

printf("%s", ToOEMnew("Mémoire non libérée"));

char *lib = ToOEMnew("Mémoire libérée");
printf("%s", lib);
delete lib;



ToOEMcpy(const char txt[])

Utilisons un unique pointeur oem pour faire directement la gestion de la mémoire:
char *oem = 0;
char *ToOEMcpy(const char txt[]) {
  int n = strlen(txt);
  if (oem) delete oem;
  oem=new char[n+1];
  for (int i = 0; i <= n; ++i) oem[i] = (txt[i] >= 0) ? txt[i] : cod[127&txt[i]];
  return oem;
}

// Utilisation:

printf("%s", ToOEMcpy("Hétérogénéité des élèves"));



ToOEMext(const char txt[])

Simplifions la gestion de la mémoire en intervenant seulement lorsqu'on a besoin de l'augmenter:
char *ext = new char[1];
char *ToOEMext(const char txt[]) {
  unsigned int n = strlen(txt);
  if (n >= sizeof(ext)) {delete ext; ext = new char[n+1];}
  for (unsigned int i = 0; i <= n; ++i) ext[i] = (txt[i] >= 0) ? txt[i] : cod[127&txt[i]];
  return ext;
}

// Utilisation:

printf("%s", ToOEMext("De Genève à Düsseldorf à vélo"));


Remarque: Pour les 5 routines, lorsque le texte à afficher ne comporte pas de caractères interprétés par le format (tels que '%', '', ...), on peut simplifier le code d'utilisation. Par exemple:
    printf("%s",ToOEMfix("De Genève à Düsseldorf à vélo"));
peut directement s'écrire:
    printf(ToOEMfix("De Genève à Düsseldorf à vélo"));

Le zip contient le fichier Console.cpp qui génère l'output représenté par l'image de capture.

Voir aussi:
Afficher des caractères spéciaux(accents, ...)
Table des codes ASCII étendus OEM et ANSI


Bonne lecture ...

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
147
Date d'inscription
samedi 1 août 2009
Statut
Membre
Dernière intervention
5 novembre 2019

Bien vu William , en plus le discret setconsoleattribut. Si tu fais de la TI 83-82 je viens de poser un decompileur pour la TI . Y a les chaines STRX que j arrive pas a bien gerer si t ai au courant dis le moi . Voila Bravo encore apres les pi du papi l accent suisse je crois ...
Messages postés
261
Date d'inscription
mardi 12 décembre 2006
Statut
Membre
Dernière intervention
10 juin 2019
>
Messages postés
147
Date d'inscription
samedi 1 août 2009
Statut
Membre
Dernière intervention
5 novembre 2019

Bonjour ccgousset,

Merci le message encourageant.
Non, désolé, je ne connais pas les calculatrices TI-82 ou TI-83 et leur assembleur.

Toutes mes excuses pour cette réponse tardive, mais tout le monde sait que chez nous, il y a pas le feu au lac ...
Messages postés
326
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
5 janvier 2021
2
Bonjour à tous,
Il y aussi une autre solution : employer la fonction CharToOemA() prévue pour cela.
http://codes-sources.commentcamarche.net/source/53868-pour-afficher-les-caracteres-accentues-sous-windows-en-mode-console en montre l'utilisation avec des exemples.
Pouvoir choisir est un avantage.
Messages postés
261
Date d'inscription
mardi 12 décembre 2006
Statut
Membre
Dernière intervention
10 juin 2019
>
Messages postés
326
Date d'inscription
samedi 18 décembre 2004
Statut
Membre
Dernière intervention
5 janvier 2021

Bonjour pgl10,

Merci pour votre message pertinent.

Excusez-moi de ne pas avoir trouvé votre article !
Il me semble pourtant d'avoir bien recherché tous ceux qui contiennent les mots "console" et "accent".

Conclusion: avec l'âge, je deviens nul en "recherche" !

Et mon article devient quasiment caduque.

Le programme suivant montre que CharToOem traduits les caractères non représentables par les "plus ressemblants":
#include <windows.h>
#include <stdio.h>

void main() {
  char s1[]=" !\"#$%&'()*+,-./0123456789:;<=>?"; // 34: \"
  char s2[]="@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; // 92: \\ 
  char s3[]="`abcdefghijklmnopqrstuvwxyz{|}~";   // 127: non représentable
  char s4[]="€ 'f"...+#^0/00S<OE Z  `'""*---~(TM)s>oe zY";       // 129,141,143,144,156: nr
  char s5[]=" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³'µ¶·¸¹º»¼½¾¿";   // 174: non représentable
  char s6[]="ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß";
  char s7[]="àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";

  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);
  char oem[256];
  CharToOem("Caractères traduits par CharToOem:",oem); printf("\n%s\n", oem);
  CharToOem(s1,oem); printf("%i: %s\n",strlen(s1),oem);
  CharToOem(s2,oem); printf("%i: %s\n",strlen(s2),oem);
  CharToOem(s3,oem); printf("%i: %s\n",strlen(s3),oem);
  CharToOem(s4,oem); printf("%i: %s\n",strlen(s4),oem);
  CharToOem(s5,oem); printf("%i: %s\n",strlen(s5),oem);
  CharToOem(s6,oem); printf("%i: %s\n",strlen(s6),oem);
  CharToOem(s7,oem); printf("%i: %s\n",strlen(s7),oem);
  getchar();

/* Output
Caractères traduits par CharToOem:
32:  !"#$%&'()*+,-./0123456789:;<=>?
32: @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
32: `abcdefghijklmnopqrstuvwxyz{|}~?
32: __'f".??^%S<O_Z__''""--~Ts>o_zY
32:  ¡¢£¤¥¦§¨©ª«¬­®¯°±²³'µ¶*¸¹º»¼½¾¿
32: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
32: àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
*/
}

Ce second code, présente une manière toute simple d'utiliser CharToOem().
La méthode du "caractère le plus ressemblant" est le plus souvent satisfaisante, mais peut parfois créer des surprises:
#include <windows.h>
#include <stdio.h>

void main() { //  correspond à peu près à ToOEMfix(...) de l'article
  char oem[256];
  CharToOem("On tolère un taux d'alcoolémie de 0,50/00", oem);
  printf("\n%s",oem);

  getchar();
}
(malheureusement, l'affichage de CodeS-SourceS remplace le caractère "pour mille" (ANSI 137 ou x89) par "0/00"): recorrigez donc le code ci-dessus et le texte ci-dessous.

En effet, le texte:
"On tolère un taux d'alcoolémie de 0,50/00"
est affiché:
"On tolère un taux d'alcoolémie de 0,5%"
ce qui est dix fois plus !


En mettant le tableau de traduction unsigned char cod[128] à disposition, chacun a la possibilité d'y introduire les caractères représentables dont la signification lui semble correcte.

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.