简体   繁体   中英

Efficiently replace a substring in a string

I have made two functions that find a substring index and substitute that substring in the string. I'm glad I jury rigged this at all, given that similar questions previously asked were never answered/marked as closed without any help. Is there a cleaner method?

void destroy_substr(int index, int len)
{
    int i;

    for (i = index; i < len; i++)
    {
        string[i] = '~';
    }
}


void find_substr_index(char* substr)
{
    int i;
    int j;
    int k;
    int count;
    int len = strlen(substr);

    for (i = 0; i < strlen(string); i++)
    {
        if (string[i] == substr[0])
        {
            for(j = i, k = 0; k < len; j++, k++)
            {
                if (string[j] == substr[k])
                {
                    count++;
                }
                if (count == len)
                    destroy_substr((j - len + 1), len);
            }
            j = 0;
            k = 0;
            count = 0;
        }
    }
}

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

How about this:

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

int main(int argc, char **argv)
{
    char string[] = "HELLO hello WORLD world HELLO hello ell";
    char substring[] = "ell";
    int stringLength = strlen(string);
    int substringLength = strlen(substring);

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

    if(substringLength <= stringLength)
    {
        int i;
        int j;

        for(i = 0, j = stringLength - substringLength + 1; i < j; )
        {
            if(memcmp(&string[i], substring, substringLength) == 0)
            {
                memset(&string[i], '~', substringLength);
                i += substringLength;
            }
            else
            {
                i++;
            }
        }
    }

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

    return 0;
}

Key ideas are:

  1. You only need to scan the string (stringLength - substringLength) times
  2. You can use functions from string.h to do the comparison and to replace the substring

You can copy the new string in place. If you want to support insertion of longer strings you will need to manage memory with malloc()/realloc(). If you want to support insertion of smaller strings you'll need to advance the pointer to the beginning by the length of the replacement string, copy the rest of the string to that new location, then zero the new end of the string.

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

int main(int argc, char **argv)
{   
    char *str = strdup("The fox jumps the dog\n");
    char *search = "fox";
    char *replace = "cat";
    size_t replace_len = strlen(replace);
    char *begin = strstr(str, search);

    if (begin == NULL)  
        errx(1, "substring not found");

    if (strlen(begin) < replace_len)
        errx(1, "replacement too long");

    printf("%s", str);
    memcpy(begin, replace, replace_len);
    printf("%s", str);

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM