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

替换C中字符串中出现的所有子字符串,c,string,str-replace,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

我试图在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++;
    }
} 
我对C编程并不陌生,但我在这里遗漏了一些东西

示例:对于输入字符串“marie has apples has”,搜索“has”并替换为“blabla”

在第一种情况下,正确替换了“has”,但第二种情况下没有正确替换。 最终输出为“marie blabla苹果Hasbala”。注意,第二个“has”仍然存在

我做错了什么?:)

编辑 他正在工作。添加空终止字符修复了该问题。 我知道结果字符串可以大于100。这是学校的家庭作业,所以我的字符串长度不会超过20左右。

首先:

这条线

strncpy(buffer, string, p-string);
不一定要将
0
-终止符附加到已复制到
缓冲区的内容上

下一行

strcat(buffer, replace);
然而,依赖于
buffer
0
终止


由于
buffer
尚未初始化,虽然
0
-终止符很可能未命中后一行,但很可能会超出
buffer
的内存,并由此引发臭名昭著的未定义行为。

我似乎不清楚您试图遵循的算法,这一切看起来都很可疑。最简单的方法可能是:

  • 搜索“针”的第一个匹配项(搜索子字符串)
  • 将第一个引用之前的零件复制到结果缓冲区
  • 将替换字符串追加到结果缓冲区
  • 增加
    p
    指针,使其指向针的正后方
  • 转到10
警告:您还必须注意如何调用函数。如果替换字符串大于指针,则修改后的字符串将比原始字符串长,因此必须确保原始缓冲区足够长,以容纳修改后的字符串。例如:

char s[1024] = "marie has apples has";                         
str_replace(s, "has", "blabla");
输入:玛丽有苹果


输出:玛丽·布拉布拉布拉苹果布拉布拉布拉

我发现需要对函数进行一些必要的修改。。 这是一个新函数

char *replace_str(char *str, char *orig, char *rep)
{
    static char buffer[1024];
    char *p;
    int i = 0;

    if (!(p = strstr(str + i, orig)))
    {
        return str;
    }

    while (str[i])
    {
        if (!(p = strstr(str + i, orig)))
        {
            strcat(buffer, str + i);
            break; //return str;
        }
        strncpy(buffer + strlen(buffer), str + i, (p - str) - i);
        buffer[p - str] = '\0';
        strcat(buffer, rep);
        //printf("STR:%s\n", buffer);
        i = (p - str) + strlen(orig);
    }

    return buffer;
}

@GerardvanHelden可能是因为它们不在C标准库中?(你在想PHP吗?)你是如何看到结果的?使用调试器?@ace fair point,删除注释。虽然PHP函数在内部映射到C stdlib(它们经常这样做),但在这种情况下就不是了。这个函数有点冒险,因为你不知道输入字符串是否能容纳100字节。但除此之外,您的
while
循环每次通过循环时只会将
p
增加1。我假设它需要根据替换字符串的长度进行缓冲
strcpy(字符串、缓冲区)你是做什么的?你不需要第一行,你可以把第二行移出循环…你用文字描述的算法就是我想要实现的。我知道我可以做得更好,但这只是学校的作业。谢谢你的意见:)@ErikBlenert你可以通过投票选出你认为有用的答案来实现你的感激之情。我不能。没有足够的代表。我只能选择“最佳”答案。在strncpy之后忘记了0-terminator的事情。谢谢:)请不要只是给出一段代码,还要解释这些更改以及它们的重要性。也;这能解决问题吗?你能解释为什么这比其他4个答案好吗?
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
int i=0;

while(str[i]){
    if (!(p=strstr(str+i,orig)))  return str;
    strncpy(buffer+strlen(buffer),str+i,(p-str)-i);
    buffer[p-str] = '\0';
    strcat(buffer,rep);
    printf("STR:%s\n",buffer);
    i=(p-str)+strlen(orig);
}

return buffer;
}

int main(void)
{
  char str[100],str1[50],str2[50];
  printf("Enter a one line string..\n");
  gets(str);
  printf("Enter the sub string to be replaced..\n");
  gets(str1);
  printf("Enter the replacing string....\n");
  gets(str2);
  puts(replace_str(str, str1, str2));

  return 0;
}
char *replace_str(char *str, char *orig, char *rep)
{
    static char buffer[1024];
    char *p;
    int i = 0;

    if (!(p = strstr(str + i, orig)))
    {
        return str;
    }

    while (str[i])
    {
        if (!(p = strstr(str + i, orig)))
        {
            strcat(buffer, str + i);
            break; //return str;
        }
        strncpy(buffer + strlen(buffer), str + i, (p - str) - i);
        buffer[p - str] = '\0';
        strcat(buffer, rep);
        //printf("STR:%s\n", buffer);
        i = (p - str) + strlen(orig);
    }

    return buffer;
}
int replace_str(char* i_str, char* i_orig, char* i_rep)
{
   char l_before[2024];
   char l_after[2024];
   char* l_p;
   int l_origLen;

   l_origLen = strlen(i_orig);
   while (l_p = strstr(i_str, i_orig)) {
      sprintf(l_before ,"%.*s" ,l_p - i_str ,i_str);
      sprintf(l_after ,"%s" ,l_p + l_origLen);
      sprintf(i_str ,"%s%s%s" ,l_before ,i_rep ,l_after);
   }
   return(strlen(i_str));
}