¿Qué función es reemplazar una subcadena de una cadena en C?

94

Dada una char *cadena ( ), quiero encontrar todas las apariciones de una subcadena y reemplazarlas con una cadena alternativa. No veo ninguna función simple que logre esto en <string.h>.

RobertS apoya a Monica Cellio
fuente
4
Dudo que puedas hacer esto de una manera mutable
user44511

Respuestas:

87

El optimizador debería eliminar la mayoría de las variables locales. El puntero tmp está ahí para asegurarse de que strcpy no tenga que recorrer la cadena para encontrar el nulo. tmp apunta al final del resultado después de cada llamada. (Consulte el algoritmo del pintor de Shlemiel para saber por qué strcpy puede ser molesto).

// 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
fuente
@jmucchiello: se usa en size_tlugar de intpara objetos arbitrarios / tamaños de cadena e índices en ellos. Además, ¿cuál es el propósito strcpy(tmp, orig);al final? Parece mal.
Alexey Frunze
@Alex, la última strcpy (tmp, orig) copia la última parte de la cadena en el destino. Por ejemplo: reemplace ("abab", "a", "c") al final del ciclo, el resultado contiene, "cbc" y orig apunta a la última "b" en "abab". La última strcpy agrega la "b" por lo que la cadena devuelta es "cbcb". Si no queda nada para copiar, orig debería apuntar al ASCIIZ de la cadena de entrada.
jmucchiello
simplificación: puede reemplazar ese primer forbucle con for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, luego tmpsolo se usa para escribir.
rampion
1
char * done = replace ("abcdefghijkl", "bc", "yz"); hacer cosas(); gratis (hecho);
jmucchiello
2
Tenga en cuenta que esta función devuelve NULL si no hay ocurrencias para reemplazar (if (! (Ins = strstr (orig, rep))) return NULL;). No puede simplemente usar la salida, debe verificar si la salida es NULL y, si es así, use la cadena original (no solo copie el puntero a la cadena de resultado porque free (resultado) libera la cadena original). El uso es más sencillo si la cadena de entrada solo se copia en la cadena de salida si no hay nada que reemplazar.
Adversus
18

Esto no se proporciona en la biblioteca C estándar porque, dado solo un carácter *, no puede aumentar la memoria asignada a la cadena si la cadena de reemplazo es más larga que la cadena que se reemplaza.

Puede hacer esto usando std :: string más fácilmente, pero incluso allí, ninguna función lo hará por usted.

Don Neufeld
fuente
12
Esta pregunta es sobre C, no sobre C ++.
Geremia
1 / strlen (char *) + 1 no es necesariamente igual al tamaño de almacenamiento. 2 / Hay muchas N versiones de funciones de cadena que reciben un parámetro de tamaño de búfer adicional, por lo que no hay ninguna razón por la que no pueda haber un snreplace (). 3 / podría haber una función de reemplazo in situ y no una función de reemplazo in situ. 4 / ¿cómo crees que funciona sprintf? Se le da un argumento char * y no es necesario aumentar la asignación de memoria, por lo que no hay razón para que un reemplazo no funcione también ... (aunque C tiene un mal diseño de "cadena" y el tamaño del búfer siempre debe pasarse con el puntero => snprintf)
Steven Spark
12

No hay uno.

Necesitarías rodar el tuyo usando algo como strstr y strcat o strcpy.

Reed Copsey
fuente
7
¿Dónde se almacenan las colecciones de ventiladores de funciones de uso frecuente? Seguramente ya hay una biblioteca para ello ....
Pacerier
1
strcat()es una mala sugerencia.
Iharob Al Asimi
11

Puede crear su propia función de reemplazo usando strstr para encontrar las subcadenas y strncpy para copiar en partes a un nuevo búfer.

A menos que lo que desee replace_withtenga la misma longitud que lo que desea replace, probablemente sea mejor usar un nuevo búfer para copiar la nueva cadena.

Brian R. Bondy
fuente
9

Como las cadenas en C no pueden crecer dinámicamente en el lugar, la sustitución generalmente no funcionará. Por lo tanto, debe asignar espacio para una nueva cadena que tenga suficiente espacio para su sustitución y luego copiar las partes del original más la sustitución en la nueva cadena. Para copiar las partes, usaría strncpy .

Lothar
fuente
El tamaño del búfer podría ser mayor que el strlen, la cadena de reemplazo podría ser más pequeña que la cadena reemplazada ... por lo tanto, no necesita asignar memoria para realizar el reemplazo. (También en los microcontroladores es posible que no tenga memoria infinita, y es posible que deba realizar el reemplazo en su lugar. Copiar todo en un nuevo búfer puede no ser la solución adecuada para todos ...)
Steven Spark
8

Aquí hay un código de muestra que lo hace.

#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
fuente
Funciona, pero tiene un poco de errores, ¡pero gracias de todos modos! : D aquí hay uno que encontré que funciona muy bien, coding.debuntu.org/… ¡ salud ! :)
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
fuente
3

La función repl_str () en creativeandcritical.net es rápida y confiable. También se incluye en esa página una variante de cadena amplia, repl_wcs () , que se puede usar con cadenas Unicode, incluidas las codificadas en UTF-8, a través de funciones auxiliares; el código de demostración está vinculado desde la página. Revelación completa tardía: soy el autor de esa página y las funciones que contiene.

Terrateniente
fuente
3
rápido y confiable, pero tiene una gran pérdida de memoria.
MightyPork
3
No veo cómo podría hacerlo. Solo hay un malloc y se le indica a la persona que llama que libere la memoria cuando ya no sea necesaria. ¿Podrías ser más específico?
Laird
@Lairdpos_cache = realloc(pos_cache
PSkocik
@PSkocik La función se ha actualizado desde la queja de @MightyPork, pero aunque ahora tiene ese malloc / realloc adicional para pos_cache, no puedo ver una ruta de código que evite el free(pos_cache);final de la función en.
Laird
@Laird reallocpuede fallar. Si lo hace, vuelve NULLy deja intacto el puntero antiguo. p = realloc(p, x), en caso de falla, reescribirá un puntero de montón válido pcon NULL, y si esa pera su única referencia a ese objeto de montón, ahora lo ha filtrado. Es un error clásico de novato.
PSkocik
3

Encuentro que la mayoría de las funciones propuestas son difíciles de entender, así que se me ocurrió esto:

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 salida debe ser libre

yogo1212
fuente
2

Puede utilizar esta función (los comentarios explican cómo funciona):

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
    }
}
Pato Donald
fuente
1

Aquí está el que creé en base a estos requisitos:

  1. Reemplace el patrón independientemente de si es largo o más corto.

  2. No utilice ningún malloc (explícito o implícito) para evitar intrínsecamente pérdidas de memoria.

  3. Reemplace cualquier número de apariciones de patrón.

  4. Tolere que la cadena de reemplazo tenga una subcadena igual a la cadena de búsqueda.

  5. No es necesario comprobar que el Line array tenga el tamaño suficiente para contener el reemplazo. Por ejemplo, esto no funciona a menos que la persona que llama sepa que la línea tiene el tamaño suficiente para contener la nueva cadena.

/* 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);
}

Cualquier sugerencia para mejorar este código se acepta con gusto. Simplemente publique el comentario y lo probaré.

si vota NewQuestionCLOSE
fuente
1

Puedes usar strrep ()

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

strrep (Reemplazo de cadena). Reemplaza 'strf' con 'strr' en 'cadena' y devuelve la nueva cadena. Debe liberar la cadena devuelta en su código después de usar strrep.

Parámetros cadena La cadena con el texto. strf El texto a buscar. strr El texto de reemplazo.

Devuelve El texto actualizado con el reemplazo.

El proyecto se puede encontrar en https://github.com/ipserc/strrep

ipserc
fuente
0

una solución a la respuesta de fann95, usando la modificación en el lugar de la cadena y asumiendo que el búfer al que apunta la línea es lo suficientemente grande para contener la cadena resultante.

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
fuente
0

Hay que ir .... esta es la función de sustituir cada ocurrencia de char xla char ydentro de la cadena de caracteresstr

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 ejemplo de uso podría ser

  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 función es de una biblioteca de cadenas que mantengo en Github , eres más que bienvenido a echar un vistazo a otras funciones disponibles o incluso contribuir al código :)

https://github.com/fnoyanisi/zString

EDITAR: @siride tiene razón, la función anterior reemplaza solo los caracteres. Acabo de escribir este, que reemplaza las cadenas de caracteres.

#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;
}

Y abajo está la salida

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
fuente
Esto solo reemplaza caracteres individuales, no subcadenas.
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
fuente
segfault cuando str es nulo
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
fuente
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
fuente
0

Esta función solo funciona si tu cadena tiene espacio adicional para una nueva longitud

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);
}

Esto solo reemplaza la primera aparición

Ninguno
fuente
0

Aquí va el mío, es autónomo y versátil, además de eficiente, aumenta o reduce los búferes según sea necesario en cada recursión

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.
fuente
0

Aquí va el mío, hazlos todos char *, lo que facilita las llamadas ...

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
fuente
0

Usando solo strlen de string.h

Lo siento por mi ingles

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 desea un código strlen para evitar llamar a 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
fuente