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 :

modifier une chaîne de caractères dans une fonction void


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2012
    Messages : 26
    Par défaut modifier une chaîne de caractères dans une fonction void
    Bonjour à tous, et bonne année à tous.

    Je m'adresse à vous car j'ai un petit souci avec une fonction, voici d'abord une version de ma fonction qui marche très bien et qui fait ce j'attend d'elle, c'est-à-dire supprimer les doublons dans une chaîne de caractère passée en paramètre un peu comme l'outil "tr" sous linux, donc si par exemple je lu donne la chaîne "bonne annnee" elle me renvoie "bone ane":

    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
    23
    24
    25
    26
    27
    28
    char* SupprimerDoublon(char *chaine, char lettre)
    {
        char *tab = malloc(sizeof(char) * strlen(chaine));
     
        if(!tab) exit(-1);
     
        int i = 0, j = 0;
     
        while(chaine[i] != '\0')
        {
            if(chaine[i] == lettre)
            {
                tab[j] = chaine[i];     
     
                for(;chaine[i] == lettre; i++);
                j++;
            }
            else
            {
                tab[j] = chaine[i];
                i++; j++;
            }
        }
     
        tab[j] = '\0';
     
        return tab;
    }
    Mais je dois appeler cette fonction de cette façon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    char *maChaine[] = {"bonjof gbbffgw fdgfwggf wdfggdfgggggdffggff wdxur al",
                            "bbonne annee a tous",
                            "superbbe biien mon ammi"};
        int i, j;
     
        for(i = 0; i < 3; i++)
            maChaine[i] = SupprimerDoublon(maChaine[i], 'n');
     
     
        for(j = 0; j < 3; j++)
        {
            printf("%s\n", maChaine[j]);
            free(maChaine[j]);
        }
    et j'ai donc décidé de la modifier en (void) pour pouvoir l'appeler simplement comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        for(i = 0; i < 3; i++)
                 SupprimerDoublon(maChaine[i], 'n');
    Et c'est là que les problème commencent, voici mon code qui donne une segmentation fault à la ligne .

    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
    23
    24
    25
    26
    27
    28
    void SupprimerDoublon(char *chaine, char lettre)
    {
        char *tab = malloc(sizeof(char) * strlen(chaine));
     
        if(!tab) exit(-1);
     
        int i = 0, j = 0;
     
        while(chaine[i] != '\0')
        {
            if(chaine[i] == lettre)
            {
                tab[j] = chaine[i];  
     
                for(;chaine[i] == lettre; i++);
                j++;
            }
            else
            {
                tab[j] = chaine[i];
                i++; j++;
            }
        }
     
        tab[j] = '\0';
     
        strcpy(chaine, tab);
    }
    Donc je me pose des questions, et je ne comprend pas pourquoi ça ne marche pas, sachant que dans le main je l'appelle de cette façon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char *maChaine[] = {"bonjof gbbffgw fdgfwggf wdfggdfgggggdffggff wdxur al",
                            "bbonne annee a tous",
                            "superbbe biien mon ammi"};
        int i, j;
     
        for(i = 0; i < 3; i++)
            SupprimerDoublon(maChaine[i], 'n');
     
     
        for(j = 0; j < 3; j++)
        {
            printf("%s\n", maChaine[j]);
        }
    J'ai un petit doute sur le fait que j'alloue dynamiquement le tab mais pas la chaine qui arrive dans la fonction mais mes tests ne sont pas concluant. Pouvez-vous m'éclairer ?

    Merci à vous.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    C'est vrai que c'est à cause de la nature de la chaine passée en argument à la fonction : elle est allouée dans une zone mémoire non modifiable et du coup le strcpy() plante.

    Il faut savoir que si on écrit
    la chaine "abcde" ne doit pas être modifiée et son adresse est placée dans tab. On préfère écrire par prudence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char * tab = "abcde";
    Par contre avec
    la chaine "abcde" INITIALISE le tableau tab qui peut parfaitement être modifié.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2012
    Messages : 26
    Par défaut
    Ok, j'ai compris mon erreur, ça marche maintenant. Merci beaucoup.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Attention, dans l'état actuel ta fonction SupprimerDoublon contient une fuite de mémoire.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2012
    Messages : 26
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attention, dans l'état actuel ta fonction SupprimerDoublon contient une fuite de mémoire.
    Bonjour, et merci de ta réponse , je t'avouerai que je n'ai pas encore compris / appris ce qu'était vraiment une "fuite de mémoire", donc je ne peux pas vraiment comprendre ce que tu me dis. Par contre, si par "fuite de mémoire" tu veux dire que j'ai oublié de libérer tab dans ma fonction, alrs je comprends de quoi tu parles. Je l'avais viré pour tester quand ça ne marchait pas, mais depuis j'ai bien rajouté:

    juste après le:

    à la fin de ma fonction. Est-ce cela ? Sinon je me suis un peu planté dans la description et je pense que vous l'aviez remarqué, elle ne supprime pas les doublons mais la répetition d'un caractère.

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    je t'avouerai que je n'ai pas encore compris / appris ce qu'était vraiment une "fuite de mémoire", donc je ne peux pas vraiment comprendre ce que tu me dis. Par contre, si par "fuite de mémoire" tu veux dire que j'ai oublié de libérer tab dans ma fonction
    Tu sais donc ce qu'est une fuite mémoire

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jujudelyon Voir le message
    Bonjour, et merci de ta réponse , je t'avouerai que je n'ai pas encore compris / appris ce qu'était vraiment une "fuite de mémoire"
    Bonjour
    Quand tu demandes de la mémoire (avec malloc) elle t'est donnée par l'OS.
    Si tu ne la libères pas mais que ton programme se termine, elle va "on ne sait où". Donc là on parle (en image) de "fuite mémoire".
    Sur certains OS, elle est alors récupérée par l'OS et tout va bien (ou plus prosaïquement l'OS rattrappe la connerie). Sur d'autres il ne la récupère pas et faut alors rebooter ta machine pour retrouver ta pleine capacité RAM.

    PS: évite les "exit()" impromptus en cas d'échec d'une ressource. On ne sort pas d'une fonction par exit mais on renvoie le pb à l'appelant qui pourra alors prendre une décision...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/11/2014, 12h55
  2. [MySQL] Remplacer une chaîne de caractères dans une base de données
    Par Furius dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 27/11/2013, 21h06
  3. Réponses: 7
    Dernier message: 14/12/2005, 09h53
  4. Remplacer une chaîne de caractères dans une base
    Par Furius dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/10/2005, 23h03
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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