【问题标题】:How can I find the nth substring in between two substrings in C?如何在 C 中的两个子字符串之间找到第 n 个子字符串?
【发布时间】:2018-04-10 02:41:48
【问题描述】:

我正在使用这个函数来获取两个子字符串之间的子字符串。

char * extract_between(const char *str, const char *p1, const char *p2/*, const int instance*/)
{
   //int count;
   const char *i1 = strstr(str, p1);
   /*for (count = 0; ; ++count) {
        const char *i1 = strstr(str, p1);
        if (count==instance)
            break;
   }*/
   if(i1 != NULL)
   {
      const size_t pl1 = strlen(p1);
      const char *i2 = strstr(i1 + pl1, p2);
      if(p2 != NULL)
      {
         /* Found both markers, extract text. */
         const size_t mlen = i2 - (i1 + pl1);
         char *ret = malloc(mlen + 1);
         if(ret != NULL)
         {
            memcpy(ret, i1 + pl1, mlen);
            ret[mlen] = '\0';
            return ret;
         }
      }
   }
   return 0;
}

我想修改它,以便它本身搜索子字符串的第 n 个实例。这怎么可能?我试过 for(count) 但我不确定如何格式化它。

【问题讨论】:

  • 请发布一些示例,以明确您的目标。
  • 因为strstr 定位第一个匹配项,您将不得不使用strstr 来定位第一个指针,然后将源字符串从该位置开始,然后再次使用strstr新的、较短的字符串,然后重复 instance 次数。
  • 顺便说一句,这个函数可能是递归的好候选;每次将较短的字符串和instance-1 传递给自身。

标签: c string substring instance


【解决方案1】:

这对你有用吗?

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

char*
extract_between (const char* str, const char* p1, const char* p2, int instance)
{
  int count = -1;
  const char* i1 = str - 1;
  for (; count < instance; ++count) {
        i1 = strstr(i1 + 1, p1);
        if (i1 == NULL)
            return NULL;
  }
  const size_t pl1 = strlen(p1);
  const char* i2 = strstr(i1 + pl1, p2);
  if (i2 != NULL)
  {
    /* Found both markers, extract text. */
    const size_t mlen = i2 - (i1 + pl1);
    char* ret = malloc(mlen + 1);
    if (ret != NULL)
    {
      memcpy(ret, i1 + pl1, mlen);
      ret[mlen] = '\0';
      return ret;
    }
  }
  return NULL;
}

示例运行:

extract_between("foobarbaz", "foo", "bar", 0) = ""
extract_between("foobarbaz", "foo", "bar", 1) = NULL
extract_between("foobarbaz", "foo", "baz", 0) = "bar"
extract_between("foobarfoobarbaz", "foo", "bar", 1) = ""
extract_between("foobarfoobarbaz", "foo", "baz", 1) = "bar"
extract_between("foofoofoobarfoo", "foo", "bar", 2) = ""
extract_between("foofoofoobarfoo", "foo", "foo", 2) = "bar"
extract_between("foofoofoobarfoo", "foo", "bar", 3) = NULL

【讨论】:

  • 将您的break 替换为return NULL; 消除了到达return NULL; 的剩余不必要的测试。虽然在使用中是合法的,但如果在增加指针地址之前曾引用过 i1const char* i1 = str - 1; 将调用 Undefined Behavior
  • 好点,谢谢!我按照您的建议删除了不必要的测试。我不确定i1 是两行的定时炸弹该怎么办。
  • 我不完全确定您所说的 i1 的“定时炸弹”是什么意思,但代码运行良好,谢谢!
  • 哦,只是i1在递减后,一定不能解引用,直到再次递增。代码很好,更多的是可维护性评论。
  • 啊,好的。感谢您清除它。呃,这可能听起来像一个菜鸟问题,但是当我做if (extract_between(&lt;variables&gt;) == "foo") {} 时,它给了我一个关于比较文字字符串的错误。这可能是什么?我仍然对 C 很粗暴
猜你喜欢
  • 2018-11-21
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
相关资源
最近更新 更多