The optimizer should eliminate most of the local variables. The tmp pointer is there to make sure strcpy doesn't have to walk the string to find the null. tmp points to the end of result after each call. (See Shlemiel the painter's algorithm for why strcpy can be annoying.)

// 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;
}
Answer from jmucchiello on Stack Overflow
Top answer
1 of 16
118

The optimizer should eliminate most of the local variables. The tmp pointer is there to make sure strcpy doesn't have to walk the string to find the null. tmp points to the end of result after each call. (See Shlemiel the painter's algorithm for why strcpy can be annoying.)

// 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;
}
2 of 16
21

This is not provided in the standard C library because, given only a char* you can't increase the memory allocated to the string if the replacement string is longer than the string being replaced.

You can do this using std::string more easily, but even there, no single function will do it for you.

🌐
LinuxQuestions.org
linuxquestions.org › questions › programming-9 › replace-a-substring-with-another-string-in-c-170076
replace a substring with another string in C
yes. me again :P and this is yet another question for string manipulation in c. I've searched this forum, but I didn't find sth helpful unluckily. So
Discussions

How to substitute strings in c? Like how sed command works
I recently published an experimental library for easy string manipulation in C , which I think could be useful for your use case. By the way, I wrote that library for two main reasons: (1) as a learning activity and (2) because I found working with strings in C to be very painful. I'm sharing a quick example here to give you an idea of how it works: #include #include #include #include "fancy_string.h" int main(void) { // Instantiate a new string object with initial internal state "Hello, World!" fancy_string_t *s = fancy_string_create("Hello, World!"); // Print a summary of the object to `stdout` fancy_string_print(s, stdout, true); // Prints: // fancy_string_t[13](Hello, World!) // Replace the first (and only) occurrence of 'World' with 'lib'. fancy_string_replace_value(s, "World", "lib", 1); //  Make sure that the string has been updated like we wanted to... assert(fancy_string_equals_value(s, "Hello, lib!")); // ... and print a summary of updated object to `stdout`. fancy_string_print(s, stdout, true); // Prints: // fancy_string_t[25](Hello, lib!) // Prepend the string object's internal state with 'Greetings: '. fancy_string_prepend_value(s, "Greetings: "); // Make sure that the string has been updated like we wanted to... assert(fancy_string_equals_value(s, "Greetings: Hello, lib!")); // ... and print a summary of updated object to `stdout`. fancy_string_print(s, stdout, true); // Prints: // fancy_string_t[36](Greetings: Hello, lib!) // So far, we've used methods suffixed with `_value`, which means that // they take as argument a string literal. But the library also has the // matching methods for string objects. Let's append something to our string: { // Instantiate a new string object containing the suffix to be appended to `s`. fancy_string_t *suffix = fancy_string_create(" My name is Francis!"); // Append `suffix` to `s`. fancy_string_append(s, suffix); // Destroy the `suffix` object, since it's no longer needed. fancy_string_destroy(suffix); // Now, let's confirm that our string object has been updated as expected: assert(fancy_string_equals_value(s, "Greetings: Hello, lib! My name is Francis!")); // and let's print a summary of updated object to `stdout`. fancy_string_print(s, stdout, true); // Prints: // fancy_string_t[56](Greetings: Hello, lib! My name is Francis!) } // We could go on forever, because there are a lot of methods in this library's // API. But let's see two more. // Regular expression with lib { // Instantiate a string object containing the pattern for which to match. // In this case, we are trying to match "lib" fancy_string_t *pattern = fancy_string_create("[a-z]*<[_a-z]*>"); // Instantiate the regular expression object. fancy_string_regex_t *re = fancy_string_regex_create(s, pattern, -1); // Confirm that no error occurred. assert(re != NULL); // Print a verbose summary of the regular expression object to `stdout`. fancy_string_regex_debug(re, stdout, true); // Confirm that we have a match. assert(fancy_string_regex_match_count(re) == 1); // Retrieve the "match" info at `index = 0`. fancy_string_regex_match_info_t match_info = fancy_string_regex_match_info_for_index(re, 0); // Confirm that we have something at `index = 0`. assert(match_info.index == 0); // Create a substring of `s` for the matched range (i.e., from `start` to `end`) fancy_string_t *match = fancy_string_substring(s, match_info.start, match_info.end); // Confirm that the match corresponds to 'lib'. assert(fancy_string_equals_value(match, "lib")); // Destroy the string object containing the substring. fancy_string_destroy(match); // Destroy the regular expression object. fancy_string_regex_destroy(re); // Destroy the string object that stores the pattern. fancy_string_destroy(pattern); } //  The library also has (string) array methods. { // Instantiate a string object with single-space-separated names. fancy_string_t *names = fancy_string_create("john eric arold joe henry zoe joey ralf"); // Split the string at ' ', an unlimited number of times (n_max_splits = -1 does that). fancy_string_array_t *a = fancy_string_split_by_value(names, " ", -1); // Print a summary of the array to `stdout`. fancy_string_array_print(a, stdout, true); // Sort the array (in ascending order) fancy_string_array_sort_values(a); // Join the array back into a string. fancy_string_t *sorted_names = fancy_string_array_join_by_value(a, " "); // Confirm that the names have been sorted. assert(fancy_string_equals_value(sorted_names, "arold eric henry joe joey john ralf zoe")); // Print the sorted string to `stdout` fancy_string_print(sorted_names, stdout, true); // Destroy the three objects. fancy_string_destroy(sorted_names); fancy_string_array_destroy(a); fancy_string_destroy(names); } // The library contains many more methods, so please have a look at the // API documentation and the `examples` directory for more! // Destroy the string object. fancy_string_destroy(s); // Exit program with success status. exit(EXIT_SUCCESS); } Let me know if you'd like me to write you another example for a specific set of operations. More on reddit.com
🌐 r/C_Programming
12
2
December 18, 2023
Replace all occurrences of a substring in a string in C - Stack Overflow
I'm trying to make a function in C to replace all occurrences of a substring in a string. I made my function, but it only works on the first occurrence of the substring in the bigger string. Here i... More on stackoverflow.com
🌐 stackoverflow.com
performance - Replace string with another string in C - Code Review Stack Exchange
I have written a program that replaces a given c-string with another c-string. My code works well with small files but takes too much time while working with large files (50 Megabytes and larger). ... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
how to replace a substring in a string using C? - Post.Byes
hi, there, for example, char *mystr="##this is##a examp#le"; I want to replace all the "##" in mystr with "****". How can I do this? I checked all the string functions in C, but did not find one. thanks. More on post.bytes.com
🌐 post.bytes.com
🌐
Cplusplus
cplusplus.com › reference › string › string › replace
std::string::replace
Position of the first character in str that is copied to the object as replacement. If this is greater than str's length, it throws out_of_range. ... Length of the substring to be copied (if the string is shorter, as many characters as possible are copied).
🌐
Creativeandcritical
creativeandcritical.net › str-replace-c
Portable C string and wide string replacement functions: repl_str and repl_wcs
The purpose of this function is to replace in the input string all occurrences of a source/search ("from") substring with a target/replace ("to") substring, and to then return a post-replacement string, doing all this as efficiently as is possible without specific knowledge of the nature of ...
🌐
PrepBytes
prepbytes.com › home › c programming › c program to replace a substring in a string
C Program to Replace a Substring in a String
June 23, 2023 - Step 1: Define the original string, the substring to be replaced, and the replacement string. Step 2: Find the position of the first occurrence of the substring within the original string using the strstr() function.
🌐
Reddit
reddit.com › r/c_programming › how to substitute strings in c? like how sed command works
r/C_Programming on Reddit: How to substitute strings in c? Like how sed command works
December 18, 2023 -

I want to make a youtube searcher in c, where i will get a string as input and curl it. Curl gives its output as one massive string. I will need to afterwards clean that curl output up to get video titles, uploaders and links. And im very much drawn to use a bunch of bash commands like sed, awk, grep and what not to accomplish this. But i want to know if its possible in c ... So far the only string manipulation ive done is searching trough a string and adding /0 to end the string there. But i would like to know what is the best way to for example replace all chars from the start of a string up untill a specific char is found, and replace with a diffeent set of chars ... Like you would with sed. I also welcome any resources on this topic or any advice

Find elsewhere
🌐
YouTube
youtube.com › watch
Replace substrings in C - YouTube
How to replace a substring in C.Down below is a link to the implementation of the function: https://pastebin.com/srLi6QZ1Check out our Discord server: https:...
Published   April 13, 2020
Top answer
1 of 5
19

It doesn't seem clear to me what algorithm you are trying to follow, it all looks fishy to me. What's probably the simplest approach is:

  • search for first occurrence of the "needle" (searched-for substring)
  • copy the part before the first occurrence to the result buffer
  • append the replacement string to the result buffer
  • increment the p pointer so it points just after the needle
  • 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);
}

Warning: You also have to be careful about how you call your function. If the replacement string is larger than the needle, your modified string will be longer than the original one, so you have to make sure your original buffer is long enough to contain the modified string. E.g.:

char s[1024] = "marie has apples has";                         
str_replace(s, "has", "blabla");
2 of 5
4

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.

🌐
Cprogramming
cboard.cprogramming.com › c-programming › 175148-replacing-string-another-string-user-inputted-position.html
Replacing string with another string with user-inputted position
November 1, 2017 - while within that second loop using an if statement ,you almost got it. you need to keep a temp of main string, then over write the main string starting at insert position to end of substring, then use that temp string to pick up where the substring left off at to complete the copy of what is left of the main string using the temp string back into that main string.
Top answer
1 of 3
2

The fast_strncat() is a good idea. The actual copying isn't efficient (though a good optimiser might recognise the pattern), but letting the caller know how much was copied helps avoid a program being Schlemiel the painter.

I don't like the name; it sounds too much like strncat(), which has very different behaviour. Perhaps len_strcpy() or something better conveys the functionality?

And instead of passing a pointer to result, it's generally better to return the result (either as a number of characters as here - though size_t is probably a better choice of type - or perhaps as a pointer to the new string end).

It's possible we don't need it though - see our use of memcpy in the next section.


The way we're using strstr() is very inefficient. We're traversing input a character at a time, repeating the same search until our position reaches the search result. Imagine this in human terms:

  • "Run down the road to the first red house, and tell me where it is."
  • It's not this one, so walk ahead to the next house.
  • "Run down the road to the first red house, and tell me where it is."

Doesn't this sound a lot like Shlemiel's algorithm, that we worked so hard to avoid earlier?

We could consider using strncmp() instead in the same loop, but we can do better. Once we have the result from strstr(), we know there are no matches up to that result. So we can measure the length change much more simply:

size_t count_old = 0;
for (const char *p = *str;  (p = strstr(p, old));  ++p) {
    ++count_old;
}

And we can copy each chunk in one go:

while (*temp) {
    const char *next_match = strstr(temp, old);
    if (next_match) {
        size_t match_len = next_match - temp;
        memcpy(buff+i, temp, match_len);
        i += match_len;
        temp += match_len;
        memcpy(buff+i, new, len_n);
        i += len_n;
        temp += len_o;
    } else {
        /* no match - copy the remainder */
        strcpy(buff+i, temp);
    }

The code is quite limited because it will only work with seekable files, it has to read the entire file into memory, and it needs space for the entire output file in memory before it starts writing.

We can make it more efficient (and avoid the need to seek) by reading a buffer of characters, replacing matches within the buffer, and then writing out the buffer, before repeating. There's a small complication that we need to deal with matches that might straddle two reads - we need to write out all but len_o - 1 characters, and then move those last few to the front of the buffer, before reading the next characters after them. If we know we're working with streams, then there's no need to write to a new string array - just fwrite() each chunk as we get there.

On the other hand, if we want a general function to work on in-memory strings, we can avoid needing separate input and output arrays. It's possible to perform replacement in situ, provided our buffer is big enough to hold the bigger of input and output. The code needs to have two branches - working from the end if the replacement string is bigger than the match string, or from the beginning otherwise. I'd definitely recommend using unit tests to guide implementation if you choose to attempt such in-place substitution.


We have no error checking for the fwrite() and fclose() in main(). These functions can and do fail (e.g. disk quota reached), and we mustn't mislead the user that we succeeded if we haven't written all the output.


Minor things:

  • We don't need to include a newline at the end of the message we give to perror(). That function will append : and error description, then a newline of its own.
  • temp isn't a great name for a variable. It only tells us that it's short-lived, but doesn't indicate what it's for.
  • There are many redundant casts - I don't think any of the casts here are necessary (Any Type* converts automatically to Type const* - a cast just costs the reader's time, and makes it harder to spot the true problems).
  • The if (ptr) test leaves us holding state in our heads for half a screenful - it's easier to read if we test if (!ptr), which has a much shorter block (and also exits the function).
  • sizeof (char) is always 1 (because sizeof works in units of char), so those expressions can be simplified.
2 of 3
1

fast_strncat() fails to make a string.

Used within strreplace(), fast_strncat() may work as that code uses zero'd out buffers. But fast_strncat() is not a static function and subject to other's use.

Either make fast_strncat() static or append the null character.

Lack of error checking

Functions like ftell(), fread(), etc. deserve to have the return value checked for errors.

On memory allocation failure, don't die.

strreplace() should return a success/failure error indication. Just like malloc(), let the caller decide.

Minor: Unneeded cast

// strlen((const char *)data)
strlen(data)

Candidate alterative: For long strings, I expect the efficiencies of strlen(), memcpy() will win out.

void fast_strncat_alt(char *dest, const char *src, size_t *dest_len) {
  if (dest && src) {
    size_t src_len = strlen(src);
    memcpy(dest + *dest_len, src, src_len + 1u);
    *dest_len += src_len;
  }
}

For a single pass, could use the below. This is reasonable when the compiler is smart enough to analyze sprintf(des,t "%s", src) and emit efficient code.

void fast_strncat_alt2(char *dest, const char *src, size_t *dest_len) {
  if (dest && src) {
    int len = sprintf(dest + *dest_len, "%s", src);
    *dest_len += len;
  }
}
🌐
GitHub
gist.github.com › bg5sbk › 11058000
replace string in C · GitHub
The outcome is the same if you try to replace the subtring with the same string, meaning: ... Sign up for free to join this conversation on GitHub. Already have an account?
🌐
IncludeHelp
includehelp.com › tips › c › replacing-a-part-of-string-in-c.aspx
Replacing a part of string in C
January 23, 2017 - memcpy() - This is the library function of string.h, which is used to copy fixed number of bytes, memcpy() does not insert NULL, so this function is safe to replace the string.
🌐
GeeksforGeeks
geeksforgeeks.org › cpp › std-string-replace-in-cpp
std::string::replace() in C++
May 29, 2026 - We cannot provide a description for this page right now
🌐
Quora
quora.com › How-do-I-replace-a-string-by-a-word-in-C
How to replace a string by a word in C - Quora
Assuming the length of the replaced ... position starts with the character position immediately after the replaced character(s). (If the replaced string is exactly as long as the existing substring, you can skip this step and the next one.)...
🌐
Post.Byes
post.bytes.com › home › forum › topic
how to replace a substring in a string using C? - Post.Byes
I think the best choice is to write your own function. It is easy task. ... Re: how to replace a substring in a string using C?