我想从一个字符串中删除特定的子字符串,例如我的主字符串是
我只想知道在C语言中是否有预定义的函数可以做到这一点,如果没有,该如何实现?
"ababccdabce"
,我想要将其中的"abc"
删除,使其变为"abcde"
。我只想知道在C语言中是否有预定义的函数可以做到这一点,如果没有,该如何实现?
"ababccdabce"
,我想要将其中的"abc"
删除,使其变为"abcde"
。C语言中没有预定义的函数可以从字符串中删除给定的子字符串,但是您可以使用 strstr
和 memmove
来编写一个函数。请注意,如果您在原地删除子字符串,则不能使用 memcpy
或 strcpy
,因为如果源和目标数组重叠,这些函数的行为是未定义的。
以下是代码:
#include <string.h>
char *strremove(char *str, const char *sub) {
size_t len = strlen(sub);
if (len > 0) {
char *p = str;
while ((p = strstr(p, sub)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
请注意,生成的字符串可能包含子字符串,就像您的示例中一样。
Netherwire 提出了一个优化建议:
char *strremove(char *str, const char *sub) {
size_t len = strlen(sub);
if (len > 0) {
char *p = str;
size_t size = 0;
while ((p = strstr(p, sub)) != NULL) {
size = (size == 0) ? (p - str) + strlen(p + len) + 1 : size - len;
memmove(p, p + len, size - (p - str));
}
}
return str;
}
在进一步完善代码的过程中,我使用了2个手指的方法,创造出了更加高效的版本:仅仅复制第一个匹配项之后的匹配项之间的片段。
char *strremove(char *str, const char *sub) {
char *p, *q, *r;
if (*sub && (q = r = strstr(str, sub)) != NULL) {
size_t len = strlen(sub);
while ((r = strstr(p = r + len, sub)) != NULL) {
memmove(q, p, r - p);
q += r - p;
}
memmove(q, p, strlen(p) + 1);
}
return str;
}
这里是同样的方法,没有调用memmove
:
char *strremove(char *str, const char *sub) {
char *p, *q, *r;
if (*sub && (q = r = strstr(str, sub)) != NULL) {
size_t len = strlen(sub);
while ((r = strstr(p = r + len, sub)) != NULL) {
while (p < r)
*q++ = *p++;
}
while ((*q++ = *p++) != '\0')
continue;
}
return str;
}
strlen
调用的次数。 - Netherwirestrlen(str)
。感谢你挑战我...我找到了一个更好的解决方案 :) - chqrliesub
为空字符串的特殊情况。可能还有其他错误,你能更具体地告诉我哪些参数导致了段错误吗? - chqrlie