IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Remplacer les accents dans une chaîne


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Remplacer les accents dans une chaîne
    Mon programme a un mode graphique et un mode texte. Il lit des chaînes dans un fichier texte et les conserve en mémoire. Lorsque vient le temps de les afficher, une petite fonction qui remplace les caractères accentués par leur équivalent non-accentué serait idéale.

    J'ai trouvé ceci: http://www.developpez.net/forums/showthread.php?t=56427 , mais je voulais savoir s'il y avait une méthode plus propre/efficace tout en restant portable.

    Merci beaucoup

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Il est tres bien son code...

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    En fait selon les commentaires, il semble y avoir quelques problèmes quoique facilement réparables. Je n'ai pas dit non plus que son code n'était pas bien, j'ai dit que s'il y avait une autre méthode par exemple utilisant les librairies standard, ce serait mieux.

  4. #4
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    voir le lien d'Emmanuel: http://emmanuel-delahaye.developpez.com/clib.htm

    les problemes evoqués par l'auteur n'apparaissent pas dans ce code la.
    click my www
    ............|___
    ...................\
    .................._|_
    ..................\ /
    ..................."

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Points : 97
    Points
    97
    Par défaut
    salut,

    Citation Envoyé par mathieumg
    J'ai trouvé ceci: http://www.developpez.net/forums/showthread.php?t=56427 , mais je voulais savoir s'il y avait une méthode plus propre/efficace tout en restant portable.
    juste une petite remarque concernant le code en question.. pour eviter les tartines de "case", et quitte a considerer que le code va tourner sous certains parametres regionaux comme c'est le cas ici ("codepage" pour les windowsiens, ou "locale" pour les unixiens), il vaut mieux utiliser des tables de translation pour faire ce genre de choses.

    exemple, la table suivante permet d'inverser majuscules/minuscules, et de ne prendre en compte que les caracteres "imprimables" (je repete, il s'agit d'un exemple, inutile de me dire qu'on peut faire la meme chose en "plus portable" avec des toupper() / tolower(), ou que ca ne marche pas en EBCDIC sur votre IBM System/390, je le sais).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    const unsigned char trans_case[ 256 ] = {
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x09, 0x0a, 0x00, 0x00, 0x0d, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,  0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
     
       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,  0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,  0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
     
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    pour convertir un caractere (unsigned char), on utilise sa valeur comme un index pour aller interroger la table, et y recuperer la valeur correspondante (translatee). si on a par exemple un buffer "x" de "n" bytes a convertir (apres un read() par exemple):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int i;
     
    for( i = 0 ; i < n ; ++i )
      x[i] = trans_case[ (int)(x[i] & 0xff) ];
    ce genre de tables presentent de nombreux avantages, entre autres:

    • c'est beaucoup plus rapide qu'un switch suivi d'une serie de case (bonus: c'est aussi plus propre),
    • elles peuvent etre utilisees, outre la conversion, pour la validation des entrees (si vous developpez des services accessibles par le public, vous savez de quoi je parle..),
    • elles peuvent etre generees automatiquement, soit au moment de la compilation, soit au runtime,
    • elles peuvent etre contenues dans des ".o" separes, et linkees ensuite, ce qui est tres interessant dans certains cas, et qui facilite les mises a jour / modifs.


    -pirus.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Cela met bien les caractères en majuscules mais les caractères accentués sont remplacés par des espaces

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Points : 97
    Points
    97
    Par défaut
    Citation Envoyé par mathieumg
    Cela met bien les caractères en majuscules mais les caractères accentués sont remplacés par des espaces
    eh eh.. oui, en fait je me suis peut-etre mal exprime, mais il s'agissait d'un.. exemple ;p (dont la vocation etait d'ailleurs plus d'attirer ton attention sur la methode que de repondre precisement a ton probleme).

    voici donc une nouvelle table qui fait ce que tu souhaites (remplacer les caracteres accentues par leur equivalent sans accent):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    const unsigned char trans_acc[ 256 ] = {
       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,  0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
     
       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,  0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,  0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
     
       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
       0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,  0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
       0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,  0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
       0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
     
       0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xc6, 0x43,  0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
       0xd0, 0x4e, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0xd7,  0xd8, 0x55, 0x55, 0x55, 0x55, 0x59, 0xde, 0xdf,
       0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xe6, 0x63,  0x65, 0x65, 0x65, 0x65, 0x69, 0x69, 0x69, 0x69,
       0x6f, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0xf7,  0xf8, 0x75, 0x75, 0x75, 0x75, 0x79, 0xfe, 0x79
    };
    tu noteras que c'est dans le dernier quart de la table (entre 192 et 255) que ca se passe. exemple, de 0xc0 (192) a 0xc4 (197, soit les caracteres "ÀÁÂÃÄ"), tout est remplace par 0x41 (65, soit "A").

    encore une fois, ceci est tout a fait dependant des parametres de langue de la machine sur laquelle tourne le programme.. si tu veux etre certain que tout fonctionne partout de la meme facon, il faut laisser tomber le code ASCII et passer en Unicode.

    exemple de ce que ca donne ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    % cat accents.txt 
    ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
    ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
    àáâãäåæçèéêëìíîï
    ðñòóôõö÷øùúûüýþÿ
     
    % ./conv < accents.txt 
    AAAAAAÆCEEEEIIII
    ÐNOOOOO×ØUUUUYÞß
    aaaaaaæceeeeiiii
    onooooo÷øuuuuyþy
    -pirus.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    J'avais mal interprété "prendre en compte que les caractères imprimables" alors, désolé

    Le nouveau code fonctionne à la perfection! Merci beaucoup! Tant qu'il est compilable dans GCC sous Linux, Mac et Windows, je serais plus qu'heureux, est-ce le cas?

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Points : 97
    Points
    97
    Par défaut
    salut,

    j'allais commencer ma reponse en te demandant de m'excuser pour le retard, mais je constate qu'on a a peu pres les memes horaires

    j'ai teste sous Linux (i386), NetBSD (sparc64) et Windows (avec mingw, et seulement sous wine). je n'ai pas de mac sous la main pour l'instant.

    -pirus.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Merci beaucoup pour l'information et pour tout, cela me semble assez portable

Discussions similaires

  1. Supprimer les accents dans une chaîne
    Par SuperChafouin dans le forum Langage
    Réponses: 4
    Dernier message: 17/12/2007, 17h28
  2. Comment remplacer plusieurs caractères dans une chaîne?
    Par Antigonos Ier Gonatas dans le forum Général Python
    Réponses: 5
    Dernier message: 16/06/2006, 16h04
  3. [RegEx] Trouver tous les "/mot" dans une chaîne
    Par micatmidog dans le forum Langage
    Réponses: 7
    Dernier message: 31/03/2006, 12h07
  4. ignorer les accents dans une recherche
    Par nono_cap dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/03/2006, 17h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo