0

我正在尝试制作一个小型测试函数,当通过 a 时,char *它将在该字符串中搜索某个子字符串,然后在空格之后输出下一个字符,直到下一个空格。

strstr()我使用and做了一个基本的实现,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;
}

此代码示例的作用是,如果您通过 say ParseCommand("ten hats 10 are cool")and CommandOneis equal"hats"函数将输出"10"。虽然这确实有效,但它执行的操作过于静态,并且很难在char *command. 我本质上需要一些可以遍历命令的东西,直到strstr()在传递的字符串中找到一个命令,然后将命令之后的所有内容复制到下一个空格。

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

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

4

3 回答 3

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。

于 2012-10-18T04:09:50.353 回答
1

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

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

haystack 是要扫描的字符串。针是要找到的词。和参数是指针(输出),函数将其设置为针后单词的开头bgnend单词的结尾加一。返回值为 0(未找到单词)或 1(找到单词)。如果*bgn == *end在返回时找到了一个词,那么后面就没有另一个词了。我选择不在const char *haystack 上指定,因为bgnandend将指向 haystack 中的位置,并且 const 正确性变得混乱;不过,该代码不会修改 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()and来替换这些循环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>>
于 2012-10-18T04:30:27.060 回答
0

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

您可能需要一种语法(以递归下降方式编写)。

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

于 2012-10-18T04:09:09.953 回答