[英]Remove a substring from a string with memmove in C
我正在尝试实现一个函数,用memmove从字符串中删除子字符串。 打印输出结果时,即使我在源字符串中使用了正确的位置,我似乎也没有正确移动子字符串。 我的职能是:
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;
}
例如,我的输出是:如果发送字符串“ please remove rem remove rem999”,我会回来:“ please ove rm ovmove re 999”
谢谢!
下列:
while(scan_p = strstr(temp_p,substr)){
temp_p = scan_p + subStrSize;
memmove(scan_p, temp_p, sizeof(temp_p)+1);
}
毫无意义。
您需要这样的东西:
while( temp_p = strstr( temp_p, substr ) )
{
length = strlen( temp_p );
memmove( temp_p, temp_p + subStrSize, length - subStrSize + 1 );
}
注意:在我的答案的第一个版本中,我只是使用strlen()
,但是正如评论者所指出的那样,由于该标准,这是不可取的。 (它仍然很可能起作用,因为我们是在复制而不是向上复制,但是最好不要通过违反标准来诱惑您的命运。)因此,这就是为什么我们需要memmove()
的原因。
请注意,可以使用多两行代码来对其进行优化,从而不必计算length = strlen( temp_p );
在循环的每次迭代中。 这种优化留给学生作为练习。
另请注意:
你最好做int subStrSize = strlen(substr);
在您检查substr == NULL
;
没有styrlen()
这样的东西
sizeof(temp_p)
所做的事情与您认为的完全不同。
在这个循环中
temp_p = str;
while(scan_p = strstr(temp_p,substr)){
temp_p = scan_p + subStrSize;
memmove(scan_p, temp_p, `sizeof(temp_p)`+1);
}
有两个错误。
第一个是,该循环的每次迭代后的指针temp_p
应等于该指针的值scan_p
因为字符串的尾部在该位置上移动。
第二个是这个表达
sizeof(temp_p)
产生char *
类型的对象的大小,而不是提供指针temp_p
指向的字符串的长度。
同样,您的函数也经常调用函数strlen
。
至于整个功能设计,则该功能不应检查参数之一是否等于NULL。 这是功能客户端的任务。 标准的C字符串函数不进行这种检查。
如示例程序所示,函数实现可以采用以下方式。
#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;
}
程序输出为
12A12B12C12D
ABCD
sizeof(temp_p)
是char *
的大小,通常为4
您可能想写strlen(temp_p)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.