文字列から文字列を探す | Programming Place Plus C言語編 逆引き

トップページC言語編逆引き

このページの概要

以下は目次です。

目的

文字列の中から、任意の文字列を探したいとします。たとえば、“abcde” から ‘cde’ を探すにはどうすればいいでしょう?

単に、その文字列があるかないかではなく、その位置を指すポインタを返す解決方法を取り上げます。そうすれば、位置が欲しいケースにも対応できますし、あるかないかだけを知りたい場合でも、ヌルポインタかどうかで判断することができます。また、ポインタの減算(第32章)を使えば、何文字目だったのかを知ることもできます。

/*
    文字列から文字列を探す。

    引数
        s: 対象の文字列
        target: 探す文字列
    戻り値
        見つかったら、その文字列の先頭の文字のメモリアドレス。
        見つからなかったらヌルポインタ。
*/
char* find_string(const char* s, const char* target);


int main(void)
{
    const char s[] = "abcde";

    // 位置が欲しい
    char* p = find_string(s, "bcd");

    // あるかないかが知りたい
    bool is_found = (find_string(s, "bcd") != NULL);

    // 何文字目にあったか
    if (p != NULL) {
        ptrdiff_t index = p - s;
    }
}

また、この手の処理では、該当する文字列が複数個含まれている可能性も考えておかなければなりません。“abcdeabcde” から “bcd” を探したら、どちらの “bcd” の位置が返されるべきでしょうか?

その答えは、“そのときによる” としかいえません。先頭に近いものを返してほしいこともあるでしょうし、末尾に近いもの(最後に見つかったもの)を返してほしいかもしれません。どうでもいいというケースもあります。本当に必要なことは、きちんと仕様を決めておくことです。

ここでは、先頭に近い文字列の位置を返すという仕様にします。

末尾に近いものを探す方法は、「逆引き 文字列の後ろの方から文字列を探す」で取り上げています。

方法①(strstr関数を使う)

標準ライブラリには、この目的に合った strstr関数があります。strstr関数は、string.h で宣言されています。

実のところ、これを使うだけですべて解決します。冒頭で、find_string関数にまとめるような感じで考えましたが、strstr関数をそのまま使うのでも問題ありません。自作の関数でラップするのなら、インライン関数(第57章)にして高速化を図るといいでしょう。

#include <stdio.h>
#include <string.h>

/*
    文字列から文字列を探す。

    引数
        s: 対象の文字列
        target: 探す文字列
    戻り値
        見つかったら、その文字列の先頭の文字のメモリアドレス。
        見つからなかったらヌルポインタ。
*/
inline char* find_string(const char* s, const char* target)
{
    return strstr(s, target);
}


int main(void)
{
    const char s[] = "abcdeabcde";

    char* p = find_string(s, "bcd");
    if (p == NULL) {
        puts("not found");
    }
    else {
        printf("found. (%td)\n", p - s);
    }
}

実行結果:

found. (1)


参考リンク


更新履歴



逆引きのトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る