替换C中字符串中出现的所有子字符串

Eri*_*ert 6 c string str-replace

我正在尝试在C中创建一个函数来替换字符串中所有出现的子字符串.我创建了我的函数,但它只适用于较大字符串中第一次出现的子字符串.

这是迄今为止的代码:

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++;
    }
} 
Run Code Online (Sandbox Code Playgroud)

我不是C编程的新手,但我在这里缺少一些东西.

示例:输入字符串"marie has apples has",搜索"has"并替换为"blabla"

在第一个"has"被正确替换,但第二个没有.最终的输出是"marie blabla apples hasblabla".注意第二个"有"仍然存在.

我究竟做错了什么?:)

编辑现在正在运作.添加空终止字符可以解决问题.我知道结果字符串可能大于100.这是学校的作业,所以我不会有超过20左右的字符串.

The*_*ant 11

我似乎不清楚你想要遵循什么算法,这对我来说都很可疑.最简单的方法可能是:

  • 搜索第一次出现的"针"(搜索的子字符串)
  • 将第一次出现之前的部件复制到结果缓冲区
  • 将替换字符串附加到结果缓冲区
  • 增加p指针,使其指向针后
  • 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);
}
Run Code Online (Sandbox Code Playgroud)

警告:您还必须小心如何调用您的函数.如果替换字符串大于针,则修改后的字符串将比原始字符串长,因此您必须确保原始缓冲区足够长以包含修改后的字符串.例如:

char s[1024] = "marie has apples has";                         
str_replace(s, "has", "blabla");
Run Code Online (Sandbox Code Playgroud)

  • 我不能.代表不够.我只能选择"最佳"答案. (2认同)

alk*_*alk 4

对于初学者:

这条线

strncpy(buffer, string, p-string);
Run Code Online (Sandbox Code Playgroud)

不一定0在复制到的内容后附加 - 终止符buffer

下面一行

strcat(buffer, replace);
Run Code Online (Sandbox Code Playgroud)

然而依赖buffer0终止。

由于buffer尚未初始化,尽管 -0终止符很可能错过了后一行,但很可能会超出buffer的记忆范围,从而引发臭名昭著的未定义行为。