初心者でもわかる!C++のstrstr関数の使い方5選

C++のstrstr関数を使ったプログラミングのイメージC++
この記事は約16分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事はC++のstrstr関数について、その使い方から応用テクニックまで詳しく解説することを目的としています。

strstr関数は、特定の文字列を検索する際に非常に便利な標準ライブラリ関数であり、これをマスターすることで、文字列操作の技術が一段と向上します。

初心者から中級者まで、幅広い読者に向けて、分かりやすく実用的な情報を提供するために、基本的な説明から始めて、具体的なサンプルコードを交えながら進めていきます。

●strstr関数とは

strstr関数は、C++で使用される標準ライブラリの一部であり、ある文字列(親文字列)の中から別の文字列(検索文字列)を見つけ出すために使用されます。

この関数の戻り値は、検索文字列が見つかった場合にはその位置を指すポインタを返し、見つからない場合にはNULLを返します。

このシンプルながら強力な機能により、ログ分析からユーザー入力の検証まで、さまざまな場面で活用されています。

○strstr関数の基本概要

具体的には、strstr関数は次の形で定義できます。

char *strstr(const char *haystack, const char *needle);

ここで、haystackは親文字列(検索対象の文字列)、needleは検索したい文字列です。

この関数を使う際の主な利点は、その実装のシンプルさと、複雑なアルゴリズムを自分で書く必要がないことにあります。

例えば、ある特定のキーワードがログファイルに存在するかどうかをチェックする場合などに役立ちます。

○なぜstrstr関数が重要か?

strstr関数の重要性は、その汎用性にあります。

テキスト処理はほぼすべてのプログラミングプロジェクトで必要とされるため、効率的な文字列検索方法を知っておくことは、多くの場面で役立ちます。

特に、大量のデータを扱うアプリケーションでは、この関数を適切に使用することで、パフォーマンスの向上が期待できるため、データベースクエリ、データ分析、さらにはリアルタイムシステムでの使用が考えられます。

また、プログラミングを学ぶ上での理解を深めるためにも、このような基本的な関数の動作原理を学ぶことは非常に有効です。

●strstr関数の基本的な使い方

strstr関数を効果的に使用するためには、まずはその基本的な動作を理解することが重要です。こ

の関数を使用する主な目的は、一つの長い文字列(親文字列)の中から別の短い文字列(検索文字列)を見つけ出すことです。

例えば、ユーザーが入力したテキストから特定の単語を検索する際に非常に役立ちます。

実際にコードを見てみましょう。

この例では、親文字列 haystack の中から、検索文字列 needle を見つける簡単なデモンストレーションを行っています。

#include <iostream>
#include <cstring> // strstrを使うために必要

int main() {
    const char *haystack = "Here is a simple string";
    const char *needle = "simple";

    char *result = strstr(haystack, needle);

    if (result != nullptr) {
        std::cout << "Found '" << needle << "' in '" << haystack << "'" << std::endl;
    } else {
        std::cout << "The string '" << needle << "' was not found." << std::endl;
    }

    return 0;
}

このコードは、strstr 関数を使って haystack の中から needle を検索し、見つかった場合はその位置を表示します。

見つからなかった場合は、その旨をユーザーに通知します。これが strstr 関数の最も基本的な使い方です。

○サンプルコード1:文字列内の特定の文字列を検索する基本的な使い方

次に、さらに具体的な使用例を見てみましょう。

ウェブサイトのログから特定のエラーメッセージを探す場合などに、この関数がどのように役立つかを紹介します。

#include <iostream>
#include <cstring>

int main() {
    const char *log = "Error: 404 not found. Error: 500 internal server error.";
    const char *search = "Error";

    char *ptr = strstr(log, search);
    while (ptr != nullptr) {
        std::cout << "Error found at position: " << (ptr - log) << std::endl;
        ptr = strstr(ptr + 1, search); // 次のエラーを検索
    }

    return 0;
}

このサンプルコードでは、ログ文字列 log 内のすべての “Error” を検索し、その位置を出力しています。

strstr 関数をループ内で再度呼び出すことで、複数のエラーメッセージが存在する場合にそれぞれを検出することができます。

○サンプルコード2:strstr関数を使ってデータをフィルタリングする方法

さらに応用として、データをフィルタリングする際に strstr 関数を使う方法を見てみましょう。

例えば、特定のキーワードに基づいてテキストデータから情報を抽出することが考えられます。

#include <iostream>
#include <cstring>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> messages = {
        "Meeting today at 3 PM",
        "Reminder: submit your report",
        "Lunch at noon",
        "Meeting tomorrow at 10 AM"
    };
    const char *keyword = "Meeting";

    for (const auto &message : messages) {
        if (strstr(message.c_str(), keyword)) {
            std::cout << "Meeting schedule: " << message << std::endl;
        }
    }

    return 0;
}

この例では、文字列のリスト messages から “Meeting” という単語が含まれるメッセージだけを選択して表示しています。

これにより、ミーティングに関連する通知だけを簡単にフィルタリングすることができます。

●strstr関数の応用例

strstr関数はその基本的な機能だけでなく、さまざまな応用が可能です。

特にデータ解析や処理において、その柔軟性を活かすことができます。

ここでは、より高度なテクニックとして、ログファイルの解析や動的な検索機能、さらにはテキストデータのパースについて説明します。

○サンプルコード3:ログファイルから特定のエラーコードを検索する

サーバーのログファイルには多くの情報が含まれていますが、特定のエラーコードを素早く見つけることはシステム管理には欠かせません。

このコードは、ログファイルから特定のエラーコードを探し出しています。

#include <iostream>
#include <cstring>
#include <fstream>
#include <string>

int main() {
    std::ifstream file("server.log");
    std::string line;
    const char *search = "Error 500";

    while (getline(file, line)) {
        if (strstr(line.c_str(), search)) {
            std::cout << "Error 500 found: " << line << std::endl;
        }
    }

    return 0;
}

このプログラムでは、ファイルから一行ずつ読み取り、指定されたエラーコードを含む行を探しています。

これにより、特定のエラーが発生した事象を迅速に特定することが可能になります。

○サンプルコード4:ユーザ入力から指定のキーワードを検索する動的な検索機能

ウェブアプリケーションやデータベースシステムでは、ユーザーが入力したキーワードに基づいて情報を検索する機能が必要です。

strstr関数を利用して、このような動的な検索機能を実装することができます。

#include <iostream>
#include <cstring>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> database = {"Apple", "Banana", "Cherry", "Date"};
    std::string input;
    std::cout << "Enter search term: ";
    std::cin >> input;

    for (const auto &item : database) {
        if (strstr(item.c_str(), input.c_str())) {
            std::cout << "Found: " << item << std::endl;
        }
    }

    return 0;
}

このコードは、ユーザーが提供したキーワードでデータベース内を検索し、一致する項目を表示します。

動的な検索は、特に大規模なデータセットにおいて、情報のアクセシビリティを向上させるために役立ちます。

○サンプルコード5:strstr関数を使ったテキストデータのパース方法

テキストデータから特定の情報を抽出するためには、パース処理がしばしば必要になります。

strstr関数を使うと、このようなテキストデータのパースも効率的に行えます。

#include <iostream>
#include <cstring>

int main() {
    const char *data = "Name: John Doe; Age: 30; Occupation: Developer;";
    const char *delimiter = ";";
    char *token = strtok(const_cast<char*>(data), delimiter);

    while (token != nullptr) {
        if (strstr(token, "Age")) {
            std::cout << "Extracted Data: " << token << std::endl;
        }
        token = strtok(nullptr, delimiter);
    }

    return 0;
}

この例では、セミコロンで区切られたテキストデータから「Age」というキーワードを含む部分を抽出しています。

strstr関数を使用することで、必要な情報のみを簡単にフィルタリングできます。

●strstr関数を使った一般的なエラーと対処法

strstr関数を使用する際にはいくつか一般的なエラーが発生する可能性があります。

これらのエラーを理解し、適切に対処することで、プログラムの堅牢性を高めることができます。

○エラーケース1:NULLポインタが渡された場合の対応

strstr関数は、第一引数または第二引数にNULLが渡された場合には正しく動作しません。

この場合、関数はセグメンテーションフォールトを引き起こす可能性があります。

そのため、関数にポインタを渡す前に、必ずNULLチェックを行うようにしましょう。

#include <iostream>
#include <cstring>

int main() {
    const char *haystack = "This is a test string";
    const char *needle = nullptr; // NULL pointer

    if (haystack != nullptr && needle != nullptr) {
        char *result = strstr(haystack, needle);
        if (result != nullptr) {
            std::cout << "Found substring." << std::endl;
        } else {
            std::cout << "Substring not found." << std::endl;
        }
    } else {
        std::cout << "Invalid input, one or more pointers are NULL." << std::endl;
    }

    return 0;
}

このコード例では、ポインタがNULLかどうかを確認することで、エラーを回避しています。

これにより、プログラムが予期せず終了することを防ぐことができます。

○エラーケース2:検索対象の文字列が空の場合の対応

strstr関数に空の文字列(””)を検索対象として渡した場合、多くの環境では常に最初の文字を指すポインタが返されます。

これは、空の文字列がすべての文字列に存在すると解釈されるためです。

しかし、この挙動は直感的ではないかもしれませんので、事前に検討が必要です。

#include <iostream>
#include <cstring>

int main() {
    const char *haystack = "Sample text";
    const char *needle = ""; // Empty string

    char *result = strstr(haystack, needle);
    if (result != nullptr) {
        std::cout << "Found empty string at position: " << (result - haystack) << std::endl;
    } else {
        std::cout << "Empty string not found." << std::endl;
    }

    return 0;
}

この例では、空の検索文字列がどのように処理されるかを表しています。

結果として、プログラムは常に最初の文字の位置を返します。

この特性を理解しておくことは、デバッグ時に混乱を避けるのに役立ちます。

●エンジニアが知っておくべきstrstr関数のテクニック

strstr関数は、そのシンプルさから多くのプログラミングシナリオで重宝されますが、より効果的に使用するためのテクニックを知っておくことが重要です。

ここでは、パフォーマンスの向上や他言語との比較に焦点を当てて解説します。

○テクニック1:パフォーマンスの観点から見たstrstr関数の効率的な使い方

strstr関数を使用する際には、呼び出し回数を最小限に抑えることでパフォーマンスを向上させることができます。

特に、大規模なテキストデータを扱う場合や、ループ内での反復的な呼び出しが必要な場面では、この点が重要です。

#include <iostream>
#include <cstring>

int main() {
    const char *text = "Example text where 'example' word repeats multiple times: example, example.";
    const char *search = "example";
    const char *current = text;
    char *result;

    while ((result = strstr(current, search)) != nullptr) {
        std::cout << "Found at position: " << (result - text) << std::endl;
        current = result + strlen(search);
    }

    return 0;
}

この例では、見つかった文字列の後ろから検索を再開することで、全体の検索回数を減少させ、パフォーマンスを向上させています。

○テクニック2:他言語での同様の関数との比較

strstr関数はC++に特有のものですが、他の多くのプログラミング言語にも似た機能を提供する関数が存在します。

例えば、Pythonではstr.find()やJavaではString.indexOf()がこの役割を果たします。

これらの関数も内部的には似たようなアルゴリズムを使用しており、使い方によってはパフォーマンスの違いを体感することができます。

# Pythonの例
text = "Here is a simple example where 'example' is repeated."
search = "example"
position = text.find(search)
while position != -1:
    print(f"Found at position: {position}")
    position = text.find(search, position + len(search))
// Javaの例
public class Main {
    public static void main(String[] args) {
        String text = "Sample text for searching: hello, hello.";
        String search = "hello";
        int position = text.indexOf(search);

        while (position != -1) {
            System.out.println("Found at position: " + position);
            position = text.indexOf(search, position + search.length());
        }
    }
}

これらのコード例では、C++のstrstrと同様に、指定されたサブストリングの出現位置を検出しています。

各言語での実装を理解することで、横断的なプログラミングスキルが向上し、より多様なプロジェクトに対応可能になります。

まとめ

この記事では、C++におけるstrstr関数の基本的な使い方から応用テクニックまでを詳しく解説しました。

プログラム例を通じて、具体的な使用方法とその効果を示すことで、読者がこの関数の強力な機能を理解し活用できるように解説してきました。

strstr関数は、そのシンプルさと高い汎用性により、多くのテキスト処理シナリオで非常に価値のあるツールです。

プログラミングのスキル向上に役立てていただけることを願っています。