ฟังก์ชันใดในการแทนที่สตริงย่อยจากสตริงใน C


96

ด้วยchar *สตริง( ) ฉันต้องการค้นหาเหตุการณ์ที่เกิดขึ้นทั้งหมดของสตริงย่อยและแทนที่ด้วยสตริงอื่น ฉันไม่เห็นฟังก์ชั่นง่ายๆที่ทำได้ใน<string.h>.


4
ฉันสงสัยว่าคุณสามารถทำสิ่งนี้ในรูปแบบที่เปลี่ยนแปลงได้
user44511

คำตอบ:


90

เครื่องมือเพิ่มประสิทธิภาพควรกำจัดตัวแปรโลคัลส่วนใหญ่ ตัวชี้ tmp อยู่ที่นั่นเพื่อให้แน่ใจว่า strcpy ไม่ต้องเดินสตริงเพื่อค้นหา null tmp ชี้ไปที่จุดสิ้นสุดของผลลัพธ์หลังจากการโทรแต่ละครั้ง (ดูอัลกอริทึมของจิตรกรของ Shlemielว่าเหตุใด strcpy จึงน่ารำคาญ)

// 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: ใช้size_tแทนintสำหรับขนาดวัตถุ / สตริงและดัชนีที่กำหนดเอง จุดประสงค์ของstrcpy(tmp, orig);ท้ายที่สุดคืออะไร? ดูเหมือนไม่ถูกต้อง
Alexey Frunze

@Alex strcpy สุดท้าย (tmp, orig) คัดลอกส่วนสุดท้ายของสตริงไปยังปลายทาง เช่น: แทนที่ ("abab", "a", "c") ที่ส่วนท้ายของลูปผลลัพธ์ประกอบด้วย "cbc" และ orig ชี้ไปที่ "b" สุดท้ายใน "abab" strcpy สุดท้ายต่อท้าย "b" ดังนั้นสตริงที่ส่งคืนคือ "cbcb" หากไม่มีสิ่งใดเหลือให้คัดลอก orig ควรชี้ไปที่ ASCIIZ ของสตริงอินพุต
jmucchiello

การทำให้เข้าใจง่าย: คุณสามารถแทนที่forลูปแรกfor (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}นั้นได้จากนั้นtmpจะใช้สำหรับการเขียนเท่านั้น
rampion

1
ถ่าน * done = แทนที่ ("abcdefghijkl", "bc", "yz"); do_stuff (); ฟรี (ทำ);
jmucchiello

2
ขอเตือนว่าฟังก์ชันนี้จะคืนค่า NULL หากไม่มีเหตุการณ์ที่จะแทนที่ (if (! (ins = strstr (orig, rep))) return NULL;) คุณไม่สามารถใช้เอาต์พุตได้คุณต้องตรวจสอบว่าเอาต์พุตเป็น NULL หรือไม่และหากเป็นเช่นนั้นให้ใช้สตริงเดิม (อย่าเพิ่งคัดลอกตัวชี้ไปยังสตริงผลลัพธ์เพราะอิสระ (ผลลัพธ์) จะทำให้สตริงเดิมเป็นอิสระ) การใช้งานจะตรงไปตรงมามากขึ้นหากมีการคัดลอกสตริงอินพุตลงในสตริงเอาต์พุตหากไม่มีสิ่งใดให้แทนที่
Adversus

18

สิ่งนี้ไม่มีให้ในไลบรารี C มาตรฐานเนื่องจากมีเพียงถ่าน * คุณไม่สามารถเพิ่มหน่วยความจำที่จัดสรรให้กับสตริงได้หากสตริงแทนที่ยาวกว่าสตริงที่ถูกแทนที่

คุณสามารถทำได้โดยใช้ std :: string ได้ง่ายขึ้น แต่ถึงอย่างนั้นก็ไม่มีฟังก์ชันเดียวที่จะทำเพื่อคุณ


12
คำถามนี้เกี่ยวกับ C ไม่ใช่ C ++
Geremia

1 / strlen (ถ่าน *) + 1 ไม่จำเป็นต้องเท่ากับขนาดพื้นที่จัดเก็บ 2 / มีฟังก์ชันสตริง N เวอร์ชันจำนวนมากที่รับและพารามิเตอร์ขนาดบัฟเฟอร์เพิ่มเติมดังนั้นจึงไม่มีเหตุผลว่าทำไมจึงไม่มี snreplace () 3 / อาจมีฟังก์ชั่นการแทนที่แบบแทนที่และไม่แทนที่ในตำแหน่ง 4 / คุณคิดว่า sprintf ทำงานอย่างไร? ได้รับอาร์กิวเมนต์ char * และไม่จำเป็นต้องเพิ่มการจัดสรรหน่วยความจำดังนั้นจึงไม่มีเหตุผลที่การแทนที่ไม่สามารถทำงานได้เช่นกัน ... (แม้ว่า C จะมีการออกแบบ "สตริง" ที่ไม่ดีและควรส่งขนาดบัฟเฟอร์เสมอ ด้วยตัวชี้ => snprintf)
Steven Spark

12

ไม่มีเลย

คุณต้องม้วนของคุณเองโดยใช้สิ่งต่างๆเช่นstrstrและ strcat หรือ strcpy


7
คอลเลกชันแฟน ๆ ของฟังก์ชันที่ใช้บ่อยจะถูกเก็บไว้ที่ไหน? แน่นอนว่ามีห้องสมุดอยู่แล้ว ....
Pacerier

1
strcat()เป็นคำแนะนำที่ไม่ดี
Iharob Al Asimi

11

คุณสามารถสร้างฟังก์ชันการแทนที่ของคุณเองโดยใช้ strstr เพื่อค้นหาสตริงย่อยและ strncpy เพื่อคัดลอกส่วนต่างๆไปยังบัฟเฟอร์ใหม่

เว้นแต่สิ่งที่คุณต้องการจะreplace_withมีความยาวเท่ากับสิ่งที่คุณต้องการคุณreplaceควรใช้บัฟเฟอร์ใหม่เพื่อคัดลอกสตริงใหม่


9

เนื่องจากสตริงใน C ไม่สามารถเติบโตแบบไดนามิกการแทนที่ในสถานที่โดยทั่วไปจะไม่ทำงาน ดังนั้นคุณต้องจัดสรรพื้นที่สำหรับสตริงใหม่ที่มีที่ว่างเพียงพอสำหรับการทดแทนของคุณจากนั้นคัดลอกส่วนจากต้นฉบับบวกการแทนที่ลงในสตริงใหม่ การคัดลอกส่วนที่คุณจะใช้strncpy


ขนาดบัฟเฟอร์อาจใหญ่กว่า strlen สตริงทดแทนอาจมีขนาดเล็กกว่าสตริงที่ถูกแทนที่ ... ดังนั้นคุณไม่จำเป็นต้องจัดสรรหน่วยความจำเพื่อทำการแทนที่ (นอกจากนี้ในไมโครคอนโทรลเลอร์คุณอาจไม่มีหน่วยความจำไม่สิ้นสุดและคุณอาจต้องทำการแทนที่การคัดลอกทุกอย่างไปยังบัฟเฟอร์ใหม่อาจไม่ใช่วิธีที่เหมาะสมสำหรับทุกคน ... )
Steven Spark

8

นี่คือตัวอย่างโค้ดบางส่วนที่ทำได้

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

มันใช้งานได้ แต่มีข้อผิดพลาดเล็กน้อย แต่ยังไงก็ตามขอบคุณ! : D นี่คือสิ่งที่ฉันพบว่าใช้งานได้ดีcoding.debuntu.org/…ไชโย! :)
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 เป็นไปอย่างรวดเร็วและเชื่อถือได้ รวมอยู่ในหน้านั้นด้วยคือตัวแปรสตริงแบบกว้างrepl_wcs ()ซึ่งสามารถใช้ได้กับสตริง Unicode รวมถึงที่เข้ารหัสใน UTF-8 ผ่านฟังก์ชันตัวช่วย - โค้ดสาธิตจะเชื่อมโยงจากเพจ การเปิดเผยข้อมูลทั้งหมดที่ล่าช้า: ฉันเป็นผู้เขียนหน้านั้นและหน้าที่ในหน้านั้น


3
รวดเร็วและเชื่อถือได้ แต่มีหน่วยความจำรั่วไหลมาก
MightyPork

3
ฉันไม่เห็นว่ามันทำได้อย่างไร มี Malloc เพียงตัวเดียวและผู้โทรจะได้รับคำสั่งให้เพิ่มหน่วยความจำเมื่อไม่จำเป็นต้องใช้อีกต่อไป คุณสามารถเจาะจงมากขึ้นได้ไหม
Laird

@Lairdpos_cache = realloc(pos_cache
PSkocik

@PSkocik ฟังก์ชั่นได้รับการอัปเกรดตั้งแต่มีการร้องเรียนโดย @MightyPork แต่ถึงแม้ว่าตอนนี้จะมี malloc / realloc เพิ่มเติมสำหรับ pos_cache แต่ฉันไม่เห็นเส้นทางรหัสที่หลีกเลี่ยงfree(pos_cache);ฟังก์ชัน at
Laird

@Laird reallocอาจล้มเหลว หากเป็นเช่นนั้นระบบจะส่งกลับNULLและปล่อยให้ตัวชี้เก่าเหมือนเดิม p = realloc(p, x)เมื่อเกิดความล้มเหลวให้เขียนตัวชี้ฮีปที่ถูกต้องอีกครั้งpด้วยNULLและหากนั่นpเป็นการอ้างอิงเพียงอย่างเดียวของคุณไปยังวัตถุฮีปนั้นตอนนี้คุณก็รั่วไหล มันเป็นความผิดพลาดของมือใหม่แบบคลาสสิก
PSkocik

3

ฉันพบว่าฟังก์ชั่นที่นำเสนอส่วนใหญ่ยากที่จะเข้าใจ - ดังนั้นฉันจึงคิดสิ่งนี้:

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

ผลลัพธ์ต้องเป็นอิสระ


2

คุณสามารถใช้ฟังก์ชันนี้ (ความคิดเห็นอธิบายวิธีการทำงาน):

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

นี่คือสิ่งที่ฉันสร้างขึ้นตามข้อกำหนดเหล่านี้:

  1. แทนที่รูปแบบไม่ว่าจะยาวหรือสั้น

  2. อย่าใช้ malloc ใด ๆ (โดยชัดแจ้งหรือโดยนัย) เพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำภายใน

  3. แทนที่จำนวนของรูปแบบที่เกิดขึ้น

  4. ทนต่อสตริงการแทนที่ที่มีสตริงย่อยเท่ากับสตริงการค้นหา

  5. ไม่ต้องตรวจสอบว่า Line array มีขนาดเพียงพอที่จะทำการเปลี่ยนหรือไม่ เช่นไม่ได้ผลเว้นแต่ผู้โทรจะรู้ว่าเส้นมีขนาดเพียงพอที่จะเก็บสตริงใหม่ได้

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

ข้อเสนอแนะใด ๆ ในการปรับปรุงรหัสนี้ได้รับการยอมรับด้วยความยินดี เพียงโพสต์ความคิดเห็นและฉันจะทดสอบ


1

นี่เป็นของฉันทำให้เป็นถ่าน * ทั้งหมดซึ่งทำให้การโทรง่ายขึ้น ...

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 ()

ถ่าน * strrep (const char * cadena, const char * strf, const char * strr)

strrep (สตริงแทนที่) แทนที่ 'strf' ด้วย 'strr' ใน 'cadena' และส่งคืนสตริงใหม่ คุณต้องปลดปล่อยสตริงที่ส่งคืนในโค้ดของคุณหลังจากใช้ strrep

Parameters cadena สตริงที่มีข้อความ strf ข้อความที่ต้องการค้นหา strr ข้อความแทนที่

ส่งคืนข้อความที่อัปเดตด้วยการแทนที่

สามารถดูโครงการได้ที่https://github.com/ipserc/strrep


0

การแก้ไขการตอบสนองของ fann95 โดยใช้การปรับเปลี่ยนในสถานที่ของสตริงและสมมติว่าบัฟเฟอร์ที่ชี้ไปทีละบรรทัดมีขนาดใหญ่พอที่จะเก็บสตริงผลลัพธ์ได้

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

มีคุณไป .... นี้เป็นฟังก์ชั่นที่จะเปลี่ยน occurance ของทุกchar xกับchar yภายในตัวอักษร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;
}

ตัวอย่างการใช้งานอาจเป็น

  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.

ฟังก์ชั่นนี้มาจากไลบรารีสตริงที่ฉันดูแลบน Githubคุณยินดีเป็นอย่างยิ่งที่จะได้ดูฟังก์ชั่นอื่น ๆ ที่มีอยู่หรือแม้แต่ร่วมให้โค้ด :)

https://github.com/fnoyanisi/zString

แก้ไข: @siride ถูกต้องฟังก์ชันด้านบนจะแทนที่ตัวอักษรเท่านั้น เพิ่งเขียนอันนี้ซึ่งแทนที่สตริงอักขระ

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

และด้านล่างคือผลลัพธ์

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'

สิ่งนี้จะแทนที่อักขระเดี่ยวเท่านั้นไม่ใช่สตริงย่อย
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 เมื่อ str เป็นโมฆะ
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

ฟังก์ชันนี้ใช้ได้เฉพาะเมื่อสตริง ur มีช่องว่างเพิ่มเติมสำหรับความยาวใหม่

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

สิ่งนี้จะแทนที่เหตุการณ์แรกเท่านั้น


0

ที่นี่เป็นของฉันมันมีอยู่ในตัวและมีความหลากหลายรวมถึงมีประสิทธิภาพมันจะเติบโตหรือลดขนาดบัฟเฟอร์ตามความจำเป็นในการเรียกซ้ำแต่ละครั้ง

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

ใช้ strlen จาก string.h

ขอโทษสำหรับภาษาอังกฤษของฉัน

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 เพื่อหลีกเลี่ยงการเรียก string.h

int strlen(char * string){//use this code to avoid calling string.h
    int lenght = 0;
    while(string[lenght] != '\0'){
        lenght++;
    }
    return lenght;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.