Transcodage entre diffrérents codes (dev-cpp)

Description

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
 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', 'ø', '£', 'Ø', '×', '&#402;',
//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,
//'€'  ''  '&#8218;'  '&#402;'  '&#8222;'  '&#8230;'  '&#8224;'  '&#8225;'  '&#710;'  '&#8240;'  'Š'  '&#8249;'  'Œ'  ''  'Ž'  ''
  32,'\'','\'','\"','\"',  '.', '-', '-','\"', 32, 's', '>', 'o',  32, 'z', 'Y', 
//''  '&#8216;'  '&#8217;'  '&#8220;'  '&#8221;'  '&#8226;'  '&#8211;'  '&#8212;'  '&#732;'  '&#8482;'  'š'  '&#8250;'  'œ'  ''  'ž'  'Ÿ'  
  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,
//'€'  ''  '&#8218;'  '&#402;'  '&#8222;'  '&#8230;'  '&#8224;'  '&#8225;'  '&#710;'  '&#8240;'  'Š'  '&#8249;'  'Œ'  ''  'Ž'  ''  
  32, '\'','\'','\"','\"','\'','-', '-', '~',  32, 's', '>', 'o',  32, 'z', 'Y',
//''  '&#8216;'  '&#8217;'  '&#8220;'  '&#8221;'  '&#8226;'  '&#8211;' '&#8212;'   '&#732;'  '&#8482;'  'š'  '&#8250;'  'œ'  ''  'ž'  'Ÿ'  
  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

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.