文字列の検索1

strchr関数

ある文字列中から任意の文字を検索するにはstrchr関数を使用します。

このページの関数を使用するには#include <string.h>が必要です。


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

int main()
{
    const char* s = "This is a pen.";
    const char c = 'a';

    //文字列sから文字cを検索
    char* p = strchr(s, c);

    if (p == NULL)
    {
        printf("[%c]は[%s]中にありません。", c, s);
    }
    else
    {
        printf("[%c]は[%s]の%d文字目にあります。", c, s, p - s);
    }
    getchar();
}
[a]は[This is a pen.]の8文字目にあります。
char *strchr(
 const char *str,
 int c
);
文字列str内の文字cの位置をポインタで返す。
存在しない場合はNULLを返す。

strchr関数は文字が見つかった位置をポインタで返します。
この戻り値から文字列の先頭位置のポインタを引くことで、文字が文字列中の何文字目に出現するかを得ることができます。
(正確にはバイト数)
先頭文字は0文字目になるので注意してください。

そのまま使用すると最初に見つかった文字の位置を返すだけです。
文字列中の全ての位置を取得するにはループを使用します。


const char* s = "This is a pen.";
const char c = 'i';

//キャストでconst外し
char* p = (char*)s;
int count = 0;

printf("[%s]中に[%c]は", s, c);
while ((p = strchr(p, c)) != NULL)
{
	printf("\n%d文字目", p - s);

	//次の文字から検索するため
	//ポインタをひとつ進める
	p++;
	count++;
}
if (count == 0) {
	printf("ありません。");
}
else {
	printf("\nの計%d個あります。", count);
}
[This is a pen.]中に[i]は
2文字目
5文字目
の計2個あります。

なお、5行目のキャストはconstを外すために行っています。
const char*型で宣言している変数をただのchar*型に代入すると、コンパイラによっては警告が出てコンパイルできない場合があるので、これの回避策です。
もちろんconstは「変更されたくない」場合に付けるものですので、普段はconstを安易に外すべきではありません。

_mbschr関数

_mbschr関数は第一引数のマルチバイト文字列対応版です。
日本語等のマルチバイト文字が含まれる文字列から検索を行う場合はこちらを使用します。
ただしこれはVisual Studioなどの一部のコンパイラでのみ使用できます。

マルチバイト用関数の実行のために、最初にロケールを設定します。
<locale.h>をインクルードし、setlocale関数を実行します。
(→文字列の長さの取得を参照)
それ以外の使い方はstrchr関数と同じです。

返されるのはバイトです。
日本語などは2文字以上とカウントされるので、見た目上の文字数と得られる番号にはズレが生じます。
また、文字コードによって一文字当たりのバイト数が異なるため、戻り値が変化することに注意が必要です。


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

int main()
{
    const char* s = "あいうえおABCDE";
    const char c = 'A';

    setlocale(LC_ALL, "");
    char* p = _mbschr(s, c);

    if (p == NULL)
    {
        printf("[%c]は[%s]中にありません。", c, s);
    }
    else
    {
        printf("[%c]は[%s]の%dバイト目にあります。", c, s, p - s);
    }

    getchar();
}
[A]は[あいうえおABCDE]の10バイト目にあります。

第二引数(検索する文字)はシングルバイト文字ですので、「日本語文字列から日本語一文字を検索する」場合には使えません。

strrchr関数

strchr関数は文字列を前方から検索しますが、strrchr関数は文字列の末尾から前方に向かって検索します。
つまり「最後に出現する位置」を返します。
それ以外の動作は同じです。


#include 
#include 

int main()
{
    const char* s = "This is a pen.";
    const char c = 'i';

    //文字列sの末尾から文字cを検索
    char* p = strrchr(s, c);

    if (p == NULL)
    {
        printf("[%c]は[%s]中にありません。", c, s);
    }
    else
    {
        printf("[%c]は[%s]の%d文字目にあります。", c, s, p - s);
    }
    getchar();
}
[i]は[This is a pen.]の5文字目にあります。

末尾から検索した場合でも、このコードで得られるのは「先頭からの文字数(バイト数)」であることに注意してください。

_mbsrchr関数

_mbsrchr関数は、strrchr関数のマルチバイト版対応版です。
strchr関数と_mbschr関数の関係と同じです。
サンプルコードは省略します。

memchr関数

strchr関数に近い動作をするものにmemchr関数があります。
strchr関数は文字列から文字を検索しますが、memchr関数はメモリから文字を検索します。


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

int main()
{
	const char* s = "This is a pen.";
    const char c = 'z';

	char* p = (char*)memchr(s, c, strlen(s));

    if (p == NULL)
    {
        printf("[%c]は[%s]中にありません。", c, s);
    }
    else
    {
        printf("[%c]は[%s]の%d文字目にあります。", c, s, p - s);
    }

	getchar();
}
[a]は[This is a pen.]の8文字目にあります。
void *memchr(
 const void *buf,
 int c
 size_t n
);
ポインタbufの位置から文字cをn文字分検索し、見つかった位置をポインタで返す。
存在しない場合はNULLを返す。

strchr関数のサンプルコードとほとんど同じコードです。
文字列もメモリ上にあるので、文字列検索にも使えます。
ただし検索対象は文字列に限りませんので、途中でNULL文字が見つかった場合でも処理は終了しません。
終了の条件として、検索する最大文字数(というよりバイト数)の指定が増えています。

また、第一引数と戻り値の型もchar*型からvoid*型に変わっています。
void*型はデータ型に依存しない(データ型が不明の)ポインタという意味で、必要に応じて型変換して使用します。

第二引数はint型ですが、これはunsighed char型に変換され、検索は1バイト単位で行われます。