[C言語] 文字列の検索方法を解説(文字指定・文字列指定)
C言語で文字列を検索する方法には、特定の文字を探す方法と特定の文字列を探す方法があります。
特定の文字を検索するには、標準ライブラリの関数であるstrchrを使用します。この関数は、指定した文字が最初に現れる位置を返します。
一方、特定の文字列を検索するにはstrstr関数を使用します。この関数は、指定した文字列が最初に現れる位置を返します。
これらの関数を活用することで、効率的に文字列内の情報を取得することが可能です。
文字列検索の基本概念
C言語における文字列検索は、文字列内で特定の文字や部分文字列を見つけるための重要な操作です。
文字列は文字の配列として扱われ、検索には標準ライブラリの関数が利用されます。
これにより、プログラマは効率的に文字列を操作し、必要な情報を抽出することができます。
文字列検索の基本的な関数には、特定の文字を検索するstrchrや、部分文字列を検索するstrstrなどがあります。
これらの関数は、文字列の先頭から検索を開始し、最初に見つかった位置を返します。
文字列検索は、テキスト処理やデータ解析など、さまざまな場面で活用されるため、C言語プログラマにとって必須のスキルです。
文字指定による検索方法
strchr関数の使い方
strchr関数は、文字列内で特定の文字を検索するための関数です。
文字列の先頭から指定した文字を探し、最初に見つかった位置を返します。
基本的な使用例
以下は、strchr関数を使用して文字列内の特定の文字を検索する例です。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "こんにちは、世界!";
    char *result = strchr(str, '世');
    
    if (result != NULL) {
        printf("文字 '世' は位置 %ld にあります。\n", result - str);
    } else {
        printf("文字 '世' は見つかりませんでした。\n");
    }
    return 0;
}文字 '世' は位置 6 にあります。この例では、文字列 “こんにちは、世界!” の中から ‘世’ という文字を検索し、その位置を表示しています。
戻り値の解釈
strchr関数の戻り値は、指定した文字が見つかった場合、その文字へのポインタを返します。
見つからなかった場合は、NULLを返します。
これにより、文字の存在を確認し、その位置を計算することができます。
strrchr関数の使い方
strrchr関数は、文字列内で特定の文字を検索する点ではstrchrと似ていますが、文字列の末尾から検索を開始します。
最初に見つかった位置を返す点は同じです。
基本的な使用例
以下は、strrchr関数を使用して文字列内の特定の文字を末尾から検索する例です。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "こんにちは、世界!";
    char *result = strrchr(str, '!');
    
    if (result != NULL) {
        printf("文字 '!' は位置 %ld にあります。\n", result - str);
    } else {
        printf("文字 '!' は見つかりませんでした。\n");
    }
    return 0;
}文字 '!' は位置 9 にあります。この例では、文字列 “こんにちは、世界!” の中から ‘!’ という文字を末尾から検索し、その位置を表示しています。
戻り値の解釈
strrchr関数の戻り値も、指定した文字が見つかった場合、その文字へのポインタを返します。
見つからなかった場合は、NULLを返します。
これにより、文字の存在を確認し、その位置を計算することができます。
文字指定検索の応用例
特定の文字の出現回数を数える
文字列内で特定の文字が何回出現するかを数えるには、strchrを繰り返し使用して、文字が見つかるたびにカウントを増やします。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "こんにちは、世界!こんにちは!";
    char *ptr = str;
    int count = 0;
    
    while ((ptr = strchr(ptr, '!')) != NULL) {
        count++;
        ptr++; // 次の文字から再検索
    }
    
    printf("文字 '!' は %d 回出現します。\n", count);
    return 0;
}文字 '!' は 2 回出現します。文字の位置を取得する
文字列内の特定の文字の位置をすべて取得するには、strchrを使用して、見つかるたびにその位置を記録します。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "こんにちは、世界!こんにちは!";
    char *ptr = str;
    
    printf("文字 '!' の位置: ");
    while ((ptr = strchr(ptr, '!')) != NULL) {
        printf("%ld ", ptr - str);
        ptr++; // 次の文字から再検索
    }
    printf("\n");
    return 0;
}文字 '!' の位置: 9 15 この例では、文字 ‘!’ の位置をすべて表示しています。
strchrを使って次の位置を検索し、見つかるたびにその位置を出力しています。
文字列指定による検索方法
strstr関数の使い方
strstr関数は、文字列内で特定の部分文字列を検索するための関数です。
文字列の先頭から指定した部分文字列を探し、最初に見つかった位置を返します。
基本的な使用例
以下は、strstr関数を使用して文字列内の特定の部分文字列を検索する例です。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "C言語でプログラミングを学ぶ";
    char *result = strstr(str, "プログラミング");
    
    if (result != NULL) {
        printf("部分文字列 'プログラミング' は位置 %ld にあります。\n", result - str);
    } else {
        printf("部分文字列 'プログラミング' は見つかりませんでした。\n");
    }
    return 0;
}部分文字列 'プログラミング' は位置 4 にあります。この例では、文字列 “C言語でプログラミングを学ぶ” の中から “プログラミング” という部分文字列を検索し、その位置を表示しています。
戻り値の解釈
strstr関数の戻り値は、指定した部分文字列が見つかった場合、その部分文字列の先頭へのポインタを返します。
見つからなかった場合は、NULLを返します。
これにより、部分文字列の存在を確認し、その位置を計算することができます。
strcasestr関数の使い方(POSIX)
strcasestr関数は、strstrと同様に部分文字列を検索しますが、大文字小文字を区別しない点が異なります。
この関数はPOSIX標準の一部であり、すべての環境で利用できるわけではないため、注意が必要です。
大文字小文字を区別しない検索
以下は、strcasestr関数を使用して大文字小文字を区別せずに部分文字列を検索する例です。
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "C言語でプログラミングを学ぶ";
    char *result = strcasestr(str, "プログラミング");
    
    if (result != NULL) {
        printf("部分文字列 'プログラミング' は位置 %ld にあります。\n", result - str);
    } else {
        printf("部分文字列 'プログラミング' は見つかりませんでした。\n");
    }
    return 0;
}部分文字列 'プログラミング' は位置 4 にあります。使用例と注意点
strcasestrは大文字小文字を区別しないため、”プログラミング” と “プログラミング” のように異なるケースでも一致します。
ただし、POSIX標準の一部であるため、Windows環境などでは利用できない場合があります。
その場合は、他の方法で大文字小文字を無視する処理を実装する必要があります。
文字列指定検索の応用例
部分文字列の置換
部分文字列を別の文字列に置換するには、strstrを使用して部分文字列を見つけ、見つかった位置から新しい文字列を挿入します。
#include <stdio.h>
#include <string.h>
void replaceSubstring(char *str, const char *oldSub, const char *newSub) {
    char buffer[256];
    char *pos = strstr(str, oldSub);
    
    if (pos != NULL) {
        strncpy(buffer, str, pos - str);
        buffer[pos - str] = '#include <stdio.h>
#include <string.h>
void replaceSubstring(char *str, const char *oldSub, const char *newSub) {
char buffer[256];
char *pos = strstr(str, oldSub);
if (pos != NULL) {
strncpy(buffer, str, pos - str);
buffer[pos - str] = '\0';
sprintf(buffer + (pos - str), "%s%s", newSub, pos + strlen(oldSub));
strcpy(str, buffer);
}
}
int main() {
char str[256] = "C言語でプログラミングを学ぶ";
replaceSubstring(str, "プログラミング", "コーディング");
printf("%s\n", str);
return 0;
}
';
        sprintf(buffer + (pos - str), "%s%s", newSub, pos + strlen(oldSub));
        strcpy(str, buffer);
    }
}
int main() {
    char str[256] = "C言語でプログラミングを学ぶ";
    replaceSubstring(str, "プログラミング", "コーディング");
    printf("%s\n", str);
    return 0;
}C言語でコーディングを学ぶこの例では、”プログラミング” を “コーディング” に置換しています。
特定のパターンの検出
特定のパターンを検出するには、strstrを使用してパターンが存在するかを確認します。
例えば、メールアドレスのドメインを検出する場合などに利用できます。
#include <stdio.h>
#include <string.h>
int main() {
    char email[] = "example@domain.com";
    char *domain = strstr(email, "@domain.com");
    
    if (domain != NULL) {
        printf("メールアドレスは 'domain.com' ドメインです。\n");
    } else {
        printf("メールアドレスは 'domain.com' ドメインではありません。\n");
    }
    return 0;
}メールアドレスは 'domain.com' ドメインです。この例では、メールアドレスが特定のドメインに属しているかを確認しています。
strstrを使ってドメイン部分を検索し、存在を確認しています。
応用例
複数の文字列を一度に検索する方法
複数の文字列を一度に検索するには、ループを使用して各文字列を順番に検索する方法があります。
以下の例では、複数のキーワードを一度に検索し、それぞれの位置を表示します。
#include <stdio.h>
#include <string.h>
void searchMultipleStrings(char *str, char *keywords[], int keywordCount) {
    for (int i = 0; i < keywordCount; i++) {
        char *result = strstr(str, keywords[i]);
        if (result != NULL) {
            printf("キーワード '%s' は位置 %ld にあります。\n", keywords[i], result - str);
        } else {
            printf("キーワード '%s' は見つかりませんでした。\n", keywords[i]);
        }
    }
}
int main() {
    char str[] = "C言語でプログラミングとコーディングを学ぶ";
    char *keywords[] = {"プログラミング", "コーディング", "デバッグ"};
    int keywordCount = sizeof(keywords) / sizeof(keywords[0]);
    
    searchMultipleStrings(str, keywords, keywordCount);
    return 0;
}キーワード 'プログラミング' は位置 4 にあります。
キーワード 'コーディング' は位置 11 にあります。
キーワード 'デバッグ' は見つかりませんでした。この例では、”プログラミング”、”コーディング”、”デバッグ” の3つのキーワードを検索し、それぞれの位置を表示しています。
正規表現を用いた高度な検索
C言語で正規表現を使用するには、POSIXライブラリのregex.hを利用します。
正規表現を用いることで、より柔軟で高度なパターンマッチングが可能になります。
#include <stdio.h>
#include <regex.h>
int main() {
    char str[] = "C言語でプログラミングとコーディングを学ぶ";
    regex_t regex;
    int reti;
    
    // 正規表現パターンのコンパイル
    reti = regcomp(®ex, "プログラミング|コーディング", REG_EXTENDED);
    if (reti) {
        fprintf(stderr, "正規表現のコンパイルに失敗しました\n");
        return 1;
    }
    
    // 正規表現による検索
    reti = regexec(®ex, str, 0, NULL, 0);
    if (!reti) {
        printf("パターンが見つかりました。\n");
    } else if (reti == REG_NOMATCH) {
        printf("パターンは見つかりませんでした。\n");
    } else {
        char msgbuf[100];
        regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
        fprintf(stderr, "正規表現の実行エラー: %s\n", msgbuf);
        return 1;
    }
    
    // 正規表現の解放
    regfree(®ex);
    return 0;
}パターンが見つかりました。この例では、”プログラミング” または “コーディング” というパターンを正規表現で検索しています。
正規表現を使うことで、複雑なパターンを簡単に検索できます。
自作関数によるカスタム検索
特定のニーズに合わせたカスタム検索を行うために、自作関数を作成することができます。
以下の例では、特定の文字列が含まれているかどうかを確認するカスタム関数を作成しています。
#include <stdio.h>
#include <string.h>
// カスタム検索関数
int containsSubstring(char *str, char *substring) {
    return strstr(str, substring) != NULL;
}
int main() {
    char str[] = "C言語でプログラミングを学ぶ";
    char *substring = "プログラミング";
    
    if (containsSubstring(str, substring)) {
        printf("文字列に '%s' が含まれています。\n", substring);
    } else {
        printf("文字列に '%s' は含まれていません。\n", substring);
    }
    return 0;
}文字列に 'プログラミング' が含まれています。この例では、containsSubstringというカスタム関数を使用して、文字列に特定の部分文字列が含まれているかを確認しています。
自作関数を作成することで、特定の要件に応じた柔軟な検索が可能になります。
まとめ
C言語における文字列検索は、文字や部分文字列を効率的に見つけるための重要な技術です。
この記事では、strchrやstrstrなどの基本的な関数の使い方から、正規表現を用いた高度な検索方法までを解説しました。
これらの知識を活用することで、文字列操作の幅が広がり、より複雑なプログラムを作成することが可能になります。
ぜひ、実際のプログラミングでこれらの技術を試してみてください。
 
![[C言語] atol関数の使い方 – 文字列をlong型数値に変換する](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47138.png)
![[C言語] atof関数の使い方 – 文字列を浮動小数(double)に変換する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47137.png)
![[C言語] sprintf関数の使い方 – 複数の変数を文字列にフォーマット](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47139.png)
![[C言語] sscanf関数の使い方 – フォーマット指定でファイルから読み込む](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47140.png)
![[C言語] strcat 使い方 – 文字列の連結](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47141.png)
![[C言語] strcpy関数の使い方 – 文字列をコピーする](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47144.png)
![[C言語] strcmp関数の使い方 – 文字列を比較する](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47143.png)
![[C言語] strchr関数の使い方 – 最初に見つかった文字の位置を取得](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47142.png)
![[C言語] strncat関数の使い方 – 指定文字分結合](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47148.png)
![[C言語] strlen関数の使い方 – 文字列の長さ(バイト数)の取得](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47147.png)
![[C言語] stricmp関数の使い方 – 大文字小文字を区別しない比較](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47146.png)
![[C言語] strcspn関数の使い方 – 文字群が含まれる位置を検索](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47145.png)