我正在尝试创建一个小测试函数,当传递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)但是我将如何复制搜索到的术语之后的下一个“单词”?
总的来说,我需要一些伪代码逻辑来搜索句子中的搜索词,然后复制预先存在的数据,直到到达下一个空格。 (复制句子中搜索词之后的下一个词。)
答案 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是要扫描的字符串。针是要找到的词。 bgn
和end
参数是指针(输出),函数将设置为针后的单词的开头和单词的结尾加1。返回值为0(未找到任何单词)或1(找到一个单词)。如果返回*bgn == *end
并找到一个单词,那么之后就没有其他单词了。我选择不在大海捞针上指定const char *
,因为bgn
和end
将指向大海捞针中的位置,并且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。