STEP 3.1 D (ポインターを使っています)

<問題> 対象の文字列(テキスト)中に、探したい文字列(パターン)が含まれているかどうかを調べよう。(力ずくのアルゴリズムをプログラムしよう)

<実行結果> 

文字列を入力してください :uma ga umaranai.
探したい文字列を入力してください :umatta
t[0] = u
t[1] = m
t[2] = a
t[3] =
t[4] = g
t[5] = a
t[6] =
t[7] = u
t[8] = m
t[9] = a
t[10] = r
t[11] = a
t[12] = n
t[13] = a
t[14] = i
t[15] = .
Pattern umatta is not found to 10
(← tの最後まで、調べていない。pは6文字)

<ヒント>


例題集へ



解答例

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

#define TEXTL 50 /* 改行まで */
#define PATL 20

/* プロトタイプ宣言 */
void print_text(char []); /* 文字列配列tの表示 */

int main (void) {
    char t[TEXTL];
    char p[PATL];
    char *pp; /* 文字を操作するためのポインター */

    int l; /* ループ回数  n - m まででよい */
    int n; /* テキストの長さ */
    int m; /* パターンの長さ */

    int j;

    printf("文字列を入力してください :");
    fgets(t, TEXTL, stdin);  /* TEXTL文字分しか読まない。ファイル名stdinは標準入 力のこと。ここではキーボード */
    pp = strchr(t, '\n'); /* fgetsでは、改行文字が残る。*/
    *pp = '\0';  /* その文字を、ヌル文字に置き換える */
    /* 本来入力部分は、TEXTLを超えて入力された場合の対処なども用意 */

    printf("探したい文字列を入力してください :");
    fgets(p, PATL, stdin);
    pp = strchr(p, '\n');
    *pp = '\0';

    print_text(t); /* テキストの出力 */

    n = strlen(t);
    m = strlen(p);
    l = n - m;  /* tの残りが、pより短くなったらやめるという条件のための計算 */

    pp = t; /* 配列tの先頭アドレスをppに代入。charを指している */
    for (j = 0; j <= l ; j++) {
        /*  if (strncmp(&t[j], p, m) == 0) break; 配列の場合 */
        if (strncmp(pp, p, m) == 0) break;
        pp++; /* アドレスを1単位、この場合はchar分 ずらす。つまりtの次の文字のア ドレス */
    }

    /* pが含まれていて、for文が終了したのかを調べよう */
    if (j <= l) /* テキスト配列tの添え字jから見つかった */
        printf("Pattern %s is matched at %d \n", p,j);
    else       /* 見つからない */
        printf("Pattern %s is not found to %d \n", p, l);

    return 0;
}

void print_text(char t[]) {
    int j = 0;
    /* 定番の出力プログラム */
    while (t[j] != '\0') {
        printf("t[%d] = %c\n", j, t[j]);
        j++;
    }
}