我想从字符串中删除特定的子句子,例如我的主要字符串是"ababccdabce"
,我想从中删除"abc"
所以它会变成"abcde"
,我只是想知道如果C中有预定义的功能,如果没有,怎么做?
答案 0 :(得分:3)
C中没有预定义的功能可以执行此操作,但您可以使用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;
}
,因为如果源和目标数组重叠,它们会有未定义的行为。
以下是代码:
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;
}
请注意,结果字符串可能包含子字符串,如示例中所示。
Netherwire 建议进行优化:
char *strremove(char *str, const char *sub) {
char *p, *q, *r;
if ((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;
}
进一步磨练代码,我想出了一个使用2指法更高效的版本:只在第一场比赛后开始的比赛之间复制片段:
memmove
以下是没有调用char *strremove(char *str, const char *sub) {
char *p, *q, *r;
if ((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;
}
的相同方法:
{{1}}