2012-10-18 113 views
0

我想做一个小的测试函数,当通过char *将搜索该字符串的某个子字符串,然后输出空白后的下一个字符,直到下一个空白。C字符串搜索获取字符串的一部分

我使用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()在传递的字符串中找到一个命令,然后将命令后的所有内容复制到下一个空格。我将如何搜索命令(我将用我所有的搜索词创建一个指针字符数组,并循环遍历它们直到strstr()不会返回null),但如何复制下一个“单词” “搜索词后?

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

+0

由于该函数只返回0,它可能我是'空'。您可以通过传递要找到的字符串(针)以及要搜索的字符串(干草堆)来概括该函数。如果命令长度为几百个字符并且匹配接近开始,则应该担心缓冲区溢出。您应该能够打印字符串而不需要复制子字符串('printf(“%*。* s \ n \ n”,nbytes,nbytes,str);''nbytes'的类型必须是'int'。目前还不清楚你在哪里跳过空格(例如,如果'帽子'和'10'之间有几个空格) –

+0

'帽子'需要匹配一个单词还是可以匹配部分一个字? –

+0

@JonathanLeffler这只是一个测试函数,当我创建真正的函数时,我会小心溢出,是的,它必须匹配整个单词,它也应该跳过所有的空格,直到下一个“单词找到“例如:如果我通过”十顶帽子10928很酷“输出仍应寻找”帽子“,并返回”10928“编辑:由于某种原因,空白不显示在我会通过什么引号...只是想象一下在“帽子”和“10928”之间有8-10个空格 –

回答

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。

+0

正是我需要的。感谢分配 –

+0

@bobmoch它可能是因为跨越了终止字符。我会建议你看看乔纳森的实施,这是更好,并避免这样的问题。 – g13n

+0

非常感谢你的提示。如果它甚至是一个提示...反正我只是memset指针'\ 0',并修复它。谢谢。 –

0

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

您可能需要一个语法(用递归下降法写)。

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

+0

想象一下,在100个单词的段落中只有一个命令。 – SparKot

+0

是的,我想过使用strtok,但后来我想到了什么sparkot说。 –

+0

是的,这是一个很好的建议 –

1

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

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

干草堆是要扫描的字符串。针是被发现的词。参数bgnend是指针(输出),函数将设置为针的后面的单词的开始,单词的结尾加1。返回值是0(没有找到单词)或1(找到一个单词)。如果返回时发现*bgn == *end,并且找到一个单词,那么之后就没有另一个单词。我选择不在干草堆上指定const char *,因为bgnend将指向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>> 
+0

这是一个很棒的实现和解释#hatsoff – g13n