我试图用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;
}
我的输出例如是: 如果发送字符串"请删除rem删除rem999", 我回来了:"请过去参加999"
谢谢!
答案 0 :(得分:4)
以下内容:
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)
与您的想法完全不同。
答案 1 :(得分:1)
在这个循环中
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
答案 2 :(得分:0)
sizeof(temp_p)
是char *
的大小,通常为4
你可能想写strlen(temp_p)