【问题标题】:Remove a substring in C given positions of substring删除 C 中给定子字符串位置的子字符串
【发布时间】:2012-09-15 19:06:52
【问题描述】:

假设我有一个包含 20 个字符的 char *example。我想删除从example[5]example[10] 的每个字符,然后修复数组,使example[11] 紧跟在example[4] 之后。

基本上将删除区域之后的所有字符移动到删除区域开始的时间。

有什么想法吗?

编辑:我认为可能有一种使用 memcpy 的方法?但我不知道该怎么做。

【问题讨论】:

  • memcpy() 仅适用于非重叠数组。你需要 memmove()。

标签: c arrays string char substring


【解决方案1】:

您不能可靠地使用memcpy(),因为源和目标之间存在重叠;你可以使用memmove()。由于您知道长度,因此您可以使用:

memmove(&example[5], &example[11], (20 - 11 + 1));

记住你也需要复制空终止符。

#include <string.h>
#include <stdio.h>

int main(void)
{
    char array[] = "abcdefghijklmnopqrst";
    char *example = array;
    printf("%.2zu: <<%s>>\n", strlen(example), example);
    memmove(&example[5], &example[11], (20 - 11 + 1));
    printf("%.2zu: <<%s>>\n", strlen(example), example);
    return(0);
}

使用 C99 编译器编译,产生:

20: <<abcdefghijklmnopqrst>>
14: <<abcdelmnopqrst>>

如果您有 C89 编译器(更具体地说,是 C 库),您将不得不担心格式字符串中的 z,它表示 size_t 参数。删除z 并将strlen() 的结果转换为(unsigned) 是最简单的。

【讨论】:

    【解决方案2】:

    剧透:

    void cut_the_string(char *str, size_t cutpos, size_t cutlen)
    {
      size_t len;
    
      len = strlen(str);
    
      if (cutpos >= len) return;
      if (cutpos + cutlen > len) cutlen = len-cutpos;
    
      memmove( str+cutpos, str+cutpos+cutlen, 1+len - cutpos - cutlen);
    
      return;
    }
    

    【讨论】:

      【解决方案3】:
      1. 在循环中移动字符或
      2. 复制字符示例+11..示例+20,粘贴到示例+4 或
      3. ....

      【讨论】:

        【解决方案4】:

        有什么想法吗?

        我会准备一个并行​​数组,从源数组中复制所有字符,但忽略指定范围内的那些字符。或者,如果源数组不在堆栈上,可以释放它使用的内存。

        【讨论】:

          【解决方案5】:
          memmove(&example[5], &example[11], strlen(example) - 11 + 1);
          

          注意memcpy在内存块重叠时的行为是不确定的,所以memmove在这里更合适。

          【讨论】:

            猜你喜欢
            • 2011-12-08
            • 1970-01-01
            • 1970-01-01
            • 2021-04-07
            • 2015-11-20
            • 1970-01-01
            • 2015-10-02
            相关资源
            最近更新 更多