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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32413667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 12:06:30  来源:igfitidea点击:

Replace all occurrences of a substring in a string in C

cstringstr-replace

提问by Erik Blenert

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.

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

Here is the code so far:

这是到目前为止的代码:

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] = '
strncpy(buffer, string, p-string);
'; //EDIT: THIS WAS MISSING strcat(buffer, replace); strcat(buffer, p+strlen(search)); strcpy(string, buffer); p++; } }

I'm not new to C programming, but I'm missing something here.

我对 C 编程并不陌生,但我在这里遗漏了一些东西。

Example: for input string "marie has apples has", searching for "has" and replace with "blabla"

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

In the first "has" is replaced correctly, but the second one is not. The final output is "marie blabla apples hasblabla". Notice the second "has" is still there.

在第一个“有”被正确替换,但第二个不是。最终输出是“marie blabla apples hasblabla”。注意第二个“有”仍然存在。

What am I doing wrong? :)

我究竟做错了什么?:)

EDIT Is is working now. Adding the null terminating character fixed the problem. I know the resulting string can be bigger than 100. It's a school homework so I won't have strings longer than 20 or so.

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

采纳答案by alk

For starters:

对于初学者:

This line

这条线

strcat(buffer, replace);

not necessarily appends a 0-terminator to what had been copied to buffer.

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

The following line

以下行

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

however relies on bufferbeing 0-terminated.

然而依赖于buffer0终止。

As bufferhad 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.

Asbuffer尚未初始化,尽管 -0终止符很可能会错过后一行,但很可能会超出buffer内存的范围,从而调用臭名昭著的未定义行为。

回答by The Paramagnetic Croissant

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 ppointer so it points just after the needle
  • GOTO 10
  • 搜索第一次出现的“针”(搜索的子字符串)
  • 将第一次出现之前的部分复制到结果缓冲区
  • 将替换字符串附加到结果缓冲区
  • 增加p指针,使其指向指针之后
  • 转到 10
char s[1024] = "marie has apples has";                         
str_replace(s, "has", "blabla");

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 *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] = '
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));
}
'; 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; }

回答by StackUser

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] = '##代码##';
        strcat(buffer, rep);
        //printf("STR:%s\n", buffer);
        i = (p - str) + strlen(orig);
    }

    return buffer;
}

Input:marie has apples has

输入:玛丽有苹果有

Output:marie blabla apples blabla

输出:marie blabla 苹果 blabla

回答by Claudio

##代码##

回答by umesh walkar

i find some needful corrections to be made in function.. here is new function

我发现需要在功能上进行一些必要的更正……这是新功能

##代码##