假设已经有一个kmp函数,返回substr在str中出现的位置,如果不存在则返回NULL(行为和strstr一样)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *kmp(const char *str, const char *substr)
{
    return strstr(str, substr); //kmp的实现略过
}
void str_replace(char *dest, const char *src, 
        const char *pattern, const char *replace)
{
    int lp = strlen(pattern), lr = strlen(replace);
    const char *temp = src, *last = src;
    while ((temp = kmp(temp, pattern)) != NULL)
    {
        //copy to dest
        memcpy(dest, last, temp - last);
        dest += temp - last;
        strcpy(dest, replace);
        dest += lr;
        temp += lp;
        last = temp;
    }
    strcpy(dest, last);
}
int main()
{
    char dest[1000];
    str_replace(dest, "abcdefgabcdefgabcdefg", "fg", "----");
    printf("%s\n", dest);
    str_replace(dest, "abcdefgabcdefgabcdefg", "ef", "----");
    printf("%s\n", dest);
    str_replace(dest, "hello world", "l", "ab");
    printf("%s\n", dest);
    return 0;
}p.s. 里面虽然用到了 memcpy, strlen, strcpy,但是这些自己额外写都是很简单的。
算法其实挺简单,蛋疼的是接口的设计,得写额外的代码来计算需要多大的空间,上面就略过了,另外附一个由函数负责分配空间的安全版(相应的后果是要额外扫一遍):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *kmp(const char *str, const char *substr)
{
    return strstr(str, substr);
}
char *str_replace(const char *src, const char *pattern, const char *replace)
{
    int count = 0, lp = strlen(pattern), lr = strlen(replace);
    char *dest = NULL, *ret = NULL;
    const char *temp = src, *last = NULL;
    while ((temp = kmp(temp, pattern)) != NULL)
    {
        count++;
        temp += lp;
    }
    dest = ret = (char *)malloc(sizeof(lr - lp) * count + strlen(src) + 1);
    if (ret == NULL) 
        return NULL;
    temp = src, last = src;
    while ((temp = kmp(temp, pattern)) != NULL)
    {
        //copy to dest
        memcpy(dest, last, temp - last);
        dest += temp - last;
        strcpy(dest, replace);
        dest += lr;
        temp += lp;
        last = temp;
    }
    strcpy(dest, last);
    return ret;
}
int main()
{
    char *dest = NULL;
    dest = str_replace("abcdefgabcdefgabcdefg", "fg", "----");
    if (dest != NULL)
        printf("%s\n", dest);
    free(dest);
    dest = str_replace("abcdefgabcdefgabcdefg", "ef", "----");
    if (dest != NULL)
        printf("%s\n", dest);
    free(dest);
    dest = str_replace("hello world", "l", "ab");
    if (dest != NULL)
        printf("%s\n", dest);
    free(dest);
    return 0;
}