【问题标题】:Remove a substring from a string in C从C中的字符串中删除子字符串
【发布时间】:2017-11-05 00:19:45
【问题描述】:

我想从一个字符串中删除一个特定的子字符串,例如我的主字符串是"ababccdabce",我想从中删除"abc",这样它就会变成"abcde"

我只是想知道C中是否有一个预定义的函数可以做到这一点,如果没有,怎么做?

【问题讨论】:

标签: c string


【解决方案1】:

C 中没有预定义的函数可以从 C 字符串中删除给定的子字符串,但您可以使用 strstrmemmove 编写一个函数。请注意,如果您在适当位置删除子字符串,则不能使用 memcpystrcpy,因为如果源数组和目标数组重叠,它们的行为未定义。

代码如下:

#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;
}

【讨论】:

  • 您可以通过缓存str 长度来减少strlen 调用的数量,每次删除sub 时都会减少它
  • @Netherwire: 好点子,但它使代码更麻烦,特别是如果没有匹配项时想要避免计算strlen(str)。谢谢你取笑我......我找到了一个更好的解决方案:)
  • Signal: SIGSEGV (Segmentation fault) :)
  • @r1v3n:我修复了 sub 是空字符串的特殊情况。可能还有其他错误,您能否更具体地告诉我导致段错误的参数是什么?
猜你喜欢
  • 2011-10-15
  • 2020-10-28
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2015-02-03
相关资源
最近更新 更多