Quelle est la fonction de remplacer une sous-chaîne d'une chaîne en C?

94

Étant donné une char *chaîne ( ), je veux trouver toutes les occurrences d'une sous-chaîne et les remplacer par une chaîne alternative. Je ne vois aucune fonction simple qui permette d'y parvenir <string.h>.

RobertS soutient Monica Cellio
la source
4
Je doute que vous puissiez le faire de manière mutable
user44511

Réponses:

87

L'optimiseur doit éliminer la plupart des variables locales. Le pointeur tmp est là pour s'assurer que strcpy n'a pas à parcourir la chaîne pour trouver le null. tmp pointe vers la fin du résultat après chaque appel. (Voir l'algorithme de Shlemiel le peintre pour savoir pourquoi strcpy peut être ennuyeux.)

// You must free the result if result is non-NULL.
char *str_replace(char *orig, char *rep, char *with) {
    char *result; // the return string
    char *ins;    // the next insert point
    char *tmp;    // varies
    int len_rep;  // length of rep (the string to remove)
    int len_with; // length of with (the string to replace rep with)
    int len_front; // distance between rep and end of last rep
    int count;    // number of replacements

    // sanity checks and initialization
    if (!orig || !rep)
        return NULL;
    len_rep = strlen(rep);
    if (len_rep == 0)
        return NULL; // empty rep causes infinite loop during count
    if (!with)
        with = "";
    len_with = strlen(with);

    // count the number of replacements needed
    ins = orig;
    for (count = 0; tmp = strstr(ins, rep); ++count) {
        ins = tmp + len_rep;
    }

    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);

    if (!result)
        return NULL;

    // first time through the loop, all the variable are set correctly
    // from here on,
    //    tmp points to the end of the result string
    //    ins points to the next occurrence of rep in orig
    //    orig points to the remainder of orig after "end of rep"
    while (count--) {
        ins = strstr(orig, rep);
        len_front = ins - orig;
        tmp = strncpy(tmp, orig, len_front) + len_front;
        tmp = strcpy(tmp, with) + len_with;
        orig += len_front + len_rep; // move to next "end of rep"
    }
    strcpy(tmp, orig);
    return result;
}
jmucchiello
la source
@jmucchiello: utilisez à la size_tplace de intpour des tailles et des index arbitraires d'objets / chaînes. Aussi, quel est le but strcpy(tmp, orig);à la toute fin? Cela semble faux.
Alexey Frunze
@Alex, le dernier strcpy (tmp, orig) copie la dernière partie de la chaîne vers la destination. Ex: replace ("abab", "a", "c") à la fin de la boucle, result contient, "cbc" et orig pointe vers le dernier "b" de "abab". Le dernier strcpy ajoute le "b" de sorte que la chaîne renvoyée soit "cbcb". S'il n'y a plus rien à copier, orig doit pointer vers l'ASCIIZ de la chaîne d'entrée.
jmucchiello
simplification: vous pouvez remplacer cette première forboucle par for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, puis tmpn'est utilisée que pour l'écriture.
rampion
1
char * done = replace ("abcdefghijkl", "bc", "yz"); faire des trucs(); gratuit (fait);
jmucchiello
2
Soyez averti que cette fonction renvoie NULL s'il n'y a pas d'occurrences à remplacer (if (! (Ins = strstr (orig, rep))) return NULL;). Vous ne pouvez pas simplement utiliser la sortie, vous devez vérifier si la sortie est NULL et si tel est le cas, utilisez la chaîne d'origine (ne copiez pas simplement le pointeur vers la chaîne de résultat car free (result) libère alors la chaîne d'origine). L'utilisation est plus simple si la chaîne d'entrée est simplement copiée dans la chaîne de sortie s'il n'y a rien à remplacer.
Adversus
18

Ceci n'est pas fourni dans la bibliothèque C standard car, avec seulement un char *, vous ne pouvez pas augmenter la mémoire allouée à la chaîne si la chaîne de remplacement est plus longue que la chaîne remplacée.

Vous pouvez le faire en utilisant std :: string plus facilement, mais même là, aucune fonction ne le fera à votre place.

Don Neufeld
la source
12
Cette question concerne C, pas C ++.
Geremia
1 / strlen (char *) + 1 n'est pas nécessairement égal à la taille de stockage. 2 / Il y a beaucoup de N versions de fonctions string qui reçoivent un paramètre supplémentaire de taille de tampon donc il n'y a aucune raison pour laquelle il n'y aurait pas de snreplace (). 3 / il pourrait y avoir une fonction de remplacement sur place et non de remplacement sur place. 4 / Comment penses-tu que Sprintf fonctionne? On lui donne un argument char * et il n'est pas nécessaire d'augmenter l'allocation de mémoire de celui-ci, donc aucune raison pour qu'un remplacement ne puisse pas fonctionner aussi ... (bien que C ait une mauvaise conception de «chaîne», et la taille du tampon devrait toujours être passée avec le pointeur => snprintf)
Steven Spark
12

Il n'y en a pas.

Vous devez créer le vôtre en utilisant quelque chose comme strstr et strcat ou strcpy.

Reed Copsey
la source
7
Où sont stockées les collections de fans de fonctions souvent utilisées? Il y a sûrement déjà une bibliothèque pour cela ....
Pacerier
1
strcat()est une mauvaise suggestion.
Iharob Al Asimi
11

Vous pouvez créer votre propre fonction de remplacement en utilisant strstr pour trouver les sous-chaînes et strncpy pour copier en parties dans un nouveau tampon.

À moins que ce que vous voulez replace_withsoit de la même longueur que ce que vous voulez replace, il est probablement préférable d'utiliser un nouveau tampon pour copier la nouvelle chaîne.

Brian R. Bondy
la source
9

Comme les chaînes en C ne peuvent pas se développer dynamiquement, la substitution en place ne fonctionnera généralement pas. Par conséquent, vous devez allouer de l'espace pour une nouvelle chaîne qui a suffisamment de place pour votre substitution, puis copier les parties de l'original plus la substitution dans la nouvelle chaîne. Pour copier les parties, vous utiliseriez strncpy .

Lothar
la source
La taille de la mémoire tampon peut être plus grande que la strlen, la chaîne de remplacement peut être plus petite que la chaîne remplacée ... vous n'avez donc pas besoin d'allouer de la mémoire pour effectuer le remplacement. (Également sur les microcontrôleurs, vous n'aurez peut-être pas une mémoire infinie et vous devrez peut-être effectuer un remplacement sur place. Copier tout dans un nouveau tampon n'est peut-être pas la bonne solution pour tout le monde ...)
Steven Spark
8

Voici un exemple de code qui le fait.

#include <string.h>
#include <stdlib.h>

char * replace(
    char const * const original, 
    char const * const pattern, 
    char const * const replacement
) {
  size_t const replen = strlen(replacement);
  size_t const patlen = strlen(pattern);
  size_t const orilen = strlen(original);

  size_t patcnt = 0;
  const char * oriptr;
  const char * patloc;

  // find how many times the pattern occurs in the original string
  for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
  {
    patcnt++;
  }

  {
    // allocate memory for the new string
    size_t const retlen = orilen + patcnt * (replen - patlen);
    char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );

    if (returned != NULL)
    {
      // copy the original string, 
      // replacing all the instances of the pattern
      char * retptr = returned;
      for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
      {
        size_t const skplen = patloc - oriptr;
        // copy the section until the occurence of the pattern
        strncpy(retptr, oriptr, skplen);
        retptr += skplen;
        // copy the replacement 
        strncpy(retptr, replacement, replen);
        retptr += replen;
      }
      // copy the rest of the string.
      strcpy(retptr, oriptr);
    }
    return returned;
  }
}

#include <stdio.h>
int main(int argc, char * argv[])
{
  if (argc != 4)
  {
    fprintf(stderr,"usage: %s <original text> <pattern> <replacement>\n", argv[0]);
    exit(-1);
  }
  else
  {
    char * const newstr = replace(argv[1], argv[2], argv[3]);
    if (newstr)
    {
      printf("%s\n", newstr);
      free(newstr);
    }
    else
    {
      fprintf(stderr,"allocation error\n");
      exit(-2);
    }
  }
  return 0;
}
rampion
la source
Cela fonctionne, mais c'est un peu bogué, mais merci quand même! : D en voici un que j'ai trouvé qui fonctionne très bien, coding.debuntu.org/ ... bravo ! :)
Joe DF
4
// Here is the code for unicode strings!


int mystrstr(wchar_t *txt1,wchar_t *txt2)
{
    wchar_t *posstr=wcsstr(txt1,txt2);
    if(posstr!=NULL)
    {
        return (posstr-txt1);
    }else
    {
        return -1;
    }
}

// assume: supplied buff is enough to hold generated text
void StringReplace(wchar_t *buff,wchar_t *txt1,wchar_t *txt2)
{
    wchar_t *tmp;
    wchar_t *nextStr;
    int pos;

    tmp=wcsdup(buff);

    pos=mystrstr(tmp,txt1);
    if(pos!=-1)
    {
        buff[0]=0;
        wcsncpy(buff,tmp,pos);
        buff[pos]=0;

        wcscat(buff,txt2);

        nextStr=tmp+pos+wcslen(txt1);

        while(wcslen(nextStr)!=0)
        {
            pos=mystrstr(nextStr,txt1);

            if(pos==-1)
            {
                wcscat(buff,nextStr);
                break;
            }

            wcsncat(buff,nextStr,pos);
            wcscat(buff,txt2);

            nextStr=nextStr+pos+wcslen(txt1);   
        }
    }

    free(tmp);
}
Ruchira Hasaranga
la source
3

La fonction repl_str () sur creativeandcritical.net est rapide et fiable. Cette page contient également une variante de chaîne large, repl_wcs () , qui peut être utilisée avec des chaînes Unicode, y compris celles encodées en UTF-8, via des fonctions d'assistance - le code de démonstration est lié à partir de la page. Divulgation complète tardive: je suis l'auteur de cette page et des fonctions qu'elle contient.

Laird
la source
3
rapide et fiable, mais a une énorme fuite de mémoire.
MightyPork
3
Je ne vois pas comment cela pourrait. Il n'y a qu'un seul malloc et l'appelant est invité à libérer la mémoire lorsqu'elle n'est plus nécessaire. Pourriez-vous être plus précis?
Laird
@Lairdpos_cache = realloc(pos_cache
PSkocik
@PSkocik La fonction a été mise à jour depuis la plainte de @MightyPork mais même si elle a maintenant ce malloc / realloc supplémentaire pour pos_cache, je ne vois pas de chemin de code qui évite la free(pos_cache);fin de la fonction at.
Laird le
@Laird reallocpeut échouer. Si c'est le cas, il retourne NULLet laisse l'ancien pointeur intact. p = realloc(p, x)va, en cas d'échec, réécrire un pointeur de tas valide pavec NULL, et si pc'était votre seule référence à cet objet de tas, vous l'avez maintenant divulgué. C'est une erreur de débutant classique.
PSkocik
3

Je trouve que la plupart des fonctions proposées sont difficiles à comprendre - alors j'ai trouvé ceci:

static char *dull_replace(const char *in, const char *pattern, const char *by)
{
    size_t outsize = strlen(in) + 1;
    // TODO maybe avoid reallocing by counting the non-overlapping occurences of pattern
    char *res = malloc(outsize);
    // use this to iterate over the output
    size_t resoffset = 0;

    char *needle;
    while (needle = strstr(in, pattern)) {
        // copy everything up to the pattern
        memcpy(res + resoffset, in, needle - in);
        resoffset += needle - in;

        // skip the pattern in the input-string
        in = needle + strlen(pattern);

        // adjust space for replacement
        outsize = outsize - strlen(pattern) + strlen(by);
        res = realloc(res, outsize);

        // copy the pattern
        memcpy(res + resoffset, by, strlen(by));
        resoffset += strlen(by);
    }

    // copy the remaining input
    strcpy(res + resoffset, in);

    return res;
}

la sortie doit être libre

yogo1212
la source
2

Vous pouvez utiliser cette fonction (les commentaires expliquent comment cela fonctionne):

void strreplace(char *string, const char *find, const char *replaceWith){
    if(strstr(string, replaceWith) != NULL){
        char *temporaryString = malloc(strlen(strstr(string, find) + strlen(find)) + 1);
        strcpy(temporaryString, strstr(string, find) + strlen(find));    //Create a string with what's after the replaced part
        *strstr(string, find) = '\0';    //Take away the part to replace and the part after it in the initial string
        strcat(string, replaceWith);    //Concat the first part of the string with the part to replace with
        strcat(string, temporaryString);    //Concat the first part of the string with the part after the replaced part
        free(temporaryString);    //Free the memory to avoid memory leaks
    }
}
Donald Duck
la source
1

Voici celui que j'ai créé en fonction de ces exigences:

  1. Remplacez le motif, qu'il soit long ou court.

  2. N'utilisez aucun malloc (explicite ou implicite) pour éviter intrinsèquement les fuites de mémoire.

  3. Remplacez n'importe quel nombre d'occurrences de motif.

  4. Tolérez la chaîne de remplacement ayant une sous-chaîne égale à la chaîne de recherche.

  5. Il n'est pas nécessaire de vérifier que le Line array est de taille suffisante pour contenir le remplacement. Par exemple, cela ne fonctionne que si l'appelant sait que la ligne est de taille suffisante pour contenir la nouvelle chaîne.

/* returns number of strings replaced.
*/
int replacestr(char *line, const char *search, const char *replace)
{
   int count;
   char *sp; // start of pattern

   //printf("replacestr(%s, %s, %s)\n", line, search, replace);
   if ((sp = strstr(line, search)) == NULL) {
      return(0);
   }
   count = 1;
   int sLen = strlen(search);
   int rLen = strlen(replace);
   if (sLen > rLen) {
      // move from right to left
      char *src = sp + sLen;
      char *dst = sp + rLen;
      while((*dst = *src) != '\0') { dst++; src++; }
   } else if (sLen < rLen) {
      // move from left to right
      int tLen = strlen(sp) - sLen;
      char *stop = sp + rLen;
      char *src = sp + sLen + tLen;
      char *dst = sp + rLen + tLen;
      while(dst >= stop) { *dst = *src; dst--; src--; }
   }
   memcpy(sp, replace, rLen);

   count += replacestr(sp + rLen, search, replace);

   return(count);
}

Toutes les suggestions pour améliorer ce code sont acceptées avec joie. Postez simplement le commentaire et je vais le tester.

si NewQuestion voteCLOSE
la source
1

Vous pouvez utiliser strrep ()

char * strrep (const char * cadena, const char * strf, const char * strr)

strrep (remplacement de chaîne). Remplace «strf» par «strr» dans «cadena» et renvoie la nouvelle chaîne. Vous devez libérer la chaîne retournée dans votre code après avoir utilisé strrep.

Paramètres cadena La chaîne avec le texte. strf Le texte à rechercher. strr Le texte de remplacement.

Renvoie Le texte mis à jour avec le remplacement.

Le projet peut être trouvé à https://github.com/ipserc/strrep

ipserc
la source
0

un correctif à la réponse de fann95, en utilisant la modification sur place de la chaîne, et en supposant que le tampon pointé par la ligne est suffisamment grand pour contenir la chaîne résultante.

static void replacestr(char *line, const char *search, const char *replace)
{
     char *sp;

     if ((sp = strstr(line, search)) == NULL) {
         return;
     }
     int search_len = strlen(search);
     int replace_len = strlen(replace);
     int tail_len = strlen(sp+search_len);

     memmove(sp+replace_len,sp+search_len,tail_len+1);
     memcpy(sp, replace, replace_len);
}
Byron
la source
0

Voilà ... c'est la fonction pour remplacer chaque occurrence de char xavec une char ychaîne de caractèresstr

char *zStrrep(char *str, char x, char y){
    char *tmp=str;
    while(*tmp)
        if(*tmp == x)
            *tmp++ = y; /* assign first, then incement */
        else
            *tmp++;

    *tmp='\0';
    return str;
}

Un exemple d'utilisation pourrait être

  Exmaple Usage
        char s[]="this is a trial string to test the function.";
        char x=' ', y='_';
        printf("%s\n",zStrrep(s,x,y));

  Example Output
        this_is_a_trial_string_to_test_the_function.

La fonction provient d'une bibliothèque de chaînes que je maintiens sur Github , vous êtes plus que bienvenu pour jeter un coup d'œil aux autres fonctions disponibles ou même contribuer au code :)

https://github.com/fnoyanisi/zString

EDIT: @siride a raison, la fonction ci-dessus ne remplace que les caractères. Je viens d'écrire celui-ci, qui remplace les chaînes de caractères.

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

/* replace every occurance of string x with string y */
char *zstring_replace_str(char *str, const char *x, const char *y){
    char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
    int len_str=0, len_y=0, len_x=0;

    /* string length */
    for(; *tmp_y; ++len_y, ++tmp_y)
        ;

    for(; *tmp_str; ++len_str, ++tmp_str)
        ;

    for(; *tmp_x; ++len_x, ++tmp_x)
        ;

    /* Bounds check */
    if (len_y >= len_str)
        return str;

    /* reset tmp pointers */
    tmp_y = y;
    tmp_x = x;

    for (tmp_str = str ; *tmp_str; ++tmp_str)
        if(*tmp_str == *tmp_x) {
            /* save tmp_str */
            for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
                if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
                /* Reached end of x, we got something to replace then!
                * Copy y only if there is enough room for it
                */
                    for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
                        *tmp_str = *tmp_y;
            }
        /* reset tmp_x */
        tmp_x = x;
        }

    return str;
}

int main()
{
    char s[]="Free software is a matter of liberty, not price.\n"
             "To understand the concept, you should think of 'free' \n"
             "as in 'free speech', not as in 'free beer'";

    printf("%s\n\n",s);
    printf("%s\n",zstring_replace_str(s,"ree","XYZ"));
    return 0;
}

Et ci-dessous est la sortie

Free software is a matter of liberty, not price.
To understand the concept, you should think of 'free' 
as in 'free speech', not as in 'free beer'

FXYZ software is a matter of liberty, not price.
To understand the concept, you should think of 'fXYZ' 
as in 'fXYZ speech', not as in 'fXYZ beer'
fnisi
la source
Cela ne remplace que les caractères uniques, pas les sous-chaînes.
siride
0
/*замена символа в строке*/
char* replace_char(char* str, char in, char out) {
    char * p = str;

    while(p != '\0') {
        if(*p == in)
            *p == out;
        ++p;
    }

    return str;
}
qwerty ytrewq
la source
segfault lorsque str est nul
Code_So1dier
0
DWORD ReplaceString(__inout PCHAR source, __in DWORD dwSourceLen, __in const char* pszTextToReplace, __in const char* pszReplaceWith)
{
    DWORD dwRC = NO_ERROR;
    PCHAR foundSeq = NULL;
    PCHAR restOfString = NULL;
    PCHAR searchStart = source;
    size_t szReplStrcLen = strlen(pszReplaceWith), szRestOfStringLen = 0, sztextToReplaceLen = strlen(pszTextToReplace), remainingSpace = 0, dwSpaceRequired = 0;
    if (strcmp(pszTextToReplace, "") == 0)
        dwRC = ERROR_INVALID_PARAMETER;
    else if (strcmp(pszTextToReplace, pszReplaceWith) != 0)
    {
        do
        {
            foundSeq = strstr(searchStart, pszTextToReplace);
            if (foundSeq)
            {
                szRestOfStringLen = (strlen(foundSeq) - sztextToReplaceLen) + 1;
                remainingSpace = dwSourceLen - (foundSeq - source);
                dwSpaceRequired = szReplStrcLen + (szRestOfStringLen);
                if (dwSpaceRequired > remainingSpace)
                {
                    dwRC = ERROR_MORE_DATA;
                }

                else
                {
                    restOfString = CMNUTIL_calloc(szRestOfStringLen, sizeof(CHAR));
                    strcpy_s(restOfString, szRestOfStringLen, foundSeq + sztextToReplaceLen);

                    strcpy_s(foundSeq, remainingSpace, pszReplaceWith);
                    strcat_s(foundSeq, remainingSpace, restOfString);
                }

                CMNUTIL_free(restOfString);
                searchStart = foundSeq + szReplStrcLen; //search in the remaining str. (avoid loops when replWith contains textToRepl 
            }
        } while (foundSeq && dwRC == NO_ERROR);
    }
    return dwRC;
}
Andy Mazanec
la source
0
char *replace(const char*instring, const char *old_part, const char *new_part)
{

#ifndef EXPECTED_REPLACEMENTS
    #define EXPECTED_REPLACEMENTS 100
#endif

    if(!instring || !old_part || !new_part)
    {
        return (char*)NULL;
    }

    size_t instring_len=strlen(instring);
    size_t new_len=strlen(new_part);
    size_t old_len=strlen(old_part);
    if(instring_len<old_len || old_len==0)
    {
        return (char*)NULL;
    }

    const char *in=instring;
    const char *found=NULL;
    size_t count=0;
    size_t out=0;
    size_t ax=0;
    char *outstring=NULL;

    if(new_len> old_len )
    {
        size_t Diff=EXPECTED_REPLACEMENTS*(new_len-old_len);
        size_t outstring_len=instring_len + Diff;
        outstring =(char*) malloc(outstring_len); 
        if(!outstring){
            return (char*)NULL;
        }
        while((found = strstr(in, old_part))!=NULL)
        {
            if(count==EXPECTED_REPLACEMENTS)
            {
                outstring_len+=Diff;
                if((outstring=realloc(outstring,outstring_len))==NULL)
                {
                     return (char*)NULL;
                }
                count=0;
            }
            ax=found-in;
            strncpy(outstring+out,in,ax);
            out+=ax;
            strncpy(outstring+out,new_part,new_len);
            out+=new_len;
            in=found+old_len;
            count++;
        }
    }
    else
    {
        outstring =(char*) malloc(instring_len);
        if(!outstring){
            return (char*)NULL;
        }
        while((found = strstr(in, old_part))!=NULL)
        {
            ax=found-in;
            strncpy(outstring+out,in,ax);
            out+=ax;
            strncpy(outstring+out,new_part,new_len);
            out+=new_len;
            in=found+old_len;
        }
    }
    ax=(instring+instring_len)-in;
    strncpy(outstring+out,in,ax);
    out+=ax;
    outstring[out]='\0';

    return outstring;
}
fann95
la source
0

Cette fonction ne fonctionne que si votre chaîne a un espace supplémentaire pour la nouvelle longueur

void replace_str(char *str,char *org,char *rep)
{
    char *ToRep = strstr(str,org);
    char *Rest = (char*)malloc(strlen(ToRep));
    strcpy(Rest,((ToRep)+strlen(org)));

    strcpy(ToRep,rep);
    strcat(ToRep,Rest);

    free(Rest);
}

Cela remplace uniquement la première occurrence

personne
la source
0

Voici le mien, il est autonome et polyvalent, ainsi qu'efficace, il augmente ou réduit les tampons au besoin à chaque récursivité

void strreplace(char *src, char *str, char *rep)
{
    char *p = strstr(src, str);
    if (p)
    {
        int len = strlen(src)+strlen(rep)-strlen(str);
        char r[len];
        memset(r, 0, len);
        if ( p >= src ){
            strncpy(r, src, p-src);
            r[p-src]='\0';
            strncat(r, rep, strlen(rep));
            strncat(r, p+strlen(str), p+strlen(str)-src+strlen(src));
            strcpy(src, r);
            strreplace(p+strlen(rep), str, rep);
        }
    }
}
Daniel J.
la source
0

Voici le mien, faites-les tous char *, ce qui facilite les appels ...

char *strrpc(char *str,char *oldstr,char *newstr){
    char bstr[strlen(str)];
    memset(bstr,0,sizeof(bstr));
    int i;
    for(i = 0;i < strlen(str);i++){
        if(!strncmp(str+i,oldstr,strlen(oldstr))){
            strcat(bstr,newstr);
            i += strlen(oldstr) - 1;
        }else{
                strncat(bstr,str + i,1);
            }
    }

    strcpy(str,bstr);
    return str;
}
LinconFive
la source
0

Utiliser uniquement strlen de string.h

Désolé pour mon anglais

char * str_replace(char * text,char * rep, char * repw){//text -> to replace in it | rep -> replace | repw -> replace with
    int replen = strlen(rep),repwlen = strlen(repw),count;//some constant variables
    for(int i=0;i<strlen(text);i++){//search for the first character from rep in text
        if(text[i] == rep[0]){//if it found it
            count = 1;//start searching from the next character to avoid repetition
            for(int j=1;j<replen;j++){
                if(text[i+j] == rep[j]){//see if the next character in text is the same as the next in the rep if not break
                    count++;
                }else{
                    break;
                }
            }
            if(count == replen){//if count equals to the lenght of the rep then we found the word that we want to replace in the text
                if(replen < repwlen){
                    for(int l = strlen(text);l>i;l--){//cuz repwlen greater than replen we need to shift characters to the right to make space for the replacement to fit
                        text[l+repwlen-replen] = text[l];//shift by repwlen-replen
                    }
                }
                if(replen > repwlen){
                    for(int l=i+replen-repwlen;l<strlen(text);l++){//cuz replen greater than repwlen we need to shift the characters to the left
                        text[l-(replen-repwlen)] = text[l];//shift by replen-repwlen
                    }
                    text[strlen(text)-(replen-repwlen)] = '\0';//get rid of the last unwanted characters
                }
                for(int l=0;l<repwlen;l++){//replace rep with repwlen
                    text[i+l] = repw[l];
                }
                if(replen != repwlen){
                    i+=repwlen-1;//pass to the next character | try text "y" ,rep "y",repw "yy" without this line to understand
                }
            }
        }
    }
    return text;
}

si vous voulez que le code strlen évite d'appeler string.h

int strlen(char * string){//use this code to avoid calling string.h
    int lenght = 0;
    while(string[lenght] != '\0'){
        lenght++;
    }
    return lenght;
}
Salmy
la source