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 :

Ecrire une fonction de substitution d'une chaîne dans une autre


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Collégien
    Inscrit en
    Novembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Novembre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Ecrire une fonction de substitution d'une chaîne dans une autre
    Bonjour,

    Je débute tranquillement et en autonomie dans la programmation en langage C.
    Je cherche aujourd'hui à substituer une chaîne à l'intérieur d'une autre. Je n'arrive pas à écrire cette fonction.
    L'exercice 4 de cette page correspond à peu près à ce que je souhaiterai faire : https://www.irif.fr/~carton/Enseigne...d05/sujet.html

    Je ne suis en revanche pas encore habile avec tous ces paramètres. Pouvez-vous m'aider à faire cet exercice qui me servira ensuite à l'adapter à mon besoin personnel.

    Merci de votre aide

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 215
    Points : 10 140
    Points
    10 140
    Par défaut
    Et si tu expliquais précisément ce qui te bloque ?
    Par contre un conseil , si tu ne sais pas expliqué et résoudre le probleme en Français , tu n'arrivera pas a le résoudre dans un autre langage !
    Donc pense d'abord a résoudre le probleme en Français et en pseudo-code(oui parce que l'algo demandé est vraiment pas complexe ) , le traduire en langage C ensuite sera un jeu d'enfant.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Bonjour,

    Regarde du côté des fonctions de manipulation de chaînes :
    Pour substituer une chaîne dans une autre, il faut sans doute commencer par identifier la partie à substituer : cela peut se faire avec une fonction de recherche de sous-chaîne (rien à voir avec l’élixir breton) comme strstr().
    Ensuite les fonctions de manipulation de chaînes sont à étudier pour réaliser une substitution :
    strtok() : pour identifier des sous-chaînes avec des délimiteurs dans la chaîne
    strcpy() : pour copier une chaîne dans une autre
    strcat() : pour concaténer plusieurs chaînes dans une seule

  4. #4
    Nouveau Candidat au Club
    Femme Profil pro
    Collégien
    Inscrit en
    Novembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Novembre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Ce qui me bloque, c'est la construction de l'algorithme, je ne sais pas dans quel ordres effectuer les tâches.
    Je ne suis pas du tout à l'aise avec les chaines de caractères non plus.
    Comme je l'ai dit, je suis débutant et cherche à me former par moi même.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Programmeur des cavernes
    Inscrit en
    Août 2017
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Programmeur des cavernes
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2017
    Messages : 364
    Points : 1 241
    Points
    1 241
    Par défaut
    Il y a d'autres exercices plus simples à faire avant celui-là.

    En as-tu fait d'autres, sur les manipulations de chaînes, jusque là ? Les as-tu réussis ? Est-ce le premier qui te bloque ?

  6. #6
    Nouveau Candidat au Club
    Femme Profil pro
    Collégien
    Inscrit en
    Novembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Novembre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Des exercices de base sur l'insertion de données dans un chaîne, l'affichage, la copie d'une chaine, etc sont des exercices que j'ai réussi à faire sans problème.
    C'est vraiment cet exercice que je voudrais faire car il me semble être une bonne poursuite par rapport aux exercices précédent.
    Mais je ne sais pas quelles étapes et dans quel ordre les effectuer.

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Les chaînes sont des tableaux de caractères :
    Imagine ces chaînes sous forme de bandelettes de papier quadrillé avec un caractère dans chaque case (avec le caractère ‘\0’ dans la dernière case).
    Comment t’y prendrais-tu et dans quel ordre pour les découper et les assembler ?

  8. #8
    Membre éprouvé
    Homme Profil pro
    Programmeur des cavernes
    Inscrit en
    Août 2017
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Programmeur des cavernes
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2017
    Messages : 364
    Points : 1 241
    Points
    1 241
    Par défaut
    melaniedebo:

    Cet exercice là est effectivement plus difficile que les autres :

    1) le motif qu'on veut remplacer peut ne pas exister dans la chaîne initiale : dans ce cas elle doit rester inchangée ;

    2) si le motif recherché existe, on doit le remplacer par un autre motif qui n'a peut être pas la même longueur... la chaîne obtenue peut donc être plus longue que la chaîne initiale, ce qui oblige à bien réfléchir à la manière d'allouer la mémoire ;

    3) l'algorithme en lui-même ressemblerait à :
    a) chercher le motif dans la chaîne initiale (cette question là, à elle seule, n'est déjà pas très simple, et peut faire l'objet d'un exercice préalable et d'une fonction spécifique)
    - s'il n'existe pas : ne rien faire -- fin de l'algo ;
    - s'il existe : noter à quelle position dans la chaîne initiale il commence ;
    b) allouer une nouvelle chaîne de caractères dans laquelle on va écrire le résultat du remplacement (attention : il faut calculer à l'avance la taille de cette chaîne et prévoir de la place pour le zéro final) ;
    c) copier dans cette nouvelle chaîne, dans l'ordre :
    - les caractères de la chaîne initiale situés avant le début du motif cherché ;
    - les caractères du motif de remplacement ;
    - les caractères de la chaîne initiale situés après la fin du motif cherché.

    Bonjour les calculs d'indices à la noix tout le long du processus :-)

    Pour écrire l'algorithme tu peux très bien tout faire "à la main", en lisant et en écrivant des caractères un par un où il faut et quand il faut...
    Ou bien chercher à utiliser les fonctions des bibliothèques standard qui peuvent faire une partie du travail...

    Mais souvent, l'esprit de ce genre d'exercice, c'est plutôt de choisir la première option, parce que ça forme vraiment à la logique et à la maîtrise des bases :-)


    Il faut aussi réfléchir à la façon dont on veut que la fonction de recherche / remplacement se comporte si le motif cherché n'existe pas... affiche-t-on un message d'erreur ou d'avertissement ? donne-t-on une valeur spéciale à une sortie de l'algorithme pour que l'appelant puisse savoir si le motif qu'il voulait remplacer existe réellement dans la chaîne ? Ou bien est-ce qu'on se contente de ne rien faire ?

    Le fait que la chaîne après remplacement puisse avoir une longueur différente de la chaîne avant remplacement pose un petit problème sur la déclaration de la fonction de recherche et remplacement.

    Par exemple :

    void rech_et_remp (char* str, char* motif_cherche, char* motif_de_remplacement);

    n'est pas correct, car les paramètres sont passés par valeur donc problème si str est réallouée à un autre emplacement mémoire pendant l'exécution de la fonction.


    Donc deux options correctes :

    1) char* rech_et_remp (char* str, char* motif_cherche, char* motif_de_remplacement);
    Cette fonction retourne la chaîne obtenue à la fin... pour appeler cette fonction on peut par exemple écrire :

    char* str = clonage_de_chaîne ("Toto est très heureux.");
    str = rech_et_remp (str, "Toto", "Seraphin");

    après cet appel la chaîne str sera égale à "Seraphin est très heureux.".

    2) void rech_et_remp (char** str, chr* motif_cherche, char* motif_de_remplacement);

    ici, str est passé par pointeur (c'est donc un pointeur de pointeur de char) et on en fait en fait un paramètre d'entrée / sortie.

    Dans ce cas l'appel ressemblera à :
    char* str = clonage_de_chaîne ("Toto est très heureux.");
    rech_et_remp (&str, "Toto", "Seraphin");


    N'hésite pas à poser des questions si tu n'as pas tout compris, parce que tu t'attaques là à un problème complexe pour un programmeur débutant... mais il faut persévérer parce que ce genre d'exercice est formateur !

    En cas d'échec persistant, tu peux toujours trouver, ou même inventer toi-même, des exercices de difficulté intermédiaire avant de revenir vers celui-ci.

  9. #9
    Nouveau Candidat au Club
    Femme Profil pro
    Collégien
    Inscrit en
    Novembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Novembre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    De la façon dont je comprends l'exercice, on ne s'intéresse pas à quel morceau de la chaine d'origine doit etre substitué, on donne simplement la position, le nombre de caractères à remplacer et par quoi le remplacer.
    Est ce que je me trompe ?

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Non, c'est cela : une position pos dans la chaine str à remplacer avec un nombre de caractères.

  11. #11
    Nouveau Candidat au Club
    Femme Profil pro
    Collégien
    Inscrit en
    Novembre 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Novembre 2017
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Mais alors quel est l’intérêt de chercher si le morceaux de chaîne existe ?

    Pouvez-vous me montrer un morceau de code, car je piétine sur ce coup.
    Merci

  12. #12
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Écrire une fonction strsubs qui substitue une chaîne de caractères dans une autre chaîne. Cette fonction prend les quatre paramètres suivants :
    1. une chaîne str à l'intérieur de laquelle s'effectue la substitution.
    2. une chaîne motif qui remplace une partie de la chaîne str.
    3. une position pos dans la chaîne str à partir de laquelle on commence à remplacer les caractères de str par ceux de motif.
    4. un nombre len qui donne le nombre maximal de caractères à substituer. La fonction en substitue moins si les fins des chaînes str ou motif sont atteintes avant.
    La fonction strsubs retourne le nombre de caractères qu'elle a effectivement substitués. Le morceau de code
    char s[] = "bonjour à tous";
    strsubs(s, "soirée", 3, 4);
    printf("s = \"%s\"\n", s);

    doit afficher le résultat s = "bonsoir à tous".
    Il s’agit de chercher le morceau de chaîne dans la chaîne motif (« soirée » dans l’exemple), len donne le nombre de caractères depuis le début (4 dans l’exemple et on obtient « soir »).
    On remplace les caractères de str par « soir » à partir de pos

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    Non, il ne s'agit pas de chercher un morceau. Il s'agit d'une copie d'une longueur limité à une position donnée.

    Tu as besoin de l'arithmétique des pointeurs et d'une boucle avec un if.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Points : 321
    Points
    321
    Par défaut
    Effectivement, j'aurais du écrire "prendre le morceau" plutôt que "chercher le morceau", merci ternel.

  15. #15
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,
    Citation Envoyé par melaniedebo Voir le message
    Mais alors quel est l’intérêt de chercher si le morceaux de chaîne existe ?

    Pouvez-vous me montrer un morceau de code, car je piétine sur ce coup.
    Merci
    De façon simple, il vous faut prendre en compte deux choses importantes; la première est la taille des deux chaînes de caractères et la seconde l'offset de départ. Et comme ce que @ternel a dit le but est "de faire la copie d'une longueur limité à une position donnée". Et à la limite, on n'a pas vraiment besoin de boucle, car de mon point de vue tout dépendra de là où l'on modifiera les informations. Donc, vous devez respecter les règles suivantes :
    1. Si la chaîne de caractères à remplacer est plus grande que la chaîne de caractères que l'on va remplacer alors votre fonction se doit de créer une nouvelle chaîne de caractères de taille mémoire suffisamment grande pour appliquer les modifications.
    2. Si la chaîne de caractères a remplacé à une taille inférieure à celle qu'elle remplace, il suffit de remplacer les éléments les unes à la suite des autres, mais avec la contrainte de décaler "\0" en fin de chaîne sinon ce n'est pas une chaîne de caractères.
    3. Et enfin, si les deux chaînes de caractères, on l'a même taillé, on ne fait que remplacer les éléments les unes après les autres.

    Ce qui nous donne le code source ci-dessous.
    Code C : 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    char *f_strsub( char *psrc, char * const psrci,
                   size_t ofst, size_t szi ){
     
        char *p = NULL;
        extern int errno;
        const size_t siz_src = strlen(psrc);
        const size_t siz_srci = strlen(psrci);
        const size_t siz_max = ( siz_src + siz_srci + szi +1);
     
        errno = 0;
        if( szi == siz_srci ){
            if( NULL == (p = strdup(psrc) ))
                return NULL;
            if( 1 == szi )
                *(p+ofst) = *psrci;
            else
                (void)memcpy((p+ofst), psrci, szi);
            return p;
        }
     
        if( NULL == (p = malloc((sizeof *p) *siz_max) ) )
            return NULL;
        (void)memset( p, 0, siz_max );
        (void)memcpy( p, psrc, siz_src );
        (void)memcpy( ( p + ofst ), psrci, siz_srci );
        (void)memcpy( ( p + ofst + siz_srci ),( psrc + ofst + szi),
                     siz_src - szi - ofst + 1 );
        return p;
    }
     
     
    int main( void ){
     
        char *p = NULL;
        char *pp = NULL;
        extern int errno;
     
        if( NULL == (p =strdup("bonjour a tous\0") )){
            (void)fprintf(stderr, "Erreur(%d)\t:%s\n\t%s\n", errno,
                          "Erreur allocation data", strerror(errno));
            return EXIT_FAILURE;
        }
     
        if( NULL == (pp = strdup( "soir\0" ) ) ){
            (void)fprintf(stderr, "Erreur(%d)\t:%s\n\t%s\n", errno,
                          "Erreur allocation data", strerror(errno));
            return EXIT_FAILURE;
        }
     
        (void)fprintf(stderr, "Echo\t:%s\n", p );
     
        p = f_strsub(p, pp, 3, 4 );
        if( NULL == p )
            exit( EXIT_FAILURE );
        fprintf( stdout, "[>>]\t: %s\n", p );
     
     
        free( p);
        free( pp );
        p = NULL;
        pp = NULL;
     
        return EXIT_SUCCESS;
    }
    à bientôt.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. Réponses: 17
    Dernier message: 16/07/2012, 15h10
  2. Réponses: 1
    Dernier message: 27/03/2012, 18h14
  3. Réponses: 17
    Dernier message: 09/03/2011, 12h14
  4. Réponses: 12
    Dernier message: 09/11/2009, 20h56
  5. Réponses: 3
    Dernier message: 08/04/2008, 21h50

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