サイトマップ / C言語講座出入り口総目次目次:ポインタ>部分文字列の検索

青い直線

部分文字列の検索

青い直線

[単純選択ソート]←このソース→[ポインタと配列]

/* 標準ライブラリ関数strstr( )

strstr( )は標準ライブラリ関数です。文字列s1中で部分文字列s2を探します。

    #include <string.h>
    char *strstr(const char *s1, const char *s2);

    例:str = strstr(s1, s2);

    実行結果    戻り値
                成功    s1 で最初に出現した s2 へのポインタ
                失敗    NULL

今回は同等の関数StrString( )を作ります。この関数の中で使う標準ライブラリ関数について先に説明します。

strchr( )は文字列s中で文字cを探します。

    #include <string.h>
    char *strchr(const char *s, char c);

    例:str = strchr(s, c);

    実行結果    戻り値
                成功    s で最初に出現した c へのポインタ
                失敗    NULL

strncmp( )は文字列s1とs2の先頭からn文字を比較します。

    #include <string.h>
    int strncmp(const char *s1, const char *s2, size_t n);

    例:n = strncmp(s1, s2, n);

    実行結果    戻り値
    s1 > s2    正の整数
    s1 = s2    0
    s1 < s2    負の整数

size_tはstring.hの中で、次のように型宣言されています。

    typedef unsigned size_t;

ソースプログラムの説明

StrString( )を作ります。ライブラリ関数と同様に、2つのconst char型の引数s1とs2をとり、char型のポインタを返します。

s1の中に部分文字列s2があるかどうか調べます。関数の中で、文字列s2の長さを求めて、nに保存しておきます。次いでstrchr( )を使って、文字列s1の中に、文字列s2の先頭の文字があるか調べます。もしなければ、s1の中に部分文字列s2はないので、NULLを返します。もしあれば、その位置からstrncmp( )を使って、n文字比較します。もし一致したら、部分文字列が存在することになるので、その位置のポインタを返します。

一致しなければ、次の1文字比較に備えて、s1を指すポインタを1進めます。

以上をそのまま素直にコードにしたのが、 ソースプログラムです。詳しいコメントを付けておいたので、 あとはそちらをご覧下さい。 */

/* ここからソースプログラム */

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

char *StrString(const char *s1, const char *s2);
void main(void);

  /* 文字列s1の中に部分文字列s2があるか調べる */
  /* あればその位置のポインタを返し、なければNULLを返す */
char *StrString(const char *s1, const char *s2)
{
    int n;

    n = strlen(s2);                            /* 文字列s2の長さを求める */
	
    while (1) {
        s1 = strchr(s1, s2[0]);                /* s2の先頭の1文字を探す */
        if (s1 == NULL)                        /* 見つからなければ */
            return (NULL);                     /* NULLを返す */
        if(strncmp(s1, s2, n) == 0)            /* 見つかったらn文字比較 */
            return (char *)s1;                 /* 一致したらポインタを返す */
        s1++;    /* ポインタを進めて */         /* s1はconstを付けて宣言 */
    }            /* 次の strchr に備える */     /* しているのでキャストが必要 */
}

void main(void)
{
    int n = 0;            /* カウンタ */
      /* 検索対象の文字列 */
    char *s1 = "sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)";
    char *s2 = "sizeof";        /* 部分文字列 */
 
    printf("char *s1 = \"%s\";\n", s1);	 /* '\"'で'"'を表示 */
    printf("char *s2 = \"%s\";\n", s2);

    while ((s1 = StrString(s1, s2)) != NULL) { /* 部分文字列が見つかったら */
        n++;                                   /* カウンタを1増やす */
        s1 = s1 + strlen(s2);                  /* 文字列s2の長さだけポインタを進めて */
    }                                          /* 次のStrString(  )の呼び出しに備える */
 
    if (n == 0)
        printf("s1 に sizeof 演算子は見つかりません。\n");
    else if (n == 1)
        printf("s1 に sizeof 演算子は一つあります。\n");
    else
        printf("s1 に sizeof 演算子は %d 個あります。\n", n);
}

/* ここまでソースプログラム */

/* メインルーチンの中でStrString( )を呼び出して、部分文字列が見つかったら、s1を指すポインタをs2の長さだけ進めます。これにより、次の部分文字列を探すことができます。プログラムの実行結果はいかがでしたか。部分文字列を色々書き換えて、再度実行して見て下さい。

ところで、sizeof( )は関数ではなく演算子です。 */

[単純選択ソート]←このソース→[ポインタと配列]

青い直線

/* (C) 2000- YFプロ. All Rights Reserved. */    提供:C言語講座−それ自体コンパイルできる教材を使った講座です−

青い直線

サイトマップ / C言語講座出入り口総目次目次:ポインタ>部分文字列の検索