2015-09-05 8 views
5

Ich versuche, eine Funktion in C zu erstellen, um alle Vorkommen einer Teilzeichenfolge in einer Zeichenfolge zu ersetzen. Ich habe meine Funktion gemacht, aber sie funktioniert nur beim ersten Auftreten der Teilkette in der größeren Zeichenfolge. HierErsetzen Sie alle Vorkommen einer Teilzeichenfolge in einer Zeichenfolge in C

ist der Code so weit:

void strreplace(char string[], char search[], char replace[]){ 
    char buffer[100]; 
    char*p = string; 
    while((p=strstr(p, search))){ 
     strncpy(buffer, string, p-string); 
     buffer[p-string] = '\0'; //EDIT: THIS WAS MISSING 
     strcat(buffer, replace); 
     strcat(buffer, p+strlen(search)); 
     strcpy(string, buffer); 
     p++; 
    } 
} 

ich die C-Programmierung nicht neu bin, aber ich bin hier fehlt etwas.

Beispiel: für die Eingabezeichenfolge „Marie hat Äpfel hat“, die Suche nach „hat“ und Ersetzen durch „blabla“

In der ersten „hat“ ersetzt wird richtig, aber die zweite nicht. Die endgültige Ausgabe ist "Marie blabla Äpfel hasblabla". Beachten Sie, dass das zweite "hat" immer noch da ist.

Was mache ich falsch? :)

EDIT Es funktioniert jetzt. Durch das Hinzufügen des Nullabschlusszeichens wurde das Problem behoben. Ich weiß, dass die resultierende Zeichenfolge größer als 100 sein kann. Es ist eine Hausaufgabe, so dass ich keine Strings länger als 20 oder so haben werde.

+2

@GerardvanHelden Wahrscheinlich, weil sie nicht in der C-Standard-Bibliothek sind? (Denken Sie PHP?) – ace

+0

Wie haben Sie das Ergebnis gesehen? mit einem Debugger? – yeyo

+0

@ace fair point, Kommentar gelöscht. Dachte die PHP-Funktionen intern zugeordnet C stdlib (was sie eine Menge Zeit tun), aber nicht in diesem Fall. –

Antwort

4

Für den Anfang:

Diese Linie

strncpy(buffer, string, p-string); 

nicht unbedingt anhängt eine 0 -terminator zu dem, was auf buffer kopiert worden waren.

Die folgende Zeile

strcat(buffer, replace); 

verlässt sich jedoch auf buffer0 -terminierten ist.

Als buffer hatte nicht initialisiert und obwohl die 0 -terminator am ehesten die letztere Linie verpasst über buffer ‚s-Speicher und damit aufrufen, um den berüchtigten nicht definiertes Verhalten kann sehr gut lesen.

+0

Vergessen Sie 0-Terminator-Sache nach Strncpy. Danke :) –

6

Es scheint mir nicht klar zu sein, welchen Algorithmus Sie versuchen zu folgen, alles sieht mir faul aus. Was ist wohl der einfachste Ansatz ist:

  • Suche nach ersten Auftreten der „Nadel“ (gesuchten für substring)
  • kopieren Sie den Teil vor dem ersten Auftreten auf den Ergebnispuffer
  • den Ersatz-String anhängen zu der Ergebnispuffer
  • Inkrement der p Zeiger so weist es nur, nachdem die Nadel
  • GOTO 10
void str_replace(char *target, const char *needle, const char *replacement) 
{ 
    char buffer[1024] = { 0 }; 
    char *insert_point = &buffer[0]; 
    const char *tmp = target; 
    size_t needle_len = strlen(needle); 
    size_t repl_len = strlen(replacement); 

    while (1) { 
     const char *p = strstr(tmp, needle); 

     // walked past last occurrence of needle; copy remaining part 
     if (p == NULL) { 
      strcpy(insert_point, tmp); 
      break; 
     } 

     // copy part before needle 
     memcpy(insert_point, tmp, p - tmp); 
     insert_point += p - tmp; 

     // copy replacement string 
     memcpy(insert_point, replacement, repl_len); 
     insert_point += repl_len; 

     // adjust pointers, move on 
     tmp = p + needle_len; 
    } 

    // write altered string back to target 
    strcpy(target, buffer); 
} 

Warnung: Sie müssen auch vorsichtig sein, wie Sie Ihre Funktion aufrufen. Wenn die Ersetzungszeichenfolge größer als die Nadel ist, ist die geänderte Zeichenfolge länger als die ursprüngliche Zeichenfolge. Daher müssen Sie sicherstellen, dass der ursprüngliche Puffer so lang ist, dass er die geänderte Zeichenfolge enthält. Z.B.:

char s[1024] = "marie has apples has";       
str_replace(s, "has", "blabla"); 
+0

Der Algorithmus, den Sie in Worten beschrieben haben, ist das, was ich erreichen wollte. Ich weiß, dass ich es besser machen kann, aber es ist nur eine schulische Aufgabe. Danke für die Eingabe :) –

+0

@ErikBlenert Sie können Ihre Dankbarkeit durch Upvoting der Antwort (en) materialisieren, die Sie nützlich fanden. –

+1

kann ich nicht. Nicht genug rep. Ich kann nur die "beste" Antwort wählen. –

3
char *replace_str(char *str, char *orig, char *rep) 
{ 
static char buffer[4096]; 
char *p; 
int i=0; 

while(str[i]){ 
    if (!(p=strstr(str+i,orig))) return str; 
    strncpy(buffer+strlen(buffer),str+i,(p-str)-i); 
    buffer[p-str] = '\0'; 
    strcat(buffer,rep); 
    printf("STR:%s\n",buffer); 
    i=(p-str)+strlen(orig); 
} 

return buffer; 
} 

int main(void) 
{ 
    char str[100],str1[50],str2[50]; 
    printf("Enter a one line string..\n"); 
    gets(str); 
    printf("Enter the sub string to be replaced..\n"); 
    gets(str1); 
    printf("Enter the replacing string....\n"); 
    gets(str2); 
    puts(replace_str(str, str1, str2)); 

    return 0; 
} 

Eingang: marie hat

Ausgangs Äpfel hat: marie blabla Äpfel einige nötige Korrekturen blabla

-1

i .. finden Sie hier in der Funktion gemacht werden soll neue Funktion

char *replace_str(char *str, char *orig, char *rep) 
{ 
    static char buffer[1024]; 
    char *p; 
    int i = 0; 

    if (!(p = strstr(str + i, orig))) 
    { 
     return str; 
    } 

    while (str[i]) 
    { 
     if (!(p = strstr(str + i, orig))) 
     { 
      strcat(buffer, str + i); 
      break; //return str; 
     } 
     strncpy(buffer + strlen(buffer), str + i, (p - str) - i); 
     buffer[p - str] = '\0'; 
     strcat(buffer, rep); 
     //printf("STR:%s\n", buffer); 
     i = (p - str) + strlen(orig); 
    } 

    return buffer; 
} 
+0

Bitte geben Sie nicht nur einen Block Code, sondern erklären Sie die Änderungen und warum sie wichtig sind. Ebenfalls; löst dies das Problem? –

Verwandte Themen