Replace Substring With Another Substring C++

How to replace a part of a string with another substring

Replacing a substring with another is easy if both substrings have the same length:

  • locate the position of the substring with strstr
  • if it is present, use memcpy to overwrite it with the new substring.
  • assigning the pointer with *strstr(m, "on") = "in"; is incorrect and should generate a compiler warning. You would avoid such mistakes with gcc -Wall -Werror.
  • note however that you cannot modify a string literal, you need to define an initialized array of char so you can modify it.

Here is a corrected version:

#include <stdio.h>
#include <string.h>

int main(void) {
char m[] = "cat on couch";
char *p = strstr(m, "on");
if (p != NULL) {
memcpy(p, "in", 2);
}
printf("%s\n", m);
return 0;
}

If the replacement is shorter, the code is a little more complicated:

#include <stdio.h>
#include <string.h>

int main(void) {
char m[] = "cat is out roaming";
char *p = strstr(m, "out");
if (p != NULL) {
memcpy(p, "in", 2);
memmove(p + 2, p + 3, strlen(p + 3) + 1);
}
printf("%s\n", m);
return 0;
}

In the generic case, it is even more complicated and the array must be large enough to accommodate for the length difference:

#include <stdio.h>
#include <string.h>

int main(void) {
char m[30] = "cat is inside the barn";
char *p = strstr(m, "inside");
if (p != NULL) {
memmove(p + 7, p + 6, strlen(p + 6) + 1);
memcpy(p, "outside", 7);
}
printf("%s\n", m);
return 0;
}

Here is a generic function that handles all cases:

#include <stdio.h>
#include <string.h>

char *strreplace(char *s, const char *s1, const char *s2) {
char *p = strstr(s, s1);
if (p != NULL) {
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
if (len1 != len2)
memmove(p + len2, p + len1, strlen(p + len1) + 1);
memcpy(p, s2, len2);
}
return s;
}

int main(void) {
char m[30] = "cat is inside the barn";

printf("%s\n", m);
printf("%s\n", strreplace(m, "inside", "in"));
printf("%s\n", strreplace(m, "in", "on"));
printf("%s\n", strreplace(m, "on", "outside"));
return 0;
}

How to replace substring in a string with another string in C?

Your code is a good start, but there are many problems:

  • the test if (str1[i+j] != str1[i+j]) is always true
  • you copy incomplete fragments and fail to skip it after copying.
  • you forgot to null terminate the destination.

Here is a modified version:

#include <stdio.h>

char *str_replace(char *dest, const char *str1, const char *str2, const char *str3) {
size_t i = 0, j, k = 0;

// replacing substring `str2` with `str3`, assuming sufficient space
while (str1[i] != '\0') {
for (j = 0; str2[j] != '\0'; j++) {
if (str1[i + j] != str2[j]) {
break;
}
}
if (str2[j] == '\0' && j > 0) {
// we have a match: copy the replacement and skip it
i += j;
for (j = 0; str3[j] != '\0'; j++) {
dest[k++] = str3[j];
}
} else {
// copy the byte and skip it.
dest[k++] = str1[i++];
}
}
dest[k] = '\0'; // null terminate the destination
return dest;
}

int main() {
char new_string[50];
printf("%s\n", str_replace(new_string, "123abc890", "abc", "abc"));
printf("%s\n", str_replace(new_string, "123abc890", "abc", "xyz"));
printf("%s\n", str_replace(new_string, "123abc890", "a", "xyz"));
printf("%s\n", str_replace(new_string, "123abc890", "abc", ""));
return 0;
}

Output:


123abc890
123xyz890
123xyzbc890
123890

Replace all occurrences of a substring in a string in C

For starters:

This line

strncpy(buffer, string, p-string);

not necessarily appends a 0-terminator to what had been copied to buffer.

The following line

strcat(buffer, replace);

however relies on buffer being 0-terminated.

As buffer had not been initialised and though the 0-terminator most likely misses the latter line may very well read beyond buffer's memory and with this invoke the infamous Undefined Behaviour.

Efficiently replace a substring in a string

Your code seems like you're trying to re-inventing your own wheel.

By using standard C functions, which is strstr() and memset(), you can achieve the same result as you expected.

#include <stdio.h>
#include <string.h>

char string[] = "foobar foobar foobar";
char substr[] = "foo";
char replace = '~';

int main() {

int substr_size = strlen(substr);

// Make a copy of your `string` pointer.
// This is to ensure we can safely modify this pointer value, without 'touching' the original one.
char *ptr = string;

// while true (infinite loop)
while(1) {

// Find pointer to next substring
ptr = strstr(ptr, substr);

// If no substring found, then break from the loop
if(ptr == NULL) { break; }

// If found, then replace it with your character
memset(ptr, replace, substr_size);

// iIncrement our string pointer, pass replaced substring
ptr += substr_size;
}

printf("%s\n", string);

return 0;
}

C - Replace substring in string

Question 1: When this line is executed in main() it causes a segfault.
However, when executed within the function everything seems to work
fine. Why?

No, printf("input: %d\t%s\n", len, buffer); // <- Question 1 is not the cause of your segfault.

printf("output: %ld\t%s\n", strlen(output), output);

This part is, strlen doesn't return int but it returns size_t. As noted in the comments, use %zu to print it out.

Also, while(input[a]) will stop at the NULL terminator which means that your output will never hold a terminator and thus printf will keep on reading, you should add it at the end:

output[c] = '\0';

Also, as noted by @LPs in the comments, you should zero initialize the variables you work with :

 int a = 0, b = 0, c = 0;

Question 2: I have realized that I need a pretty large piece of memory
allocated for the output to look as expected. strlen(input)*5 is an
arbitrary number which seems to work, but why do I get seemingly
'random' errors when lowering the number?

Probably because you haven't allocated enough memory. Because the string length depends on runtime factors there's no way to know the exact memory needed you should allocate the maximum amount required:

char *output = malloc(strlen(input) * strlen(new) + 1);

replace a substring of a given string in c++

Yet, the output of s3 is, "There Bob and Bill go again!". Could
anyone help to explain?

Not quite. The output is "There Bob and Billey go again". Starting from the word they it took the first two characters (th) and replaced them with Bob and Bill. The result is There Bob and Billey go again!.

This behavior is consistent with this documentation's explanation of std::string::replace:

Replaces the portion of the string that begins at character pos and
spans len characters (or the part of the string in the range between
[i1,i2)) by new contents:

(1) string
Copies str.

If you wanted your output to be "There Boey go again!", you can do it like this:

int size = 2; // amount of characters that should be replaced
if (pos != string::npos)
s3.replace(pos, size, s4.substr(0, size));


Related Topics



Leave a reply



Submit