从 C 中的字符串中删除子字符串 [英] Remove a substring from a string in C
问题描述
我想从字符串中删除一个特定的子字符串,例如我的主字符串是 "ababccdabce"
并且我想从中删除 "abc"
以便它将变成 "abcde"
.
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"
.
我只是想知道 C 中是否有一个预定义的函数可以做到这一点,如果没有,该怎么做?
I just wanted to know if there is a predefined function in C to do that, and if not, how to do it?
推荐答案
C 中没有预定义的函数可以从 C 字符串中删除给定的子字符串,但您可以使用 strstr
和 <代码>记住代码>.请注意,如果您原地删除子字符串,则不能使用 memcpy
或 strcpy
,因为如果源数组和目标数组重叠,它们将具有未定义的行为.
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
. 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.
代码如下:
#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 提出了优化建议:
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 指法的更有效的版本:只在第一场比赛之后开始复制比赛之间的片段:
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:
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
:
Here is the same method without any calls to 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;
}
这篇关于从 C 中的字符串中删除子字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!