Chức năng nào là thay thế một chuỗi con từ một chuỗi trong C?


94

Cho một char *chuỗi ( ), tôi muốn tìm tất cả các lần xuất hiện của một chuỗi con và thay thế chúng bằng một chuỗi thay thế. Tôi không thấy bất kỳ chức năng đơn giản nào đạt được điều này trong <string.h>.


4
tôi nghi ngờ bạn có thể làm điều này trong một thời trang có thể thay đổi
user44511

Câu trả lời:


87

Trình tối ưu hóa sẽ loại bỏ hầu hết các biến cục bộ. Con trỏ tmp ở đó để đảm bảo strcpy không phải đi bộ chuỗi để tìm giá trị rỗng. tmp trỏ đến cuối kết quả sau mỗi cuộc gọi. (Xem Shlemiel thuật toán của họa sĩ để biết tại sao strcpy có thể gây phiền nhiễu.)

// 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: sử dụng size_tthay vì intcho các kích thước và chỉ số đối tượng / chuỗi tùy ý vào chúng. Ngoài ra, mục đích strcpy(tmp, orig);cuối cùng là gì? Nó có vẻ sai.
Alexey Frunze

@Alex, strcpy cuối cùng (tmp, orig) sao chép phần cuối cùng của chuỗi tới đích. Ví dụ: thay thế ("abab", "a", "c") ở cuối vòng lặp, kết quả chứa, "cbc" và orig trỏ đến chữ "b" cuối cùng trong "abab". Strcpy cuối cùng nối thêm "b" nên chuỗi trả về là "cbcb". Nếu không còn gì để sao chép, orig phải trỏ đến ASCIIZ của chuỗi đầu vào.
jmucchiello

đơn giản hóa: bạn có thể thay thế forvòng lặp đầu tiên đó bằng for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, sau đó tmpchỉ được sử dụng để viết.
rapter

1
char * done = Replace ("abcdefghijkl", "bc", "yz"); do_stuff (); miễn phí (thực hiện);
jmucchiello

2
Hãy cảnh báo rằng hàm này trả về NULL nếu không có lần xuất hiện nào để thay thế (if (! (Ins = strstr (orig, rep))) return NULL;). Bạn không thể chỉ sử dụng đầu ra, bạn cần kiểm tra xem đầu ra có phải là NULL hay không và nếu có thì hãy sử dụng chuỗi gốc (đừng chỉ sao chép con trỏ vào chuỗi kết quả vì miễn phí (kết quả) sau đó giải phóng chuỗi gốc). Cách sử dụng đơn giản hơn nếu chuỗi đầu vào chỉ được sao chép vào chuỗi đầu ra nếu không có gì để thay thế.
Adversus

18

Điều này không được cung cấp trong thư viện C tiêu chuẩn bởi vì, chỉ được cung cấp một ký tự *, bạn không thể tăng bộ nhớ được cấp phát cho chuỗi nếu chuỗi thay thế dài hơn chuỗi được thay thế.

Bạn có thể làm điều này bằng cách sử dụng std :: string dễ dàng hơn, nhưng ngay cả khi ở đó, không có hàm đơn lẻ nào làm điều đó cho bạn.


12
Câu hỏi này là về C, không phải C ++.
Geremia

1 / strlen (char *) + 1 không nhất thiết phải bằng kích thước lưu trữ. 2 / Có rất nhiều phiên bản N của hàm chuỗi nhận và bổ sung tham số kích thước bộ đệm nên không có lý do gì không thể có snreplace (). 3 / có thể có chức năng thay thế tại chỗ và không thay thế tại chỗ. 4 / bạn nghĩ sprintf hoạt động như thế nào? Nó đưa ra một đối số char * và nó không cần phải tăng phân bổ bộ nhớ cho nó, vì vậy không có lý do gì mà một thay thế cũng không thể hoạt động ... (mặc dù C có thiết kế "chuỗi" không tốt và kích thước bộ đệm luôn phải được chuyển with the pointer => snprintf)
Steven Spark

12

Không có một.

Bạn cần phải cuộn của riêng bạn bằng cách sử dụng một cái gì đó như strstr và strcat hoặc strcpy.


7
Bộ sưu tập của người hâm mộ về các chức năng thường được sử dụng được lưu trữ ở đâu? Chắc chắn đã có một thư viện cho nó ....
Pacerier

1
strcat()là một gợi ý không tồi.
Iharob Al Asimi

11

Bạn có thể xây dựng hàm thay thế của riêng mình bằng cách sử dụng strstr để tìm các chuỗi con và strncpy để sao chép từng phần vào bộ đệm mới.

Trừ khi những gì bạn muốn replace_withcó cùng độ dài với những gì bạn muốn replace, thì tốt nhất bạn nên sử dụng một bộ đệm mới để sao chép chuỗi mới vào.


9

Vì các chuỗi trong C không thể tự động phát triển thay thế thay thế thường sẽ không hoạt động. Do đó, bạn cần phải phân bổ không gian cho một chuỗi mới có đủ chỗ cho sự thay thế của bạn và sau đó sao chép các phần từ bản gốc cộng với phần thay thế vào chuỗi mới. Để sao chép các phần, bạn sẽ sử dụng strncpy .


Kích thước bộ đệm có thể lớn hơn strlen, chuỗi thay thế có thể nhỏ hơn chuỗi được thay thế ... do đó bạn không cần cấp phát bộ nhớ để thực hiện thay thế. (Ngoài ra trên vi điều khiển bạn có thể không có bộ nhớ vô hạn, và bạn có thể cần phải thực hiện thay thế tại chỗ Sao chép tất cả mọi thứ để một bộ đệm mới có thể không phải là giải pháp đúng cho tất cả mọi người ....)
Steven Spark

8

Đây là một số mã mẫu thực hiện điều đó.

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

Nó hoạt động, nhưng hơi lỗi, nhưng dù sao cũng cảm ơn! : D đây là một cái tôi thấy hoạt động rất tốt, coding.debuntu.org/… chúc mừng! :)
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

Hàm repl_str () trên creativeandcritical.net rất nhanh và đáng tin cậy. Cũng được bao gồm trên trang đó là một biến thể chuỗi rộng, repl_wcs () , có thể được sử dụng với các chuỗi Unicode bao gồm những chuỗi được mã hóa bằng UTF-8, thông qua các hàm trợ giúp - mã demo được liên kết từ trang. Tiết lộ đầy đủ muộn màng: Tôi là tác giả của trang đó và các chức năng trên đó.


3
nhanh và đáng tin cậy, nhưng bị rò rỉ bộ nhớ lớn.
MightyPork

3
Tôi không hiểu làm thế nào nó có thể. Chỉ có một malloc và người gọi được hướng dẫn giải phóng bộ nhớ khi nó không còn cần thiết. Bạn có thể đặc sắc hơn không?
Laird

@Lairdpos_cache = realloc(pos_cache
PSkocik

@PSkocik Chức năng đã được nâng cấp kể từ khiếu nại của @MightyPork nhưng mặc dù hiện tại nó đã có thêm malloc / realloc cho pos_cache, tôi không thể thấy đường dẫn mã tránh phần free(pos_cache);cuối của hàm.
Laird

@Laird realloccó thể bị lỗi. Nếu có, nó sẽ trả về NULLvà giữ nguyên con trỏ cũ. p = realloc(p, x)sẽ, nếu xảy ra lỗi, viết lại một con trỏ đống hợp lệ pvới NULL, và nếu điều đó plà tài liệu tham khảo duy nhất của bạn với đối tượng heap, bây giờ bạn đã bị rò rỉ nó. Đó là một sai lầm cổ điển của người mới.
PSkocik

3

tôi thấy hầu hết các chức năng được đề xuất khó hiểu - vì vậy tôi đã nghĩ ra điều này:

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

đầu ra phải được miễn phí


2

Bạn có thể sử dụng chức năng này (các nhận xét giải thích cách hoạt động):

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

Đây là cái mà tôi đã tạo dựa trên những yêu cầu sau:

  1. Thay thế mẫu bất kể là dài hay ngắn hơn.

  2. Không sử dụng bất kỳ malloc nào (rõ ràng hoặc ẩn) để tránh rò rỉ bộ nhớ về bản chất.

  3. Thay thế bất kỳ số lần xuất hiện nào của mẫu.

  4. Dung sai chuỗi thay thế có chuỗi con bằng chuỗi tìm kiếm.

  5. Không phải kiểm tra xem Mảng dòng có đủ kích thước để chứa phần thay thế hay không. Ví dụ: Điều này không hoạt động trừ khi người gọi biết dòng đó có kích thước đủ để chứa chuỗi mới.

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

Bất kỳ đề xuất nào để cải thiện mã này đều được vui vẻ chấp nhận. Chỉ cần đăng bình luận và tôi sẽ kiểm tra nó.


1

Bạn có thể sử dụng strrep ()

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

strrep (Thay thế chuỗi). Thay thế 'strf' bằng 'strr' trong 'cadena' và trả về chuỗi mới. Bạn cần giải phóng chuỗi trả về trong mã của mình sau khi sử dụng strrep.

Tham số cadena Chuỗi có văn bản. strf Văn bản cần tìm. strr Văn bản thay thế.

Trả về Văn bản được cập nhật với sự thay thế.

Dự án có thể được tìm thấy tại https://github.com/ipserc/strrep


0

bản sửa lỗi cho phản hồi của fann95, sử dụng sửa đổi tại chỗ của chuỗi và giả sử bộ đệm được trỏ đến từng dòng đủ lớn để chứa chuỗi kết quả.

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

Đây rồi .... đây là hàm để thay thế mọi lần xuất hiện char xbằng char ytrong chuỗi ký tựstr

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

Một ví dụ sử dụng có thể là

  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.

Hàm là từ một thư viện chuỗi mà tôi duy trì trên Github , rất hoan nghênh bạn xem qua các hàm có sẵn khác hoặc thậm chí đóng góp vào mã :)

https://github.com/fnoyanisi/zString

CHỈNH SỬA: @siride là đúng, hàm trên chỉ thay thế các ký tự. Vừa mới viết cái này, thay thế chuỗi ký tự.

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

Và dưới đây là đầu ra

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'

Điều này chỉ thay thế các ký tự đơn, không thay thế chuỗi con.
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;
}

segfault khi str là null
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

Hàm này chỉ hoạt động nếu chuỗi của bạn có thêm không gian cho độ dài mới

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

Điều này chỉ thay thế Lần xuất hiện đầu tiên


0

Đây là vấn đề của tôi, nó độc lập và linh hoạt, cũng như hiệu quả, nó phát triển hoặc thu nhỏ bộ đệm khi cần thiết trong mỗi lần đệ quy

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

Đây là thông tin của tôi, hãy biến chúng thành tất cả các ký tự *, giúp việc gọi điện dễ dàng hơn ...

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

0

Chỉ sử dụng strlen từ string.h

xin lỗi vì tiếng Anh của tôi

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

nếu bạn muốn mã strlen để tránh gọi string.h

int strlen(char * string){//use this code to avoid calling string.h
    int lenght = 0;
    while(string[lenght] != '\0'){
        lenght++;
    }
    return lenght;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.