Welche Funktion besteht darin, einen Teilstring aus einem String in C zu ersetzen?

94

Mit einer ( char *) Zeichenfolge möchte ich alle Vorkommen eines Teilstrings finden und durch eine alternative Zeichenfolge ersetzen. Ich sehe keine einfache Funktion, die dies erreicht <string.h>.

RobertS unterstützt Monica Cellio
quelle
4
Ich bezweifle, dass Sie dies auf veränderliche Weise tun können
user44511

Antworten:

87

Das Optimierungsprogramm sollte die meisten lokalen Variablen entfernen. Der tmp-Zeiger dient dazu, sicherzustellen, dass strcpy den String nicht durchlaufen muss, um die Null zu finden. tmp zeigt nach jedem Aufruf auf das Ende des Ergebnisses. (Siehe Shlemiel, den Algorithmus des Malers, warum strcpy nervig sein kann.)

// 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
quelle
@jmucchiello: Verwenden Sie size_tanstelle von intfür beliebige Objekt- / Zeichenfolgengrößen und -indizes. Und was ist der Zweck strcpy(tmp, orig);am Ende? Es scheint falsch.
Alexey Frunze
@Alex, der letzte Strcpy (tmp, orig) kopiert den letzten Teil des Strings zum Ziel. Beispiel: Ersetzen ("abab", "a", "c") am Ende der Schleife, Ergebnis enthält "cbc" und orig zeigt auf das letzte "b" in "abab". Der letzte Strcpy hängt das "b" an, sodass der zurückgegebene String "cbcb" ist. Wenn nichts mehr zu kopieren ist, sollte orig auf das ASCIIZ der Eingabezeichenfolge zeigen.
jmucchiello
Vereinfachung: Sie können diese erste forSchleife durch ersetzen for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}und werden dann tmpnur zum Schreiben verwendet.
Rampion
1
char * done = replace ("abcdefghijkl", "bc", "yz"); Sachen machen(); frei (fertig);
jmucchiello
2
Seien Sie gewarnt, dass diese Funktion NULL zurückgibt, wenn keine zu ersetzenden Vorkommen vorhanden sind (if (! (Ins = strstr (orig, rep))) gibt NULL zurück;). Sie können nicht nur die Ausgabe verwenden, sondern müssen auch überprüfen, ob die Ausgabe NULL ist, und in diesem Fall die ursprüngliche Zeichenfolge verwenden (kopieren Sie nicht einfach den Zeiger auf die Ergebniszeichenfolge, da free (result) dann die ursprüngliche Zeichenfolge freigibt). Die Verwendung ist einfacher, wenn die Eingabezeichenfolge nur in die Ausgabezeichenfolge kopiert wird, wenn nichts zu ersetzen ist.
Adversus
18

Dies wird in der Standard-C-Bibliothek nicht bereitgestellt, da Sie mit nur einem Zeichen * den der Zeichenfolge zugewiesenen Speicher nicht erhöhen können, wenn die Ersatzzeichenfolge länger als die zu ersetzende Zeichenfolge ist.

Sie können dies einfacher mit std :: string tun, aber selbst dort wird es keine einzelne Funktion für Sie tun.

Don Neufeld
quelle
12
Diese Frage bezieht sich auf C, nicht auf C ++.
Geremia
1 / strlen (char *) + 1 entspricht nicht unbedingt der Speichergröße. 2 / Es gibt viele N Versionen von Zeichenfolgenfunktionen, die einen zusätzlichen Parameter für die Puffergröße empfangen. Es gibt also keinen Grund, warum es keinen snreplace () geben könnte. 3 / Es könnte eine Funktion zum Ersetzen vor Ort und keine Funktion zum Ersetzen vor Ort geben. 4 / Wie funktioniert Sprintf? Es hat ein char * -Argument und muss die Speicherzuordnung nicht erhöhen, daher kann kein Ersatz auch nicht funktionieren ... (obwohl C ein schlechtes "String" -Design hat und die Puffergröße immer übergeben werden sollte mit dem Zeiger => snprintf)
Steven Spark
12

Es gibt keinen.

Sie müssten Ihre eigenen mit etwas wie strstr und strcat oder strcpy rollen.

Reed Copsey
quelle
7
Wo werden Fan-Sammlungen häufig verwendeter Funktionen gespeichert? Sicher gibt es schon eine Bibliothek dafür ...
Pacerier
1
strcat()ist ein schlechter Vorschlag.
Iharob Al Asimi
11

Sie können Ihre eigene Ersetzungsfunktion mit strstr erstellen, um die Teilzeichenfolgen zu finden, und strncpy, um Teile in einen neuen Puffer zu kopieren.

Wenn das, was Sie möchten, nicht replace_withdie gleiche Länge hat wie das, was Sie möchten replace, ist es wahrscheinlich am besten, einen neuen Puffer zum Kopieren der neuen Zeichenfolge zu verwenden.

Brian R. Bondy
quelle
9

Da Zeichenfolgen in C nicht dynamisch wachsen können, funktioniert die Ersetzung an Ort und Stelle im Allgemeinen nicht. Daher müssen Sie Platz für eine neue Zeichenfolge zuweisen, die genügend Platz für Ihre Ersetzung bietet, und dann die Teile aus dem Original sowie die Ersetzung in die neue Zeichenfolge kopieren. Zum Kopieren der Teile würden Sie strncpy verwenden .

Lothar
quelle
Die Puffergröße kann größer als die Zeichenfolge sein, die Ersatzzeichenfolge kann kleiner als die ersetzte Zeichenfolge sein. Daher müssen Sie keinen Speicher zuweisen, um das Ersetzen durchzuführen. (Auch auf Mikrocontrollern haben Sie möglicherweise nicht unendlich viel Speicher, und Sie müssen möglicherweise das Ersetzen an Ort und Stelle durchführen. Kopieren Sie alles in einen neuen Puffer ist möglicherweise nicht die richtige Lösung für alle ...)
Steven Spark
8

Hier ist ein Beispielcode, der dies tut.

#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
quelle
Es funktioniert, aber es ist ein bisschen fehlerhaft, aber trotzdem danke! : D Hier ist eine, die ich gefunden habe und die sehr gut funktioniert. Coding.debuntu.org/… Prost ! :)
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
quelle
3

Die Funktion repl_str () auf creativeandcritical.net ist schnell und zuverlässig. Auf dieser Seite ist auch eine breite Zeichenfolgenvariante, repl_wcs () , enthalten, die mit Unicode-Zeichenfolgen einschließlich der in UTF-8 codierten Zeichenfolgen über Hilfsfunktionen verwendet werden kann. Der Demo-Code wird von der Seite aus verlinkt. Verspätete vollständige Offenlegung: Ich bin der Autor dieser Seite und der Funktionen darauf.

Gutsherr
quelle
3
schnell und zuverlässig, hat aber einen großen Speicherverlust.
MightyPork
3
Ich sehe nicht, wie es könnte. Es gibt nur ein Malloc und der Anrufer wird angewiesen, den Speicher freizugeben, wenn er nicht mehr benötigt wird. Könnten Sie genauer sein?
Laird
@Lairdpos_cache = realloc(pos_cache
PSkocik
@PSkocik Die Funktion wurde seit der Beschwerde von @MightyPork aktualisiert, aber obwohl sie jetzt das zusätzliche Malloc / Realloc für pos_cache enthält, kann ich keinen Codepfad sehen, der das free(pos_cache);Ende der Funktion vermeidet .
Laird
@Laird reallockann fehlschlagen. Wenn dies der Fall ist, wird NULLder alte Zeiger zurückgegeben und bleibt intakt. Wenn dies p = realloc(p, x)fehlschlägt, wird ein gültiger Heap-Zeiger pmit neu geschrieben NULL. Wenn dies pIhr einziger Verweis auf dieses Heap-Objekt war, haben Sie ihn jetzt durchgesickert. Es ist ein klassischer Anfängerfehler.
PSkocik
3

Ich finde die meisten der vorgeschlagenen Funktionen schwer zu verstehen - also habe ich mir Folgendes ausgedacht:

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

Ausgabe muss frei sein

yogo1212
quelle
2

Sie können diese Funktion verwenden (die Kommentare erklären, wie es funktioniert):

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

Hier ist die, die ich basierend auf diesen Anforderungen erstellt habe:

  1. Ersetzen Sie das Muster, unabhängig davon, ob es lang oder kürzer war.

  2. Verwenden Sie kein Malloc (explizit oder implizit), um Speicherlecks zu vermeiden.

  3. Ersetzen Sie eine beliebige Anzahl von Mustervorkommen.

  4. Tolerieren Sie die Ersetzungszeichenfolge mit einer Teilzeichenfolge, die der Suchzeichenfolge entspricht.

  5. Muss nicht überprüfen, ob das Line-Array ausreichend groß ist, um den Ersatz aufzunehmen. zB Dies funktioniert nur, wenn der Aufrufer weiß, dass die Leitung ausreichend groß ist, um die neue Zeichenfolge aufzunehmen.

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

Vorschläge zur Verbesserung dieses Codes werden gerne angenommen. Poste einfach den Kommentar und ich werde ihn testen.

if NewQuestion voteCLOSE
quelle
1

Sie können strrep () verwenden

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

strrep (String Replace). Ersetzt 'strf' durch 'strr' in 'cadena' und gibt den neuen String zurück. Sie müssen die zurückgegebene Zeichenfolge in Ihrem Code freigeben, nachdem Sie strrep verwendet haben.

Parameter cadena Die Zeichenfolge mit dem Text. strf Der zu findende Text. strr Der Ersatztext.

Rückgabe Der mit dem Ersatz aktualisierte Text.

Das Projekt finden Sie unter https://github.com/ipserc/strrep

ipserc
quelle
0

Eine Korrektur der Antwort von fann95 unter Verwendung einer direkten Änderung der Zeichenfolge und der Annahme, dass der Puffer, auf den die Zeile zeigt, groß genug ist, um die resultierende Zeichenfolge aufzunehmen.

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

Dort gehen Sie .... das ist die Funktion jedes Vorkommen von ersetzen char xmit char yinnerhalb Zeichenkettestr

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

Ein Beispiel für eine Verwendung könnte sein

  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.

Die Funktion stammt aus einer String-Bibliothek, die ich auf Github verwalte . Sie können sich gerne andere verfügbare Funktionen ansehen oder sogar zum Code beitragen :)

https://github.com/fnoyanisi/zString

BEARBEITEN: @siride ist richtig, die obige Funktion ersetzt nur Zeichen. Habe gerade diesen geschrieben, der Zeichenketten ersetzt.

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

Und unten ist die Ausgabe

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
quelle
Dies ersetzt nur einzelne Zeichen, keine Teilzeichenfolgen.
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
quelle
segfault wenn str null ist
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
quelle
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
quelle
0

Diese Funktion funktioniert nur, wenn Ihr String zusätzlichen Platz für neue Länge hat

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

Dies ersetzt nur das erste Auftreten

Niemand
quelle
0

Hier ist meins, es ist in sich geschlossen und vielseitig sowie effizient, es wächst oder schrumpft Puffer nach Bedarf in jeder Rekursion

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

Hier geht meins, mach sie alle char *, was das Anrufen erleichtert ...

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

Verwenden Sie nur strlen aus string.h

Entschuldigung für mein Englisch

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

Wenn Sie möchten, dass strlen-Code den Aufruf von string.h vermeidet

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