C字符串搜索获取字符串的一部分

时间:2012-10-18 03:46:14

标签: c string search

我正在尝试创建一个小测试函数,当传递char *时,将搜索该字符串以查找某个子字符串,然后输出空格后的下一个字符,直到下一个空格。

我使用strstr()strncpy()进行了基本实现,但此方法是静态的,并且一次仅适用于一个搜索词,并且具有下一个字符的固定输出。

int ParseCommand(char *command)
{
    char *pSearch = strstr(command, CommandOne);
    char str[100];

    if (pSearch != NULL)
    {
        pSearch += strlen(CommandOne) + 1;
        strncpy(str, pSearch, 2);
        printf("%s\n\n", str);
    }

    printf("%s\n", command);
    return 0;
}

此代码示例的作用是,如果您传递说ParseCommand("ten hats 10 are cool")CommandOne等于"hats",则该函数将输出"10"。虽然这确实有效,但它会静态执行操作,并且很难在char *command内搜索更多命令。我基本上需要一些循环通过命令的东西,直到strstr()在传递的字符串中找到一个命令,然后将所有命令从命令后复制到下一个空白区域。

我知道如何搜索命令(我将使用我的所有搜索术语创建一个指针char数组并循环遍历它们直到strstr()不返回null)但是我将如何复制搜索到的术语之后的下一个“单词”?

总的来说,我需要一些伪代码逻辑来搜索句子中的搜索词,然后复制预先存在的数据,直到到达下一个空格。 (复制句子中搜索词之后的下一个词。)

3 个答案:

答案 0 :(得分:1)

我鞭打了一个快速的原型,似乎有效。

char *ParseCommand(char *command, char *find)
{
    char *p, *q, *t;

    p = strstr(command, find);

    if (p != NULL) {
        /* skip to the next word */
        for (q = p; *q != '\0' && *q != ' '; q++)
            ;
        if (*++q != '\0') {
            for (p = q; *q != '\0' && *q != ' '; q++)
                ;
            t = malloc(q - p);
            return strncpy(t, p, q - p);
        }
    }

    return NULL;
}

使用ParseCommand("ten hats 10 are cool", "hats")进行测试,然后返回10

HTH。

答案 1 :(得分:1)

一个问题是设计功能的接口;你得到的界面太简单了,尤其是你找到第一个字符串后需要拿起的界面。所以,我提出了一个更复杂的界面:

int find_word_following(char *haystack, const char *needle, char **bgn, char **end);

haystack是要扫描的字符串。针是要找到的词。 bgnend参数是指针(输出),函数将设置为针后的单词的开头和单词的结尾加1。返回值为0(未找到任何单词)或1(找到一个单词)。如果返回*bgn == *end并找到一个单词,那么之后就没有其他单词了。我选择不在大海捞针上指定const char *,因为bgnend将指向大海捞针中的位置,并且const-correctness变得混乱;但是,代码不会修改haystack。

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

int find_word_following(char *haystack, const char *needle, char **bgn, char **end);

int main(void)
{
    char *haystack = "ten hats 10 are cool";
    char *needle   = "hats";
    char *bgn;
    char *end;

    while (find_word_following(haystack, needle, &bgn, &end))
    {
        printf("Found <<%*.*s>>\n", (int)(end - bgn), (int)(end - bgn), bgn);
        needle = "are";  // Change search term
        haystack = end;  // Start where previous scan left off
    }
    return(0);
}

有了这么多规范,这个函数写起来并不是很难:

int find_word_following(char *haystack, const char *needle, char **bgn, char **end)
{
    assert(haystack != 0 && needle != 0 && bgn != 0 && end != 0);
    char *word = strstr(haystack, needle);

    if (word == 0)
        return(0);
    word += strlen(needle);
    // Skip to end of word (in case we found 'hatstand')
    while (*word != '\0' && !isspace(*word))
        word++;
    while (isspace(*word))   // Skip spaces after word
        word++;
    *bgn = word;             // Start of following word
    while (*word != '\0' && !isspace(*word))
        word++;
    *end = word;
    return(1);
}

您可以通过strspn()strcspn()的适当调用替换这些循环。

该计划的输出是:

Found <<10>>
Found <<cool>>

查找确切单词的变体是:

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

int find_word_following(char *haystack, const char *needle, char **bgn, char **end);

int find_word_following(char *haystack, const char *needle, char **bgn, char **end)
{
    assert(haystack != 0 && needle != 0 && bgn != 0 && end != 0);
    size_t length = strlen(needle);
    char *word;
    while ((word = strstr(haystack, needle)) != 0)
    {
        if ((word == haystack || (word > haystack && isspace(*(word - 1)))) &&
            isspace(word[length]))
        {

            word += length;
            while (isspace(*word))   // Skip spaces after word
                word++;
            *bgn = word;             // Start of following word
            while (*word != '\0' && !isspace(*word))
                word++;
            *end = word;
            return(1);
        }
        haystack = word + length;
    }
    return(0);
}

int main(void)
{
    char *haystack = "ten hatstands with hats on are OK";
    char *needle   = "hats";
    char *bgn;
    char *end;

    while (find_word_following(haystack, needle, &bgn, &end))
    {
        printf("Found <<%*.*s>>\n", (int)(end - bgn), (int)(end - bgn), bgn);
        needle = "are";  // Change search term
        haystack = end;  // Start where previous scan left off
    }
    return(0);
}

输出(注意不同的输入字符串)是:

Found <<on>>
Found <<OK>>

答案 2 :(得分:0)

为什么不使用strtok()来标记字符串?然后解析字符串以获取命令。

你可能需要一个语法(以递归下降的方式写)方式。

SPARKOT ADVICE EDIT(谢谢):如果您想要更快的字符串搜索算法,请查看Boyer-Moore Algorithm