Fonction retire_accent en C

Fermé
Dante - 9 déc. 2008 à 18:14
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 10 déc. 2008 à 00:22
Bonjour, je suis débutant en programmation et j'ai tenté de réaliser une fonction qui retire les accents d'une chaine de caractères mais elle ne fonctionne pas, si quelqu'un peut me venir en aide je le remercie d'avance

voici mon code:

char* retire_accent (char *s)
{int i;
char acc[15]={'à','â','ä','é','è','ê','ë','ï','ì','î','ô','ö','ù','û','ü'};
char cor[5]={'a','e','i','o','u'};
for (i=0;s[i]!='\0';i++)

{
if (s[i]==acc[0] || s[i]==acc[1] || s[i]==acc[2])
{s[i]==cor[0];
}
else if (s[i]==acc[3] || s[i]==acc[4] || s[i]==acc[5] || s[i]==acc[6])
{s[i]==cor[1];
}
else if (s[i]==acc[7] || s[i]==acc[8] || s[i]==acc[9])
{s[i]==cor[2];
}
else if (s[i]==acc[10] || s[i]==acc[11])
{s[i]==cor[3];
}
else if (s[i]==acc[12] || s[i]==acc[13] || s[i]==acc[14])
{s[i]==cor[4];
}
}

return s;
}

merci

6 réponses

s[i]==cor[0]; !!!!!!!!!!

Toujours le même problème:
Il ne faut pas confondre l'opérateur d'égalité (==) et l'opérateur d'assignation (=).

Donc mettre: s[i] = cor[0]; de même pour les autres.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 842
9 déc. 2008 à 18:30
Salut,
Ton algo me paraît bien compliqué.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void){
    char chAvAccents[]="éléphantà";
    const char *elem="àé"; //les caractères accentués

    //on définit une chaîne de taille égale à chAvAccents
    char *p=malloc(strlen(chAvAccents)+1);
    if(p==NULL) exit(EXIT_FAILURE);
    int j;
    int k=0;
    for(int i=0;i<strlen(chAvAccents)+1;i++){
        for(j=0;j<strlen(elem)+1;j++)
            if(chAvAccents[i]==elem[j]) break;
        if(j==strlen(elem)+1) p[k++]=chAvAccents[i]; //ce n'est pas un accent, on le copie.
    }
    free(p);p=NULL;
    return 0;
}

Cdlt
0
merci pour votre aide^^

mais ta fonction fiddy est plus courte mais plus compliqué je trouve, je la comprend pas tellement en fait
0
Encore plus simple et surtout beaucoup plus rapide:

void retire_accent (char *s)
{
   int i;
   char acc[15]={'à','â','ä','é','è','ê','ë','ï','ì','î','ô','ö','ù'­,'û','ü'};
   char cor[ 5]={'a','a','a','e','e','e','e','i','i','i','o','o','u''u','u',};
   char* p = s;

   while (*p)
   {
      for (i=0; i<15; i++)
         if (*p == acc[i])
         {
            *p = cor|i];
            break;
         }
      p++;
   }
}


Au retour la chaîne est modifiée; si l'on a besoin (pour chaînage de fonction), on peut aussi faire:

char* retire_accent (char *s)
{
   ... partie identique
   return s;
}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 842
9 déc. 2008 à 21:52
Plus simple mais faux en plusieurs point.
Déjà le char acc[15] te permets de mettre que 14 éléments, le 15ème étant réservé au \0.
Dans ce cas-là, vaut mieux laisser le calcul au compilateur en mettant char acc[]={...};

Ensuite, utiliser un tableau de char pour contenir des caractères étendus est une mauvaise idée, le char n'allant que jusque 255. Il vaut mieux utiliser wchar_t (sans oublier d'implémenter la bibliothèque).

Cdlt
0
loupius > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
9 déc. 2008 à 22:51
"Déjà le char acc[15] te permets de ne mettre que 14 éléments, le 15ème étant réservé au \0."
- Non je ne suis pas d'accord, seules les chaînes de caractères sont terminées par un \0, or ici il s'agit d'un tableau de caractères et la boucle 'for' balaye de 0 à 14. Par contre cor doit être déclaré comme cor[15] (erreur de ma part).Mais il est certain qu'il est plus facile de déclarer: char* acc[] = "...";

Pour ce qui est du type du tableau: là où il y a 20 ans il n'y avait pas de problème, aujourd'hui il y a un hic; pouquoi?
Jadis tout caractère était codé sur 8 bits... mais aujourd'hui ce n'est plus le cas et il est vrai que de déclarer un tableau de caractère de type char... peut poser un problème, curieux mais c'est la réalité. En fonction de l'environnement selon lequel on travaille, on peut effectivement être amené à utiliser un autre type. Personnellement je travaille avec Qt et donc des types QString, ce qui signifie que je laisse à Qt le soin de gérer ce type de problème.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 842 > loupius
9 déc. 2008 à 23:29
Mais il est certain qu'il est plus facile de déclarer: char* acc[] = "...";
char acc[]=... (ne pas mettre le pointeur, sinon on obtient un tableau de pointeurs).

Non je ne suis pas d'accord, seules les chaînes de caractères sont terminées par un \0
Oui, exactement. C'est bien pour ça que je te dis de mettre un \0. En fait en mémoire avec ton initialisation, tu vas obtenir un tableau de char avec tous tes caractères sans le '\0'. Et là horreur, le compilateur ne saura plus distinguer la fin. Par exemple, fais un
puts(cor)
et tu verras que tu obtiens plein des caractères non voulus à côté. (Avec de la chance t'obtiendras le résultat escompté, mais cela dépend des octets de la pile). Et c'est normal, le puts, strlen et compagnie ont besoin du '\0' pour s'arrêter.

Pour ce qui est du type du tableau: là où il y a 20 ans il n'y avait pas de problème, aujourd'hui il y a un hic; pouquoi?
Il y a toujours eu des problèmes avec les caractères. C'est pas pour rien d'ailleurs qu'il existe autant de codages différents (utf-8,utf-16, unicode, 8859-1, etc). En fait ce qui ne va pas dans ton algorithme, c'est que tu incrémentes d'un dans ton for, mais tu ne parcouriras pas tes tableaux correctement puisque le code ascii de 'é' déborde la valeur maximale du char. Donc, cafouillis dans la mémoire.

Jadis tout caractère était codé sur 8 bits
Tout dépend de l'encodage. Mais il n'existe aucun codage permettant de représenter tous les caractères en 8 bits, seulement certain. Il ne faut pas oublier nos amis slaves, chinois et compagnie).

Personnellement je travaille avec Qt et donc des types QString, ce qui signifie que je laisse à Qt le soin de gérer ce type de problème.
Oui, c'est l'avantage des langages de programmation avec un haut niveau d'abstraction. Mais dès qu'on travaille près de la machine comme en C, cela n'est pas aussi aisé.

Cdlt
0
loupius > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
9 déc. 2008 à 23:53
Oui je me suis trompé, la déclaration est bien char s[] = ""; je n'ai pas fait attention.

Mais la déclaration "char acc[15]={'à','â','ä','é','è','ê','ë','ï','ì','î','ô','ö','ù'­­,'û','ü'};" est correcte car 'acc' est utilisé en tant que tableau de caractères et jamais en tant que chaîne de caractères. Il est vrai qu'un 'puts' donnerait une erreur mais ce n'est pas le cas dans le programme.

Si j'ai utilisé des caractères 8 bits, c'est parce que la question posée le sous-entendait. mais je suis bien d'accord, aujourd'hui cela doit être pris avec des pincettes.
Effectivement le codage sur 8 bits posait problème et on utilisait plusieurs codage différents mais ils étaient tous sur 8 bits, ce qui n'est effectivement plus le cas aujourd'hui.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 842 > loupius
10 déc. 2008 à 00:22
Non avant non plus tous les caractères ne pouvaient pas être stockés sur 8 bits. Et c'est normal, le nombre de caractères universels dépassent largement 256. C'est un simple problème de dénombrements.
Après il y a des encodages comme 8859-1, où effectivement tu as toute la table ascii + étendu représenté sur 1 octet. Mais en C, ce n'est pas le cas.
Si tu fais char c='é'; le compilateur doit te signaler un warning. (Dépassement de valeur).
Par contre si tu fais char c[]="é". Il n'y aura pas de souci, mais le sizeof c, retournera 2+1. Et cela a toujours était le cas en C.
Cdlt
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ta fonction est très intéressante loupius mais je suis désolé elle ne fonctionne pas
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 842
9 déc. 2008 à 22:10
Salut,
En fait, j'ai mal lu ce que tu voulais, je croyais que tu voulais simplement effacer les caractères.
Comme j'ai dit plus haut, tu vas devoir utiliser wchar_t. Tu connais, ça te pose souci ou pas ?
Sinon je te propose :

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>

void retire_accent(wchar_t *s,char*res){
    wchar_t acc[]=L"àâäéèêëïìîôöùûü";
    wchar_t cor[]=L"aaaeeeeiiioouuu";

    int j;
    for(int i=0;i<wcslen(s)+1;i++){
        for(j=0;j<wcslen(acc)+1;j++){
            if(s[i]==acc[j]){
                res[i]=cor[j];
                break;
            }
        }
        if(j==wcslen(acc)+1) res[i]=s[i];
    }
}
int main(void){
    wchar_t s[]=L"éléphanôûî";
    char *t=malloc(wcslen(s)+1);
    if(t==NULL) exit(EXIT_FAILURE);
    retire_accent(s,t);
    puts(t);
    free(t);t=NULL;
    return 0;
}


Si tu as besoin d'explication, n'hésite pas à demander.
Cdlt
0