Ce fichier d'entête tente de résoudre le problème que posent les polices différentes utilisées par DOS (mode console, fichiers ascii) et par Windows (environnement Dev-cpp, bloc-notes...) - IL est destiné en premier lieu à une utilisation sous
Dev-cpp en mode console mais devrait pouvoir être utilisé dans tout autre environnement.
Ce fichier propose :
- la liste et le code des caractères étendus (>127) pour console DOS
- la liste et le code des caractères étendus (>127) pour Window
- une fonction polymorphe transcode ayant 2 paramètres et qui traduit les codes > 127 à l'aide d'un tableau
- une fonction polymorphe transcode à 3 paramètres qui traduit tout caractère apparaissant dans une chaîne
patron (param n°2) en son homologue dans un chaîne lexique (param n°3).
- quatre fonctions polymorphes de traduction DOS <--> Windows et en code ascii 7 bits standard (désaccentuation,
supression des caractères semi graphiques...) sous forme de macros.
= w2d (Windows to DOS) traduit les caractères Windows en caractères DOS
= d2w (DOS to Windows) traduit les caractères DOS en caractères Windows (w2d~¹)
= w2a (Window to Ascii 7bits) suppression des accents, cédilles... en partant de Windows
= d2a (DOS to Ascii 7 bits) suppression des accents, cédilles... partant de DOS
- une fonction transcode à 4 paramètres (st, model, pattern,translation) qui copie en la traduisant la chaîne model
dans la chaîne st en utilisant la chaîne pattern comme patron et la chaîne translation comme lexique.
-------------------------------------
Un petit programme permet d'illustrer l'utilisation
-------------------------------------
Source / Exemple :
//******************************************************************************
// ENTETE : transcode.hpp
// DATE : 11/02/05
// OBJET : Résoudre le problème que posent les polices différentes
// : utilisées par DOS (mode console, fichiers ascii) et
// : par Windows (environnement Dev-cpp, bloc-notes...) -
// :
// : Le code ascii sur 7 bits (0..127) est parfaitement standardisé
// : mais les codes entre 128 et 255 ont été remaniés pour prendre
// : en compte les diverses graphies européennes sans répondre à tous
// : les besoins ; la solution "définitive" réside dans l'UNICODE que
// : le C/C++ ne manie pas aisément (char sur 1 seul octet).
// :
// : Ce fichier propose :
// : - la liste et le code des caractères étendus pour console DOS
// : - la liste et le code des caractères étendus pour Windows
// : - une fonction polymorphe** transcode ayant 2 paramètres et qui
// : traduit les codes > 127 à l'aide d'un tableau (param n°2).
// : - une fonction polymorphe** transcode à 3 paramètres qui traduit
// : tout caractère apparaissant dans une chaîne patron (param n°2)
// : en son homologue dans un chaîne lexique (param n°3).
// : - quatre fonctions polymorphes** de traduction DOS <--> Windows
// : et en code ascii 7 bits standard (désaccentuation, supression
// : des caractères semi graphiques...) sous forme de macros.
// : = w2d traduit les caractères Windows en caractères DOS
// : = d2w traduit les caractères DOS en caractères Windows (w2d~¹)
// : = w2a suppression des accents, cédilles... partant de Windows
// : = d2a suppression des accents, cédilles... partant de DOS
// : ** les diverses formes des fonctions f ci-dessus sont
// : char f (const char arg) => (caractère) arg est inchangé
// : char* f(const char* st) => (chaîne fixe) st est inchangé, le
// : résultat est retourné dans un chaîne temporaire (réallouée)
// : char* f(char* st) => (chaîne) st est traduite
// : - quatre fonctions qui permettent de copier une chaîne constante
// : dans une chaîne variable en la traduisant ; elles ont pour
// : forme commune _2_cpy(char *dest, const char* source) :
// : w2dcpy, d2wcpy, w2acpy, d2acpy définies par des macros
// : - une fonction transcode à 4 paramètres (st, model, pattern,
// : translation) qui copie en la traduisant la chaîne model dans
// : la chaîne st en utilisant la chaîne pattern comme patron et
// : la chaîne translation comme lexique.
// LIMITES : Du fait de l'allocation mémoire nécessaire pour stocker la
// : traduction des chaînes constantes, il est déconseillé d'utiliser
// : ces fonctions pour des chaînes constantes dans l'appel à des
// : fonctions sur les chaînes : exemple
// : char str[80];
// : cout << strupr(strcat(w2a("Un été"),w2a(" hawaïen")));
// : devrait produire "UN ETE HAWAIEN", mais il risque de produire
// : une violation mémoire ; il est préférable d'introduire une chaîne
// : variable pour concaténer et n'avoir qu'un pointeur créé.
// : cout << strupr(strcat(w2acpy(str,"Un été"),w2a(" hawaïen!")));
// : ou encore
// : cout << strupr(w2acpy(strcat(w2acpy(string,"Un été"),
// : " hawaïen!")));
// : cette dernière forme ne provoquant pas d'allocation dynamique de la
// : mémoire.
// : Remarque : en fait, l'instruction pur sucre C/C++ (string.h)
// : cout << strupr("Un ete hawien") ;
// : passe à la compilation mais plante à l'exécution (vive le C!)
// : tandis que les fonctions w2d, w2a... s'exécutent correctement
// : avec des chaînes constantes comme par exemple dans :
// : cout << w2d("Un été hawaïen") ;
// AUTEUR(S) : A.LOZES - IUT GEII TOULOUSE III - andre.lozes@iut-tlse3.fr
//******************************************************************************
#ifndef _TRANSCODE_AL
#define _TRANSCODE_AL
#include <stdlib.h>
#include <string.h>
static const char DOS2WIN[128]=
// équivalents sous Windows des codes > 127 sous DOS
{'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è', 'ï', 'î', 'ì', 'Ä', 'Å',
//128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', 'ø', '£', 'Ø', '×', 'ƒ',
//144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '®', '¬', '½', '¼', '¡', '«', '»',
//160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
'¦', '¦', '¦', '¦', '¦', 'Á', 'Â', 'À', '©', '¦', '¦', '+', '+', '¢', '¥', '+',
//176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
'+', '-', '-', '+', '-', '+', 'ã', 'Ã', '+', '+', '-', '-', '¦', '-', '+', '¤',
//192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
'ð', 'Ð', 'Ê', 'Ë', 'È', 'i', 'Í', 'Î', 'Ï', '+', '+', '¦', '_', '¦', 'Ì', '¯',
//208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
'Ó', 'ß', 'Ô', 'Ò', 'õ', 'Õ', 'µ', 'þ', 'Þ', 'Ú', 'Û', 'Ù', 'ý', 'Ý', '¯', '´',
//224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
'-', '±', '=', '¾', '¶', '§', '÷', '¸', '°', '¨', '·', '¹', '³', '²', '¦', ' '};
//240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
static const char DOS2ASC[128]=
// équivalents ascii standard des codes > 127 sous DOS
{'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A',
//128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
'E', 'a', 'A', 'o', 'o', 'o', 'u', 'u', 'y', 'O', 'U', '/', 'L', '/', 'x', 'f',
//144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
'a', 'i', 'o', 'u', 'n', 'n', 'a', 'o', '?', 'R', '/', ' ', ' ', '!', '"', '"',
//160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
'|', '|', '|', '|', '|', 'A', 'A', 'A', 'c', '|', '|', '+', '+', 'c', 'Y', '+',
//176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
'+', '-', '-', '+', '-', '+', 'a', 'A', '+', '+', '-', '-', '|', '-', '+', '*',
//192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
'd', 'D', 'E', 'E', 'E', 'i', 'I', 'I', 'I', '+', '+', '|', '_', '|', 'I', '-',
//208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
'O', 'B', 'O', 'O', 'o', 'O', 'u', '|', '|', 'U', 'U', 'U', 'y', 'Y', '-','\'',
//224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
'-', '#', '=', '#', 'q', '$', '/', '.', ' ', '^', '.', '1', '3', '2', '|', ' '};
//240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
static const char WIN2DOS[128]=
// équivalents sous DOS des codes > 127 sous Windows
{189, 32, ',', 159, ',', 32, 197, 206, '^', 32, 'S', '<', 'O', 32, 'Z', 32,
//'' '' '‚' 'ƒ' '„' '…' '†' '‡' 'ˆ' '‰' '' '‹' '' '' '' ''
32,'\'','\'','\"','\"', '.', '-', '-','\"', 32, 's', '>', 'o', 32, 'z', 'Y',
//'' '‘' '’' '“' '”' '•' '–' '—' '˜' '™' '' '›' '' '' '' ''
32, 173, 189, 156, 207, 190, '|', 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};
//'ð' 'ñ' 'ò' 'ó' 'ô' 'õ' 'ö' '÷' 'ø' 'ù' 'ú' 'û' 'ü' 'ý' 'þ' 'ÿ'
static const char WIN2ASC[128]=
// équivalents ascii standard des codes > 127 sous Windows
{'e', 32, ',', 'f', '"', ' ', ' ', ' ', '^', 32, 'S', '<', 'O', 32, 'Z', 32,
//'' '' '‚' 'ƒ' '„' '…' '†' '‡' 'ˆ' '‰' '' '‹' '' '' '' ''
32, '\'','\'','\"','\"','\'','-', '-', '~', 32, 's', '>', 'o', 32, 'z', 'Y',
//'' '‘' '’' '“' '”' '•' '–' '—' '˜' '™' '' '›' '' '' '' ''
32, ';', 'c', ' ', ' ', 'Y', '|', '$', '\"', 'c', 'a','\"','/' ,'-', 'R', '-',
//' ' '¡' '¢' '£' '¤' '¥' '¦' '§' '¨' '©' 'ª' '«' '¬' '' '®' '¯'
' ', '#', 'a','\"','\'', 'u', 'q', '.', 32, 32, 32,'\"', ' ', ' ', ' ', '?',
//'°' '±' '²' '³' '´' 'µ' '¶' '·' '¸' '¹' 'º' '»' '¼' '½' '¾' '¿'
'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I',
//'À' 'Á' 'Â' 'Ã' 'Ä' 'Å' 'Æ' 'Ç' 'È' 'É' 'Ê' 'Ë' 'Ì' 'Í' 'Î' 'Ï'
'D', 'N', 'O', 'O', 'O', 'O', 'O', 'x', 32, 'U', 'U', 'U', 'U', 'Y', '/', 'B',
//'Ð' 'Ñ' 'Ò' 'Ó' 'Ô' 'Õ' 'Ö' '×' 'Ø' 'Ù' 'Ú' 'Û' 'Ü' 'Ý' 'Þ' 'ß'
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
//'à' 'á' 'â' 'ã' 'ä' 'å' 'æ' 'ç' 'è' 'é' 'ê' 'ë' 'ì' 'í' 'î' 'ï'
'o', 'n', 'o', 'o', 'o', 'o', 'o', ':', 'o', 'u', 'u', 'u', 'u', 'y', '/', 'y'};
//'ð' 'ñ' 'ò' 'ó' 'ô' 'õ' 'ö' '÷' 'ø' 'ù' 'ú' 'û' 'ü' 'ý' 'þ' 'ÿ'
/******************************************************************************/
/* substitution de tout caractère apparaissant dans la chaîne patron par le */
/* caractère de même rang dans la chaîne lexique : la substitution s'opère */
/* sur le caractère ou sur la chaîne passée en premier paramètre. */
/******************************************************************************/
char transcode(const char arg, const char *pattern, const char *translation)
// traduction d'un caractère isolé
{
int i;
if (i=(int) strchr(pattern,arg))
// traduction ssi patron et lexique sont cohérents
if (strlen(translation)==strlen(pattern))
return (translation[i-(int)pattern]);
return (arg);
}
/******************************************************************************/
char* transcode( const char *st, const char *pattern, const char *translation)
// traduction d'une chaîne constante : nécessité d'allouer de la mémoire pour
// la chaîne résultante. Pour éviter la famine mémoire on réalloue.
{
static char *TRANSCODE_BUFFER; // pointeur statique pour pouvoir reallouer
int i, k=strlen(st);
TRANSCODE_BUFFER=(char *) realloc(TRANSCODE_BUFFER,k+1);
strcpy(TRANSCODE_BUFFER,st);
if (strlen(translation)==strlen(pattern))
while(k-->0)
if (i=(int) strchr(pattern,st[k]))
TRANSCODE_BUFFER[k]=translation[i-(int)pattern];
return (TRANSCODE_BUFFER);
}
/******************************************************************************/
char* transcode( char *st, const char *pattern, const char *translation)
// traduction d'une chaîne variable st : st est modifiée, mais pas sa longueur.
{
int i, k=strlen(st);
if (strlen(translation)==strlen(pattern))
while(k-->0)
if (i=(int) strchr(pattern,st[k]))
st[k]=translation[i-(int)pattern];
return (st);
}
/******************************************************************************/
/* traduction d'une chaîne fixe model et copie dans une chaîne variable st en */
/* transformant tout caractère contenu dans pattern par son homologue dans la */
/* chaîne translation. */
/******************************************************************************/
char* transcode(char *st, const char *model,
const char *pattern, const char *translation)
{
int k=0;
do
st[k]=transcode((const char) model[k],pattern,translation);
while (st[k++] != '\0');
st[k]='\0'; // les longueurs de st et model peuvent diffèrer
return (st);
}
/******************************************************************************/
/* traduction des caractères de code > 127 selon un dictionnaire sous forme */
/* d'un tableau de 128 caractères : l'indice augmenté de 128 représente le */
/* code d'entrée et le contenu représente le code de sortie (code traduit). */
/******************************************************************************/
char transcode(const char arg, const char *dictionnary)
// traduction d'un caractère isolé constant
{
if (arg&0x80) // valeur de arg entre 128 et 255 => bit 7 à 1
return (dictionnary[arg&0x7F]); // l'indice est ramené entre 0 et 127
else
return (arg);
}
char* transcode(const char *st, const char *dictionnary)
// traduction d'une chaîne constante : la chaîne retournée est
// stockée en mémoire dynamique ; elle sera écrasée au prochain appel
// de la fonction
{
int i=0;
static char *TRANSCODE_BUFFER;
TRANSCODE_BUFFER=(char *) realloc(TRANSCODE_BUFFER,strlen(st)+1);
do
{
if (st[i]&0x80)
TRANSCODE_BUFFER[i]=dictionnary[st[i]&0x7F];
else
TRANSCODE_BUFFER[i]=st[i];
}
while (st[i++]);
TRANSCODE_BUFFER[i]='\0';
return(TRANSCODE_BUFFER);
}
/******************************************************************************/
char* transcode(char *st, const char *dictionnary)
// traduction d'une chaîne variable st : st est modifiée, mais pas sa longueur.
{
int i=0;
do
{
if (st[i]&0x80)
st[i]=dictionnary[st[i]&0x7F];
}
while (st[i++]);
return(st);
}
/******************************************************************************/
/* copie d'une chaîne constante dans une chaine variable et traduction de */
/* cette dernière en utilisant le dictionnaire pour les codes > 127. */
/******************************************************************************/
char* copytranscode(char *st, const char *model, const char *dictionnary)
// copie de model dans la chaîne variable st : st est traduite et modifiée.
{
int i=0;
do
{
if (model[i]&0x80)
st[i]=dictionnary[model[i]&0x7F];
else
st[i]=model[i];
}
while (model[i++]);
st[i]='\0'; // Risque potentiel de débordement comme pour strcpy...
return(st);
}
/******************************************************************************/
/* traduction d'un caractère ou d'une chaîne x de WINDOWS vers DOS, WINDOWS */
/* vers ACII7bits, DOS vers WINDOWS ou encore de DOS vers ASCII7bits. */
/******************************************************************************/
#define w2d(x) transcode(x,WIN2DOS)
#define w2a(x) transcode(x,WIN2ASC)
#define d2w(x) transcode(x,DOS2WIN)
#define d2a(x) transcode(x,DOS2ASC)
/******************************************************************************/
/* copie d'une chaîne y dans une chaine x et traduction de x de WINDOWS vers */
/* DOS, WINDOWS vers ACII 7bits, DOS vers WINDOWS ou de DOS vers ASCII 7bits. */
/******************************************************************************/
#define w2dcpy(x,y) copytranscode(x,y,WIN2DOS)
#define w2acpy(x,y) copytranscode(x,y,WIN2ASC)
#define d2wcpy(x,y) copytranscode(x,y,DOS2WIN)
#define d2acpy(x,y) copytranscode(x,y,DOS2ASC)
#endif
/************************************************************************************************/
// sauver le code ci-dessus dans un fichier dénooné transcode.hpp
// et le fichier ci-dessous dans un fichier eomchar.cpp
//*********************************************************************
// PROGRAMME : oemchar.cpp
// DATE : 7/02/05
// OBJET : exemple d'utilisation de transcode.hpp
// LIMITES :
// AUTEUR(S) : A.LOZES
//*********************************************************************
#include "transcode.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
using namespace std;
/******************************************************************************/
int main ()
{
char ligne[80]="Noëlle aperçut bientôt là bas l'âne bâté.";
char ch;
cout << "* Comment s'impriment les accents sous DOS ? " << endl;
ch='ö';
cout << 'ù' << ' ' << ch << endl;
cout << ligne << endl;
cout << "ãâäàáêëéèîïìõôöòûüùÃÂÄÀÁÊËÈÎÏÍÕÔÖÒÓÛÜñÑçÇÿýÝ" << endl;
cout << " Pour continuer taper [Entrée]" << endl;
getch();
cout << endl;
cout << w2d("* Utilisation de la fonction w2d sur caractère et chaîne")
<< endl;
cout << w2d('ù') << ' ' << w2d(ch) << endl << w2d(ligne) << endl;
cout << w2d("ãâäàáêëéèîïìõôöòûüùÃÂÄÀÁÊËÈÎÏÍÕÔÖÒÓÛÜñÑçÇÿýÝ") << endl;
cout << w2d(" C'est pas terminé") << endl;
getch();
cout << endl
<< w2d("* Utilisation de la fonction w2a sur caractère et chaîne")
<< endl;
cout << w2a('ù') << ' ' << w2a(ch) << endl << d2a(ligne) << endl;
/* d2a car ligne est déjà traduite en DOS*/
/* ou encore :
cout << w2a('ù') << ' ' << w2a(ch) << endl
<< w2acpy(ligne,"Noëlle aperçut bientôt là bas l'âne bâté") << endl;
cout << w2a("ãâäàáêëéèîïìõôöòûüùÃÂÄÀÁÊËÈÎÏÍÕÔÖÒÓÛÜñÑçÇÿýÝ") << endl;
cout << w2a(" C'est pas encore terminé") << endl;
getch();
cout << endl
<< w2d("* Utilisation de la fonction translate avec 4 paramètres")
<< endl;
cout << transcode("exemple de transcodage avec un patron et un lexique",
"aeiou",w2d("àéîöù")) << endl;
/* ou encore :
cout << w2d(transcode("exemple de transcodage avec un patron et un lexique",
"aeiou","àéîöù")) << endl;
cout << " C'est fini\n" << endl;
cout << strcat( strcat( w2dcpy( ligne,"Un été hawaïen!" ), " ==> " ),
strupr( w2a("Le noël à Curaçao") ) ) << endl;
system("pause");
}
Conclusion :
Ma source sera disponible dans 1 semaine sur
http://www.laas.fr/~alozes
pour tout commentaire, réaction ou demande d'éclairsissement : alozes@laas.fr
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.