简体   繁体   English

从C中带有memmove的字符串中删除子字符串

[英]Remove a substring from a string with memmove in C

I'm trying to implement a function for removing a substring from a string with memmove. 我正在尝试实现一个函数,用memmove从字符串中删除子字符串。 When printing out the results, it seems like I have not moved correctly the substrings, even though it seems like I used the correct position in the source string. 打印输出结果时,即使我在源字符串中使用了正确的位置,我似乎也没有正确移动子字符串。 My function is: 我的职能是:

char * removeSubStr(char * str, const char * substr){
    char *scan_p, *temp_p;
    int subStrSize = strlen(substr);
    if (str == NULL){
        return 0;
    }
    else if (substr == NULL){
        return str;
    }
    else if (strlen(substr)> strlen(str)){
        return str;
    }
    temp_p = str;
    while(scan_p = strstr(temp_p,substr)){
        temp_p = scan_p + subStrSize;
        memmove(scan_p, temp_p, sizeof(temp_p)+1);

    }
    return str;
}

My output, for example is: if sending the string "please remove rem remove rem999", I'm getting back: "please ove rm ovmove re 999" 例如,我的输出是:如果发送字符串“ please remove rem remove rem999”,我会回来:“ please ove rm ovmove re 999”

Thanks! 谢谢!

The following: 下列:

while(scan_p = strstr(temp_p,substr)){
    temp_p = scan_p + subStrSize;
    memmove(scan_p, temp_p, sizeof(temp_p)+1);
}

makes very little sense. 毫无意义。

You need something like this: 您需要这样的东西:

while( temp_p = strstr( temp_p, substr ) )
{
    length = strlen( temp_p );
    memmove( temp_p, temp_p + subStrSize, length - subStrSize + 1 );
}

Note: in the first version of my answer I was just using strlen() , but as commenters pointed out, that would be inadvisable because of the standard. 注意:在我的答案的第一个版本中,我只是使用strlen() ,但是正如评论者所指出的那样,由于该标准,这是不可取的。 (It would still most probably work, since we are copying down, not up, but it is best not to tempt your fate by violating the standard.) So, that's why we need memmove() . (它仍然很可能起作用,因为我们是在复制而不是向上复制,但是最好不要通过违反标准来诱惑您的命运。)因此,这就是为什么我们需要memmove()的原因。

Note that with a couple of more lines of code this can be optimized so that you don't have to compute length = strlen( temp_p ); 请注意,可以使用多两行代码来对其进行优化,从而不必计算length = strlen( temp_p ); in each iteration of the loop. 在循环的每次迭代中。 This optimization is left as an exercise to the student. 这种优化留给学生作为练习。

Also please note: 另请注意:

  • You better do int subStrSize = strlen(substr); 你最好做int subStrSize = strlen(substr); after you check substr == NULL ; 您检查substr == NULL

  • There is no such thing as styrlen() 没有styrlen()这样的东西

  • sizeof(temp_p) does something completely different from what you think it does. sizeof(temp_p)所做的事情与您认为的完全不同。

In this loop 在这个循环中

temp_p = str;
while(scan_p = strstr(temp_p,substr)){
    temp_p = scan_p + subStrSize;
    memmove(scan_p, temp_p, `sizeof(temp_p)`+1);

}

there are two bugs. 有两个错误。

The first one is that after each iteration of the loop the pointer temp_p should be equal to the value of the pointer scan_p because the tail of the string is moved in this position. 第一个是,该循环的每次迭代后的指针temp_p应等于该指针的值scan_p因为字符串的尾部在该位置上移动。

The second one is that this expression 第二个是这个表达

sizeof(temp_p)

yields the size of an object of the type char * instead of providing the length of the string pointed to by the pointer temp_p . 产生char *类型的对象的大小,而不是提供指针temp_p指向的字符串的长度。

Also your function too often calls the function strlen . 同样,您的函数也经常调用函数strlen

As for the function design in whole then the function should not check whether one of the parameters is equal to NULL. 至于整个功能设计,则该功能不应检查参数之一是否等于NULL。 It is the task of the client of the function. 这是功能客户端的任务。 Standard C string functions do not do such a check. 标准的C字符串函数不进行这种检查。

The function implementation can look the following way as it is shown in the demonstrative program. 如示例程序所示,函数实现可以采用以下方式。

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

char * removeSubStr( char *str, const char *substr )
{
    size_t m1 = strlen(str);
    size_t m2 = strlen(substr);

    if (!(m1 < m2))
    {
        for (char *p = str; (p = strstr(p, substr)) != NULL; )
        {
            size_t n = m1 - ( p + m2 - str );
            memmove(p, p + m2, n + 1);
        }
    }

    return str;
}

int main( void )
{
    char s[] = "12A12B12C12D";

    puts(s);

    puts(removeSubStr(s, "12"));

    return 0;
}

The program output is 程序输出为

12A12B12C12D
ABCD

sizeof(temp_p) is the size of the char * , usually 4 sizeof(temp_p)char *的大小,通常为4

You probably wanted to write strlen(temp_p) 您可能想写strlen(temp_p)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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