一个问题是设计函数的接口;你得到的界面太简单了,特别是如果你找到第一个字符串后需要拿起。所以,我提出了一个更复杂的接口:
int find_word_following(char *haystack, const char *needle, char **bgn, char **end);
haystack 是要扫描的字符串。针是要找到的词。和参数是指针(输出),函数将其设置为针后单词的开头bgn
和end
单词的结尾加一。返回值为 0(未找到单词)或 1(找到单词)。如果*bgn == *end
在返回时找到了一个词,那么后面就没有另一个词了。我选择不在const char *
haystack 上指定,因为bgn
andend
将指向 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>>