strchrや、strstrは、string.hをインクルードすれば、利用できます。
しかし正しく利用するには、その関数がどのように作られたものかを理解する必要があります。
以下では、これら関数の定義例と利用例を紹介します。
文字列の中から文字を探して、見つかった文字コードが存在するアドレス (char *)型を返します。
内部では、文字列の先頭から後方を順番に調べる繰り返しが行なわれます。
文字列の終端まで見つからない場合は、NULLを返します。
以下に定義例と実行例を示します。
の部分が出力結果です。
#include <stdio.h>
char * strchr(char * s, int c)
{
while( *s != '\0' && *s != c) {/* 終端でなく、また、文字が見つからない間、繰り返す */
s++;
}
if( *s == c ) { /* c の文字が見つかった */
return s; /* 見つかった位置のポインタを返す */
}
return NULL;/* 見つからない */
}
main()
{
char a[] = "Abc0 abc1 abc2";
char * p = strchr( a , 'a'); /* aが指し示す文字列から 'a' の文字を探す */
puts( p ); /* 見つかった位置から表示 abc1 abc2 */
p = strchr( p+1, 'a'); /* 見つかった次の位置から探す */
puts( p ); /* 見つかった位置から表示 abc2 */
}
見つからない場合に、NULLを返す関数です。NULLは、どこも指し示していないポインタなので、
本来はその場合のifやwhileなど制御構造を使ったプログラミングが必要です。
(NULLが記憶されるpを使って、puts( p )を実行すれば、実行エラーです)
文字列を探す場合は、探したい文字列全体の等価チェックができません。
そこでまず、探したい文字列の1文字で探します。
以下では、探したい文字列先頭の文字 *cpがsの文字列中にあるか調べています。
次に見つかったら、残りの部分が合っているかを調べる処理を行ないます。
以下では、先頭文字が見つかったs1と、cpが記憶されるs2で、
cpが指し示す全ての文字が合っているか調べる繰り返しです。
#include <stdio.h> char * strstr(char * s, char * cp) { char *s1, *s2; if( *cp == '\0') return s; /* cp の文字列長が0なら s を返す */ while( *s != '\0'){ while(*s != '\0' && *s != *cp) {/* 終端でなく、また、文字が見つからない間、繰り返す */ s++; } if(*s == '\0') return NULL;/* 見つからない */ s1 = s; s2 = cp; while ( *s1 == *s2 && *s1 != '\0'){ /* s1とcpの部分文字列が一致するか */ s1++; s2++; } if( *s2 == '\0'){/* cp の文字列は、全て一致した */ return s; } s++; /* 次の位置から、調べ直す */ } return NULL;/* 見つからない */ } main() { char a[] = "Abc0 abc1 abc2"; char * p = strstr( a , "bc"); /* aが指し示す文字列から 'a' の文字を探す */ puts( p ); /* 見つかった位置から表示 bc0 abc1 abc2 */ p = strstr( p+1, "bc"); /* 見つかった次の位置から探す */ puts( p ); /* 見つかった位置から表示 bc1 abc2 */ p = strstr( p+1, "bc"); /* 見つかった次の位置から探す */ puts( p ); /* 見つかった位置から表示 bc2 */ }
C言語では、文字列の一部を比較するstrncmp関数があり、strcmp関数に対して比較文字(byte)数を
与える引数が1つ多い関数です。
strcmp関数は、終端の'\0'まで合っているか調べるますが、strncmp関数は、
比較文字(byte)数nが、文字列より小さい時、その範囲内だけで比較結果が得られます。
このstrncmp関数と、strchr関数を利用した場合のstrstr関数定義例を示します。
strchr関数で、探したい文字列先頭の文字 *cpがsの文字列中にあるか調べ、
見つかった位置から、残りの部分文字列が合っているかsrncmp関数で調べています。
char * strstr(char * s, char * cp) { int n = strlen(cp); char *s1; if( n == 0 ) return s; /* cp の文字列長が0なら s を返す */ while( *s != '\0'){ s1 = strchr(s , *cp); /* cp先頭文字を見つける */ if( s1 == NULL ) return NULL;/* 見つからない時のreturn */ if(strncmp(s1 , cp , n ) == 0){/* s1とcpの部分文字列が一致するか */ return s1; } s++; /* 次の位置から、調べ直す */ } return NULL;/* 見つからない */ }
なお文字列探索は、もっと高速に調べるアルゴリズムがあるので、実際は上記のような作りでない可能性があります。 上記は、単純な考え方で作る方法です。
上記strstrと同じ機能を行なわせる別の定義例を、以下に示します。
*のポインタ演算子を使わずに、[]の配列演算子を使う変更をしてください。つまり、添え字で位置を指定する形態です。
上記プログラムの char *s1, *s2; の代わりに、int i1, i2 , i = 0 と宣言しました。
s1の役割をi1、s2の役割をi2で行なわせてください。また、sを変更しない代わりにiで制御ください。
(なお添え字変更は、後置インクリメントを使ってください)
←編集 入力後に クリックください。