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 :

Remplacement de sous-chaînes


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 8
    Par défaut Remplacement de sous-chaînes
    Bonjour,

    Je créé en ce moment une fonction qui remplace dans une chaîne donnée toutes les occurences d'une sous-chaîne donnée par une autre chaîne, et qui renvoie le nombre d'occurences remplacées. La taille du buffer est également donnée en paramètre.

    J'aimerais que dans un cas comme celui-là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int n;
    char s[10] = "bonjour";
    n = STRU_replacestr(s, sizeof(s), "bon", "contre");
    s contienne après remplacement "contrejou", avec s[9] contenant '\0', et n valant -1, signifiant que la chaîne a dû être tronquée. C'est cette fonctionnalité que je n'arrive pas à coder.

    Voici le corps de la fonction actuelle :

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    int STRU_replacestr(char *s, size_t size, const char *toreplace, const char *replaceby){
     
    	int count = 0;
     
    	/* Test sécurité + efficacité */
    	if(s && toreplace && replaceby && (s = strstr(s, toreplace))){
     
    		char *p = s;
    		const char *preplace = NULL;
    		size_t toreplacelen = strlen(toreplace);
    		long diff = (long)(strlen(replaceby) - strlen(toreplace));
     
    		while(*p != '\0'){
     
    			/* p est la sous-chaîne recherchée */
    			if(*p == *toreplace && strncmp(p+1, toreplace+1, toreplacelen-1) == 0){
    					/* On place le curseur après la sous-chaîne */
    					p += toreplacelen;
    					/* Si la chaîne de remplacement est plus grande que celle à remplacer,  */
    					/* on décale les caractères pour laisser la place manquante et on place */
    					/* le curseur à la suite de la place libérée                            */
    					if(diff > 0){
    						memmove(p + diff, p, strlen(p)+1);
    						p += diff;
    					}
    					/* Ecriture de la sous-chaîne remplaçante */
    					for(preplace = replaceby; *preplace != '\0'; s++, preplace++){
    						*s = *preplace;
    					}
    					count++;
     
    			/* Ecriture du caractère courant si besoin */
    			} else {
    				if(s != p){
    					*s = *p;
    				}
    				s++, p++;
    			}
     
    		}
    		*s = '\0';
    	}
    	return count;
    }
    Avez-vous des suggestions/solutions pour résoudre mon problème ? Merci par avance...

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par psych0o0
    Je créé en ce moment une fonction qui remplace dans une chaîne donnée toutes les occurences d'une sous-chaîne donnée par une autre chaîne, et qui renvoie le nombre d'occurences remplacées. La taille du buffer est également donnée en paramètre.

    <...>
    Avez-vous des suggestions/solutions pour résoudre mon problème ? Merci par avance...
    Le paramètre 'size' n'étant pas utilisé, je ne suis pas surpris qu'une simple instrumentation (test de débordement de chaine) mettre en évidence précisément un débordement...
    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
    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
     
    #include "ed/inc/sys.h"
     
    #include <string.h>
    #include <stdio.h>
     
    int STRU_replacestr (char *s, size_t size, const char *toreplace,
                         const char *replaceby)
    {
    /* Test sécurité + efficacité */
       int count = 0;
       if (s && toreplace && replaceby && (s = strstr (s, toreplace)))
       {
          char *p = s;
          const char *preplace = NULL;
          size_t toreplacelen = strlen (toreplace);
          long diff = (long) (strlen (replaceby) - strlen (toreplace));
          while (*p != '\0')
    /* p est la sous-chaîne recherchée */
          {
             if (*p == *toreplace
                 && strncmp (p + 1, toreplace + 1, toreplacelen - 1) == 0)
    /* On place le curseur après la sous-chaîne */
             {
                /* Si la chaîne de remplacement est plus grande que celle à remplacer, *//* on décale les caractères pour laisser la place manquante et on place *//* le curseur à la suite de la place libérée */
                p += toreplacelen;
                if (diff > 0)
                {
                   memmove (p + diff, p, strlen (p) + 1);
                   p += diff;
    /* Ecriture de la sous-chaîne remplaçante */
                }
                for (preplace = replaceby; *preplace != '\0'; s++, preplace++)
                {
                   *s = *preplace;
                }
    /* Ecriture du caractère courant si besoin */
                count++;
             }
             else
             {
                if (s != p)
                {
                   *s = *p;
                }
                s++, p++;
             }
          }
          *s = '\0';
       }
       return count;
    }
     
    int main (void)
    {
       int n;
       char s[10] = "bonjour";
     
       LIM_STR (s);
       n = STRU_replacestr (s, sizeof (s), "bon", "contre");
       CHK_STR (s);
     
       printf ("n=%d s='%s'\n", n, s);
       return 0;
    }
    Code manquant sur http://delahaye.emmanuel.free.fr/clib/ed
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SYS: assertion '(s)[sizeof (s) - 1]==0' failed at main.c:60
    SYS: *** EXIT ***
     
    Press ENTER to continue.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 8
    Par défaut
    Effectivement le paramètre size n'est pas utilisé parce que je ne sais pas encore comment l'utiliser

    Je vais regarder ton lien, merci !

Discussions similaires

  1. [RegExp] remplacement de sous-chaîne
    Par Pandi_Panda dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 28/06/2012, 09h47
  2. [RegEx] Détection et remplacement automatique de sous-chaînes
    Par Rolf-IV dans le forum Langage
    Réponses: 2
    Dernier message: 10/09/2009, 17h01
  3. Réponses: 10
    Dernier message: 14/07/2008, 20h40
  4. Remplacer sous-chaîne à partir d'une table
    Par stefposs dans le forum Access
    Réponses: 4
    Dernier message: 11/04/2008, 11h24
  5. Remplacer une sous chaîne par une autre
    Par Erakis dans le forum Général JavaScript
    Réponses: 15
    Dernier message: 10/11/2006, 09h16

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