1

我有几种可能的情况要测试strstr

if ((a = strstr(string, "FOO")) != NULL || (a = strstr(string, "BAR")) != NULL ||
    (a = strstr(string, "FOO2")) != NULL ||(a = strstr(string, "BAR2")) != NULL ||
    (a = strstr(string, "FOO3")) != NULL ||(a = strstr(string, "BAR3")) != NULL) // do something

然后根据发现我需要做的事情

 var = strlen("THE_ONE_MATCHED_ABOVE");

在不使用大量 if 语句的情况下,有什么好的方法可以做到这一点?

4

6 回答 6

2
int match_length( const char* string) {
/* return 0 if no match, otherwise strlen of match */

   static const char* const MATCHES[] = { "BAR2", "FOO2", "FOO3", "FOO", "BAR", "..." } ;
   // NB: MATCHES must be sorted in descending order of length (longest first).
   const char* r = 0;
   int i = 0 ;

   for( ; 
        i < sizeof(MATCHES) / sizeof(MATCHES[0]) 
        && ( r = strstr( string, MATCHES[i] ) ) == 0; 
        ++i );

   return r ? strlen( MATCHES[i] ) : 0 ;
}

注意:caf 提出了一个非常重要的观点:“您需要按长度降序排列 MATCHES - 如果 strstr(x, "FOO2") 不为空,那么 strstr(x, "FOO") 也是如此,所以您需要先找到前者。” 我已经编辑以反映这一点。根据此函数的使用,排序也可能在运行时完成。

于 2010-04-27T21:25:09.303 回答
2

您是否愿意使用逗号运算符:

if ((lookfor = "FOO", a = strstr(string, lookfor)) != NULL ||
    (lookfor = "BAR", a = strstr(string, lookfor)) != NULL ||
    ...)
{
    var = strlen(lookfor);
}

逗号运算符将允许您以从左到右的顺序评估多个表达式。整个表达式的值是最右边的 esub 表达式的值。

于 2010-04-27T21:20:53.090 回答
2

我觉得您的示例过于简单,但可能值得注意的是它可以简化。如果"FOO"找不到该字符串,那么您就知道该字符串"FOO2"不会被找到,因此您可以消除示例中除前两种情况之外的所有情况。

于 2010-04-27T22:16:08.347 回答
1

如果您在主题字符串中有很多模式要寻找,最好的选择是Aho-Corasick 算法

于 2010-04-27T21:47:55.917 回答
0

如果您需要以这种方式搜索大量不同的字符串,您可能应该使用正则表达式库并编译 DFA 以匹配(FOO|FOO2|FOO3|...). 这是最佳解决方案。您也可以自己制定树结构来实现相同的结果,特别是如果要搜索的字符串是常量并且您可以有效地对其进行硬编码。

于 2010-09-20T04:08:06.130 回答
-1

如果您在代码中经常使用该模式,您应该编写一个像这样的小辅助函数:

int FindFirstMatch(const char* stringItem, const char** stringList)
{
    int index = -1;
    int itemLength = strlen(stringItem);

    if (stringList == NULL)
    {
        return index;
    }

    for (; stringList[index] != NULL; index++)
    {
            if (  (strlen(stringList[index]) == itemLength)
               && (strstr(stringList[index], stringItem) != NULL))
        {
            break;
        }
    }
    return index;
}

该函数将一个字符串和一个NULL终止的字符串数组作为参数,并返回该字符串在列表中第一次出现的索引。然后,您可以使用索引来检查字符串长度。

要像您在示例中所做的那样进行检查,您将改为编写:

const char* itemList[] = {"FOO", "FOO2", "FOO3", "BAR", "BAR2", "BAR3", NULL};
int itemLength = 0;

int index = FindFirstMatch("BAR3", itemList);
if (index != -1)
{
    itemLength = strlen(itemList[index]);
}
于 2010-04-27T22:13:48.120 回答