删除字符串中括号之间的子字符串

时间:2018-05-13 21:24:58

标签: c string strtok

我需要删除括号中的每个子字符串。我找到了一些解决方案,但没有一个是好的。这是一个例子:

我的字符串是: text(lorem(ipsum)abcd)pieceoftext 和实际输出: lorem(ipsum

但是,预期输出: text(())pieceoftext textpieceoftext

这是代码。我已经没想完了。我想过使用strtok(),但我有两个不同的分隔符。

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

int main()
{
    const char *s = "text(lorem(ipsum)abcd)pieceoftext";
    const char *patternA = "(";
    const char *patternB = ")";
    char *target = NULL;
    char *start, *end;

    if (start = strstr( s, patternA ))
    {
        start += strlen( patternA);
        if (end = strstr( start, patternB ) )
        {
            target = (char *)malloc(end - start + 1);
            memcpy(target, start, end - start);
            target[end - start] = '\0';
        }
   }
   if (target)
      printf("Answer: %s\n", target);
   return 0;
}

期待听到您的一些想法来解决这个问题。谢谢

3 个答案:

答案 0 :(得分:2)

首先,只需为target分配足够的内存,因为您需要保留整个源字符串s,因为您根本不知道需要多少空间。请记住为字符串结尾字符添加一个。

然后将patternApatternBchar *更改为char,这样您就可以将它们与s中的各个字符进行比较。

然后你需要遍历源字符串,跟踪你是否在括号内。既然您需要支持嵌套括号,我会使用一个计数器来表示您在括号内的深度:

int main()
{
    const char *s = "text(lorem(ipsum)abcd)pieceoftext";
    const char patternA = '(';
    const char patternB = ')';
    char *target;
    int targetIndex = 0;
    int parenDepth = 0;

    target = malloc(strlen(s) + 1);
    // check for malloc() error

    for (int sourceIndex = 0; sourceIndex < strlen(s); sourceIndex++) {
        if (s[sourceIndex] == patternA) {
            // we are going deeper into parens, add to level, then ignore the char
            parenDepth++;
            continue;
        }

        if (s[sourceIndex] == patternB) {
            // we are coming out of the parens, lower our level, ignore the parens char
            parenDepth--;
            continue;
        }

        if (parenDepth == 0) {
            // if depth is 0, then we are not inside parens, so copy the char to target
            target[targetIndex++] = s[sourceIndex];
        }
    }

    // add end-of-string
    target[targetIndex] = '\0';

    printf("Answer: %s\n", target);

    return 0;
}

答案 1 :(得分:1)

我不明白为什么你不使用strtokstrtok_r)。我认为它更适用于此目的。只是稍微玩吧。

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

int main(void) {
    char str[] = "text(lorem(ipsum)abcd)pieceoftext";
    char const * delim = ")(";
    char *token;
    char *rest = str;

    while ((token = strtok_r(rest, delim, &rest))) {
         printf("token: %s\n", token);
         printf("rest: %s\n", rest);
    }
}

答案 2 :(得分:1)

您应该调查基本的解析技术,并使用它们来构建一个能够满足您需求的小型程序。

hello(world)world

一个简单的解决方案:

如果先行是开头,请停止保存。直到有一个闭幕式。当可能存在重叠的parens时,你只需要维护一个全局变量 deep (当有一个开始paren时递增,当有一个闭合paren时递减)。当此变量为零时,您可以保存。

您可以事先使用相同的模式来检查是否有足够的关闭数据。