C++ での文字列の find() の使い方はどうしましたか?

この記事では、C++でStringのfind()をどのように使用できるかを見ていきます。

もし文字列内に別の文字列が含まれているかを確認したい場合、std::string.find() メソッドは非常に便利です。このメソッドの使い方をいくつかの例を交えて理解しましょう!


C++のstring find()の構文

この方法はC++の文字列クラス(std::string)に属しています。したがって、ヘッダーファイルを含める必要があります。

別の文字列を引数として、このメソッドを文字列オブジェクトに適用する必要があります。

その後、find()メソッドは与えられた文字列が私たちの文字列内にあるかどうかを確認します。このメソッドは、’\0′ 終端文字を含むサブストリングのサイズ(サイズ_tで返されます)。しかし、もし文字列が私たちの元の文字列内に存在しない場合、0を返します。

それによって、その関数は次のように定義されます。 (Sore ni yotte, sono kansū wa tsugi no yō ni tei shimasu.)

size_t find(const std::string& my_string, size_t pos = 0);

始点を検索するための追加パラメータposが1つあります。

デフォルトでは、0ですので、明示的に開始位置を指定しない限り、検索は文字列の先頭から行われます。

また、文字列はconst参照で渡されることに注意してください。

文字列を変更しないため、一時的な文字列を作成する時間を無駄にしないように、参照を直接操作する方が合理的です。

C++20以降、多くの標準ライブラリメソッドはconstexpr互換性を持つため、コンパイル時に実行されます。constexprの詳細については、オンラインでさらに詳しく読むことができます。

いくつかの関数オーバーロードがありますが、詳細はこのページを参照していただければと思いますので、スキップします。代わりに、サブストリングの長さに関わる特定のオーバーロードに焦点を当てましょう。

size_t find( const Char* s, size_type pos, size_type count )

この特定のオーバーロードは、部分文字列が文字列内に存在するかどうかをチェックしますが、同時に部分文字列の長さに制限もあります。これにより、指定された数の文字まで一致します。

ただし、これはstd::stringには使用できません。原型の中に「const Char*」があることに注意してください。したがって、これはCスタイルの文字列にのみ使用することができます。

例えば、この関数に「Hello」の部分文字列「Hell」を渡した場合。

std::cout << "Hello".find("Hell", 0, 3) << std::endl;

これは「Hello」の最初から3文字だけをマッチさせるため、出力としては5バイトではなく、わずか4バイトしか得られません。

さて、学んだことを理解するためにいくつかの例を見てみましょう。


C++でstring.find()を使用する

デフォルトの呼び出しを見てみましょう。pos=0の場合、文字列の先頭から全ての部分文字列を検索します。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length = my_str.find(target_string);
    if (substring_length == 0)
        std::cout << "No\n";
    else
        std::cout << "Length of matched substring = " << substring_length << std::endl;

    return 0;
}

出力:

Is JournalDev a substring of Hello from JournalDev ?
Length of matched substring = 11

見ての通り、サブストリングは確かに私たちの元の文字列の中にあります!

今から文字列の特定の位置から同じ部分文字列を検索しましょう。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length = my_str.find(target_string, 12); // Start from index 12 (from my_str[12])
    if (substring_length == 0)
        std::cout << "No\n";
    else
        std::cout << "Length of matched substring = " << substring_length << std::endl;

    return 0;
}

出力する

Is JournalDev a substring of Hello from JournalDev ?
Length of matched substring = 18446744073709551615

なぜこんな奇妙な出力が得られるのか?実は、元の文字列のインデックス12から始めて、その位置からの部分文字列の長さが元の文字列の長さを超えてしまうからです!

したがって、私たちは文字列の末尾に到達した後、ゴミの場所に移動します。find()は文字列の終わりを越えるので、それを心に留めておいてください。

したがって、文字列の終わりに到達したかどうかを確認することで、この危険な状態を修正します。

C++にはstd::string::nposという特別な変数があります。それは現在の文字列へのハンドルを返し、文字列の終端に到達したかどうかを検出するために使用することができます。

if (my_str.find(target_str) != std::string::npos) {
    // This matches! We're still within the original string
}
else {
    // Oops! Out of bounds. Print error message!
}

この変更により、私たちのコードは次のようになります。 (Kono henkō ni yori, watashitachi no kōdo wa tsugi no yō ni narimasu.)

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length;
    if ((substring_length = my_str.find(target_string, 12)) != std::string::npos) {
        std::cout << "Length of matched substring = " << substring_length << std::endl;
    }
    else {
        std::cout << "No\n";
    }

    return 0;
}

出力

Is JournalDev a substring of Hello from JournalDev ?
No

今、私たちは期待通りの出力を得ます、なぜなら、インデックス12から始めるからです!

このチェックを使って、find()の他のオーバーロードされた形式をカウントで表示しましょう。C++の文字列には直接この形式を使用できないことを忘れないでください。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("Journ_kkfffsfsfskkk");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length;
    // Use a count to match only 5 characters
    // Note that we can use this form only for const char* strings
    if ((substring_length = my_str.find("Journ_kkfffsfsfskkk", 0, 5)) != std::string::npos) {
        std::cout << "Length of matched substring = " << substring_length << std::endl;
    }
    else {
        std::cout << "No\n";
    }

    return 0;
}

出力

Is Journ_kkfffsfsfskkk a substring of Hello from JournalDev ?
Length of matched substring = 11

私たちの対象文字列が変更されたことに注意してください。ここでは、最初の5文字だけが一致しますが、それは5つの制限カウンターを設定しているため、find()には十分です!

それによって、ターゲットのサブストリングの残り部分は単純に無視され、オリジナルの文字列の終わりまで一致が続けられます。

それが理由なので、私たちはまだ11を得ているのです。なぜなら、そこに部分文字列の一致が見つかるからです。


結論

これらの例をすべて使用して、C++のstring.find()メソッドを簡単に使い始める方法が理解できたと思います。もし疑問点があれば、以下のコメント欄で質問してください!

また、私たちのチュートリアルセクションにあるC++に関連する他の記事もぜひご覧ください!


参考文献

  • cppreference.com page on using string find() in C++
  • StackOverflow question on string find()

コメントを残す 0

Your email address will not be published. Required fields are marked *