C'deki bir dizeden bir alt dizeyi değiştirmenin işlevi nedir?


97

Bir ( char *) dizesi verildiğinde , bir alt dizenin tüm oluşumlarını bulmak ve bunları alternatif bir dizeyle değiştirmek istiyorum. Bunu başaran herhangi bir basit işlev görmüyorum <string.h>.


4
bunu değişken bir şekilde yapabileceğinizden şüpheliyim
user44511

Yanıtlar:


90

Optimize edici, yerel değişkenlerin çoğunu ortadan kaldırmalıdır. Tmp işaretçisi, strcpy'nin boş değeri bulmak için dizgeyi yürütmek zorunda olmadığından emin olmak için oradadır. tmp, her aramadan sonra sonucun sonunu gösterir. ( Strcpy'nin neden sinir bozucu olabileceği için ressamın algoritması Shlemiel'e bakın .)

// 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: keyfi nesne / dizgi boyutları ve bunların içindeki indeksler size_tyerine kullanın int. Ayrıca, en sonunda amacı strcpy(tmp, orig);nedir? Yanlış görünüyor.
Alexey Frunze

@Alex, son strcpy (tmp, orig) dizenin son kısmını hedefe kopyalar. Örneğin: döngünün sonunda ("abab", "a", "c") 'yi değiştirin, sonuç, "cbc" yi içerir ve orig, "abab" içindeki son "b" yi gösterir. Son strcpy "b" yi ekler, böylece döndürülen dizge "cbcb" olur. Kopyalanacak hiçbir şey kalmadıysa, orijinal, giriş dizesinin ASCIIZ'ına işaret etmelidir.
jmucchiello

basitleştirme: ilk fordöngüyü ile değiştirebilirsiniz for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, daha sonra tmpsadece yazmak için kullanılır.
rampa

1
char * tamamlandı = replace ("abcdefghijkl", "bc", "yz"); şeyler yapmak(); ücretsiz (tamamlandı);
jmucchiello

2
Değiştirilecek olay yoksa bu işlevin NULL döndürdüğü konusunda uyarılmalıdır (if (! (İns = strstr (orig, rep))) NULL döndürür;). Çıktıyı sadece kullanamazsınız, çıktının NULL olup olmadığını kontrol etmeniz ve eğer öyleyse orijinal dizeyi kullanmanız gerekir (sadece göstericiyi sonuç dizesine kopyalamayın çünkü free (sonuç) orijinal dizeyi serbest bırakır). Değiştirilecek bir şey yoksa, girdi dizesi çıktı dizgisine kopyalanırsa kullanım daha basittir.
Adversus

18

Bu, standart C kitaplığında sağlanmaz, çünkü yalnızca bir char * verildiğinde, yerine geçen dize değiştirilen dizeden daha uzunsa dizeye ayrılan belleği arttıramazsınız.

Bunu std :: string kullanarak daha kolay yapabilirsiniz, ancak orada bile tek bir işlev sizin için bunu yapmaz.


13
Bu soru C ile ilgili, C ++ ile değil.
Geremia

1 / strlen (char *) + 1, depolama boyutuna eşit olmak zorunda değildir. 2 / Dize işlevlerinin çok sayıda N sürümü ve ek tampon boyutu parametresi vardır, dolayısıyla bir snreplace () olamaması için hiçbir neden yoktur. 3 / yerinde değiştirme ve yerinde olmayan değiştirme işlevi olabilir. 4 / Sprintf'in nasıl çalıştığını düşünüyorsunuz? Ona bir char * argümanı verildi ve bellek tahsisini artırması gerekmiyor, bu yüzden bir değiştirmenin de işe yaramaması için bir neden yok ... işaretçi ile => snprintf)
Steven Spark

12

Bir tane yok.

Strstr ve strcat veya strcpy gibi bir şey kullanarak kendinizinkini döndürmeniz gerekir .


7
Sık kullanılan işlevlerin hayran koleksiyonları nerede saklanır? Elbette bunun için zaten bir kütüphane var ....
Pacerier

1
strcat()kötü bir öneri.
Iharob Al Asimi

11

Alt dizeleri bulmak için strstr ve parçalar halinde yeni bir tampona kopyalamak için strncpy kullanarak kendi değiştirme işlevinizi oluşturabilirsiniz.

İstediğiniz şey istediğiniz replace_withuzunlukta replacedeğilse, yeni dizgiyi kopyalamak için yeni bir tampon kullanmak muhtemelen en iyisidir.


9

C'deki dizeler dinamik olarak büyüyemediğinden, yer değiştirme genellikle işe yaramayacaktır. Bu nedenle, ikameniz için yeterli alana sahip yeni bir dizge için yer ayırmanız ve ardından orijinalden parçaları ve değiştirmeyi yeni dizeye kopyalamanız gerekir. Parçaları kopyalamak için strncpy kullanırsınız .


Arabellek boyutu dizeden daha büyük olabilir, değiştirilen dizge değiştirilen dizeden daha küçük olabilir ... bu nedenle değiştirme işlemini gerçekleştirmek için bellek ayırmanıza gerek yoktur. (Ayrıca mikrodenetleyicilerde sonsuz hafızanız olmayabilir ve yerinde değiştirme yapmanız gerekebilir. Her şeyi yeni bir arabelleğe kopyalamak herkes için doğru çözüm olmayabilir ...)
Steven Spark

8

İşte bunu yapan bazı örnek kodlar.

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

Çalışıyor, ama biraz hatalı, ama yine de teşekkürler! : D burada çok iyi çalıştığını buldum, coding.debuntu.org/… şerefe! :)
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);
}

3

Repl_str () creativeandcritical.net fonksiyon hızlı ve güvenilirdir. Bu sayfada ayrıca yardımcı işlevler aracılığıyla UTF-8'de kodlananlar da dahil olmak üzere Unicode dizeleri ile kullanılabilen geniş bir dize varyantı olan repl_wcs () bulunur - demo kodu sayfadan bağlanır. Gecikmiş tam açıklama: O sayfanın ve üzerindeki işlevlerin yazarıyım.


3
hızlı ve güvenilir, ancak büyük bir bellek sızıntısı var.
MightyPork

3
Nasıl olabileceğini anlamıyorum. Yalnızca bir malloc vardır ve arayan kişiye artık gerekmediğinde belleği boşaltması talimatı verilir. Daha açık konuşabilir misin?
Laird

@Lairdpos_cache = realloc(pos_cache
PSkocik

@PSkocik İşlev, @MightyPork tarafından yapılan şikayetten bu yana yükseltildi, ancak şimdi pos_cache için ek malloc / realloc olmasına rağmen, free(pos_cache);at işlevinin sonunu engelleyen bir kod yolu göremiyorum .
Laird

@Laird reallocbaşarısız olabilir. Varsa, geri döner NULLve eski işaretçiyi olduğu gibi bırakır. p = realloc(p, x), başarısızlık üzerine, geçerli bir yığın işaretçisi yeniden yazacak pile NULLve eğer po yığın nesneye tek referans oldu, şimdi sızdı ettik. Klasik bir acemi hatası.
PSkocik

3

Önerilen işlevlerin çoğunu anlamakta zorlanıyorum - bu yüzden şunu buldum:

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

çıktı ücretsiz olmalıdır


2

Bu işlevi kullanabilirsiniz (yorumlar nasıl çalıştığını açıklar):

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

1

İşte bu gereksinimlere göre oluşturduğum şey:

  1. Uzun veya daha kısa olmasına bakılmaksızın deseni değiştirin.

  2. Bellek sızıntılarını doğal olarak önlemek için herhangi bir malloc (açık veya örtük) kullanmayın.

  3. Herhangi bir sayıda desen oluşumunu değiştirin.

  4. Arama dizesine eşit bir alt dizeye sahip değiştirme dizesini tolere edin.

  5. Line dizisinin yedeği tutmak için yeterli boyutta olup olmadığını kontrol etmek zorunda değildir. Örneğin, arayan kişi hattın yeni dizgiyi tutmaya yetecek boyutta olduğunu bilmediği sürece bu çalışmaz.

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

Bu kodu geliştirmek için herhangi bir öneri neşeyle kabul edildi. Sadece yorumu gönder, ben de test edeceğim.


1

İşte benimki, hepsini char * yap, bu da aramayı kolaylaştırıyor ...

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

1

Strrep () kullanabilirsiniz

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

strrep (Dize Değiştir). "Cadena" da "strf" yi "strr" ile değiştirir ve yeni dizeyi döndürür. Strrep'i kullandıktan sonra kodunuzda döndürülen dizeyi serbest bırakmanız gerekir.

Parametreler cadena Metin içeren dize. strf Bulunacak metin. strr Değiştirme metni.

İadeler Değiştirme ile güncellenen metin.

Proje https://github.com/ipserc/strrep adresinde bulunabilir.


0

dizenin yerinde değiştirilmesini kullanan ve satırla gösterilen arabelleğin elde edilen dizgeyi tutacak kadar büyük olduğunu varsayarak fann95'in yanıtına bir düzeltme.

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

0

Gittiğiniz Orada .... bu her durum oluşmasına yerine fonksiyonudur char xile char ykarakter dizesindestr

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

Örnek bir kullanım olabilir

  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.

İşlev, Github'da tuttuğum bir dize kitaplığındandır , mevcut diğer işlevlere bir göz atmanız ve hatta koda katkıda bulunmanızdan memnuniyet duyarız :)

https://github.com/fnoyanisi/zString

DÜZENLEME: @siride doğru, yukarıdaki işlev yalnızca karakterlerin yerine geçer. Karakter dizilerinin yerini alan bunu yazdım.

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

Ve aşağıda çıktı

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'

Bu, alt dizeleri değil, yalnızca tek karakterleri değiştirir.
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;
}

str boş olduğunda segfault
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;
}

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

0

Bu işlev yalnızca ur dizesinde yeni uzunluk için fazladan boşluk varsa çalışır

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

Bu yalnızca İlk oluşumun yerini alır


0

İşte benimki, kendi kendine yeten ve çok yönlü, aynı zamanda verimli, her özyinelemede ihtiyaç duyulduğunda tamponları büyütür veya küçültür

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

0

Yalnızca string.h dosyasından strlen kullanarak

İngilizcem için üzgünüm

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

strlen kodunun string.h çağrısından kaçınmasını istiyorsanız

int strlen(char * string){//use this code to avoid calling string.h
    int lenght = 0;
    while(string[lenght] != '\0'){
        lenght++;
    }
    return lenght;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.