【问题标题】:Search a string using 2 different delimiters - C Programming使用 2 个不同的分隔符搜索字符串 - C 语言编程
【发布时间】:2014-11-08 09:29:30
【问题描述】:

我想在 C 中搜索一串文本,找出文本位于 2 个不同分隔符之间的位置。我专门寻找介于 /* 和 */ 之间的 cmets。我找不到允许我使用 2 个不同分隔符的函数,每个分隔符 2 个字符长。

我目前有一个很长的 char[],我需要搜索它。我能找到的最接近的东西是 strstr 来查找“/*”的第一次出现,然后将其再次与“*/”一起使用。但是,这完全省略了整个注释,只给了我“*/”和其余代码。

char *pch;
char *pch2;
pch = strstr(wholeProgramStr, "/*");
printf("%s\n",pch);
pch2 = strstr(pch, "*/");
printf("%s\n",pch2);

有什么想法吗?和相同的问题,但在“//”和换行符之间。如果没有一些非常混乱和低效的代码,我找不到实现这一点的方法。

【问题讨论】:

  • 你使用strstr的想法基本不错。你想对找到的字符串做什么?你想处理(例如打印)它,你想从原始字符串中删除它吗?您可以修改原始字符串(如strtok 所做的那样)以在注释后放置一个终止空字符吗?分隔符是否应该包含在找到的字符串中?
  • 我基本上需要获取字符串并能够计算用于组成它的字符数量,不包括 /* */。我无法修改输入。谢谢
  • 好的,那么pch2 - (pch + 2) 会给你答案,其中2 是起始分隔符/*// 的字符串长度。 (您可能应该在pch + 2 开始搜索pch2,也可以捕捉退化评论/*/。并检查它们是否存在,否则您可以将NULL 传递给第二个strstr。)
  • 我将使用什么分隔符来换行。因为有些 cmets 以 // 开头并以换行符结尾
  • 在这种情况下,右分隔符是"\n",一个只包含换行符'\n'的字符串。

标签: c


【解决方案1】:

您使用strstr 的想法很好,但它不会为您提供以空值结尾的字符串。它通过指针运算为您提供指向字符串开头和字符串长度的指针。您可以通过在printf 中指定%s 格式的宽度来打印受长度限制的char 数组:

void str_print_between(const char *str, 
    const char *left, const char *right)
{
    const char *begin, *end;
    int len; 

    begin = strstr(str, left);
    if (begin == NULL) return;
    begin += strlen(left);

    end = strstr(begin, right);
    if (end == NULL) return;

    len = end - begin;
    printf("'%.*s'\n", len, begin);
}

根据您要执行的操作,您可以从函数中返回起始指针和长度(通过指针或struct)。有许多 strn* 函数与 str* 对应的函数等效,但需要额外的最大长度,因此您可以使用它们来进一步处理您的字符串。

处理行 cmets 的工作方式与处理块 cmets 相同,只是使用其他分隔符。 (但这个简单的解决方案没有注意上下文;例如,它将检测字符串中或跨字符串的 cmets。)

【讨论】:

    【解决方案2】:
    char *tmp = strdup(wholeProgramStr); /* makes a copy to be writeable */
    char *pch;
    char *pch2;
    
    pch = strstr(tmp, "/*"); /* pointer to first occurrence */
    if (pch) { /* founded */
        pch += 2; /* skip "/*" */
        pch2 = strstr(pch, "*/"); /* pointer to second occurrence */
        if (pch2) { /* founded */
            *pch2 = '\0'; /* cut */
            printf("%s\n", pch);
        }
    }
    

    正如@alk所指出的,如果只需要打印结果,则不需要复制字符串:

    char *pch;
    char *pch2;
    
    pch = strstr(wholeProgramStr, "/*"); /* pointer to first occurrence */
    if (pch) { /* founded */
        pch += 2; /* skip "/*" */
        pch2 = strstr(pch, "*/"); /* pointer to second occurrence */
        if (pch2) { /* founded */
            printf("%*s\n", pch2 - pch, pch));
        }
    }
    

    编辑:

    我将如何再次运行它直到它到达字符串的末尾?所以 它可以找到多个cmets?

    循环直到找不到两个分隔符:

    char *tmp = wholeProgramStr;
    char *pch;
    
    while (1) {
        pch = strstr(tmp, "/*"); /* pointer to first occurrence */
        if (pch) { /* founded */
            pch += 2; // skip "/*"
            tmp = strstr(pch, "*/"); /* pointer to second occurrence */
            if (tmp) { /* founded */
                printf("%*s\n", tmp - pch, pch));
                tmp += 2; // skip "*/"
            } else break;
        } else break;
    }
    

    【讨论】:

    • 这是完美的。你能解释一下这里发生了什么吗?
    • 为什么要重复?你可以使用... "%*s\n", pch2-pch-2, pch)。只打印出一些评论。
    • 我将如何再次运行它直到它到达字符串的末尾?所以它可以找到多个cmets?
    • 你能解释一下 if(pch) 是什么意思吗?我不明白你所说的成立是什么意思?
    • if (pch) --> if (pch != NULL) --> 如果字符串包含分隔符
    猜你喜欢
    • 2014-09-29
    • 1970-01-01
    • 2014-08-31
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多