1 つの問題は、関数へのインターフェイスの設計です。特に最初の文字列を見つけた後に取得する必要がある場合は、インターフェイスが単純すぎます。そこで、より複雑なインターフェースを提案します。
int find_word_following(char *haystack, const char *needle, char **bgn, char **end);
haystack は、スキャンされる文字列です。針は見つける言葉です。および引数はポインタ (出力) であり、関数が針の後の単語の開始点と単語の終了点に 1 を加えた位置に設定しますbgn
。end
戻り値は 0 (単語が見つからない) または 1 (単語が見つかった) です。戻って単語が見つかった場合*bgn == *end
、その後に別の単語はありませんでした。と が干し草の山内の場所を指し、const-correctness が乱雑になるため、const char *
干し草の山で指定しないことを選択しました。ただし、コードは干し草の山を変更しません。bgn
end
#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>>