【问题标题】:Pure C: trim all characters in a string after a word occurs纯C:在单词出现后修剪字符串中的所有字符
【发布时间】:2014-01-10 16:37:12
【问题描述】:

我在 C 中有一个字符数组,它可以有一个值,例如 /path/example/abc。我想要它,以便/path/example/ 部分之后的任何字符都被吞噬,重新分配字符串以适应其新大小。有没有一个标准函数,或者你可以编写的函数来完成这个?也许这可以通过像 PCRE 这样的库来完成? 注意:欢迎使用纯的、独立于平台的 C 代码。

示例

int main()
{
    char str[100] = "I am a string";
    newStr = globbleAfter(str, "I am a");
    printf("%s\n", newStr); 
    return 0;
}

//=> "I am a"

【问题讨论】:

    标签: c string character


    【解决方案1】:

    PRCE 似乎对此有点过分了。只需使用 strstr 在 str 中查找 newStr。示例:

    char *gobbleAfter(char *string, char *pattern) {
        int len;
        char *gobbled;
        char *pos=strstr(string, pattern);
        if (pos==NULL)
            return NULL;
        if ((gobbled=malloc(len=((pos-string)+strlen(pos)+1)))==NULL)
            return NULL; /* or maybe call an out of memory handler */
        memcpy(gobbled, string, len-2);
        gobbled[len-1]='\0';
        return gobbled;
    }
    

    【讨论】:

      【解决方案2】:

      由于像 printf 这样的函数适用于以零结尾的字符串,因此将第一个不需要的字符设置为零就足够了。像str[strlen("I am a")] = 0 这样的东西。它虽然修改了原始字符串。最重要的是它不安全 - 在设置为零之前,您应该检查子字符串的长度是否不大于原始字符串的长度。

      【讨论】:

        【解决方案3】:

        @Wojtek Surowka 如果不检查原始字符串中的模式,则可能存在模式不包含在原始字符串中的情况。如果在字符串中的某个偏移处找到模式,也会出现问题。

        String = "bob is running"
        Pattern1 = "frank"
        Pattern2 = "is run"
        

        @Guntram Blohm 在你 malloc 之后什么时候释放分配的内存?

        if ((gobbled=malloc(len=((pos-string)+strlen(pos)+1)))==NULL)

        此方法依赖于 src 少于 260 个字符。它不会改变原始字符串。

        这个函数不正确

        #define MAX_PATH 260
        char* gobbleAfter(const char* src, const char* pattern)
        {
          int len = strlen(pattern);
          int cpy_len;
          char[MAX_PATH] gobbled_string;
          char* pos = strstr(src, pattern);
        
          gobbled_string[0] = '\0';
        
          if(pos)//null check
          {
            cpy_len = (pos - string) + len + 1
            if(cpy_len <= MAX_PATH)
            {
              memcpy(gobbled_string, src, cpy_len);
            }
          }
          return gobbled_string;
        }
        

        如果您不介意更改来源

        char* gobbleAfter(char* src, const char* pattern)
        {
          char* gobbled_string = NULL;
          char* temp = strstr(src, pattern);
          if(temp)
          {
            gobbled_string = src;
            gobbled_string[temp - src + strlen(pattern)] = '\0';
          }
          return gobbled_string;
        }
        

        【讨论】:

        • 巴克,您的 char[MAX_PATH] 将在堆栈上分配字符串,一旦调用函数调用其他内容,它将被覆盖。对于您的问题“我什么时候释放分配的内存?”:我没有。当调用者不再需要该字符串时,调用者负责执行此操作,显然,该函数不知道何时。我也无法释放原始字符串,因为它甚至可能一开始就没有被 x分配。
        • Guntram,你是对的。 gobbled_string 将在堆栈上分配并被覆盖,这是我的错误。通常,当我创建这些小的辅助函数时,我会尽量避免分配我没有释放的内存,因此用户不必跟踪他们没有分配的内存。
        • 当你试图避免这种情况时你是对的,因为用这种方式引入内存泄漏太容易了。我同意“用户在停止使用返回的字符串时必须释放它”属于此类函数的文档。不幸的是,没有真正的选择,因为调用者不知道返回字符串的长度,所以你不能让他提供一个适当大小的预分配字符串。像这样的事情,你做不好,你可以试着决定哪个邪恶最小。
        猜你喜欢
        • 2022-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        • 2017-11-01
        相关资源
        最近更新 更多