[英]Remove a substring from a string in C
I want to remove a particular substring from a string for example my main string is "ababccdabce"
and I want to remove "abc"
from it so it will become "abcde"
.我想从字符串中删除一个特定的子字符串,例如我的主字符串是
"ababccdabce"
并且我想从中删除"abc"
所以它会变成"abcde"
。
I just wanted to know if there is a predefined function in C to do that, and if not, how to do it?我只是想知道 C 中是否有一个预定义的函数可以做到这一点,如果没有,该怎么做?
There is no predefined function in C to remove a given substring from a C string, but you can write one using strstr
and memmove
. C 中没有预定义的函数可以从 C 字符串中删除给定的子字符串,但您可以使用
strstr
和memmove
编写一个。 Note that if you remove the substring in place, you cannot use memcpy
nor strcpy
because these have undefined behavior if the source and destination arrays overlap.请注意,如果您原地删除子字符串,则不能使用
memcpy
或strcpy
因为如果源数组和目标数组重叠,它们将具有未定义的行为。
Here is the code:这是代码:
#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;
}
Note that the resulting string may contain the substring as is the case in your example.请注意,结果字符串可能包含子字符串,就像您的示例中的情况一样。
Netherwire suggested an optimisation: 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;
}
Further honing the code, I came up with an even more efficient version using the 2 finger-method: only copying the fragments between matches starting after the first match:进一步磨练代码,我想出了一个使用 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;
}
Here is the same method without any calls to memmove
:这是相同的方法,没有调用
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.