ここから本文です

#include<stdio.h> #include<string.h> int main(void) { char str[64]; ...

spi********さん

2019/5/2917:41:33

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

int main(void)
{
char str[64];
char key[64];

char *adr;
char *adr2;

printf("文字列 : ");
scanf("%s", str);

printf("探す文字 : ");
scanf("%s", key);

adr = str;

while((adr2 = strstr(adr, key)) != NULL){
printf("文字列'%s'は%2ld文字目に存在します。 : ", key, adr2-str+1);
printf("str[%ld]: %s\n", adr2 - str, adr2);
adr = adr2 + sizeof(char) * strlen(key);
}
if(adr == str)
printf("文字'%s'は文字列中に存在しません。\n", key);

return 0;
}

このようなソースコードがあったとして、ポインタ変数の式である
adr = adr2 + sizeof(char) * strlen(key);
はどのような役割を果たしていますか?教えてください!
ポインタ変数式での+や*が教科書を調べていても載ってなかったので力をお貸しください。

閲覧数:
30
回答数:
2
お礼:
250枚

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

あみやさん

2019/5/2918:26:50

そこはあまりポインタを気にしなくても問題ないです。
単純な算数と同じです。
ひとつひとつ見てゆきます。

sizeof(char)
sizeof演算子は…(sizeofは+や-とかと同じ演算子の仲間なのです)
その後に指定された変数の型のサイズを返します。
char型は1Byteなので、1という数値がその値となります。

strlen(key)
strlen関数は引数に渡された文字列の文字数を返します。
この場合、key配列の中にある文字列データの文字数を返します。
(key配列自体の長さではありません)
たとえば、key="abc"であれば、3を返します。

sizeof(char) * strlen(key)
charのサイズ * 文字数
つまりは、keyの文字列のバイト数を計算しています。
sizeof(char)は無くても良いのですが、もしかして、charが16bitな環境が現れると、
計算が合わなくなるので入れてあります。

adr2 + 〜
adr2とは何かというと、その前にある
adr2 = strstr(adr, key)
と言うことなので、adrの中にあるkeyという文字列の先頭アドレスになります。

adr2 + sizeof(char) * strlen(key);
adrの中のkeyが最初に登場したアドレス + keyの文字数分のバイト数

というわけで、
『adrの中から最初に見つかったkeyの位置からkeyの文字数分進んだ位置』

adrの先頭アドレスとしています。

adrから文字列を探す
あったらその先頭をadr2に
見つけたkeyの終わった位置をadrの先頭とする
これを繰り返すと次々にkeyを見つけられます。

  • あみやさん

    2019/5/2918:30:58

    ああ、少々訂正。
    ポインタを加算する場合、+1する毎にポインタの元となる型のサイズだけ先に進みます。
    ですので、charが16bitの場合でも、普通にstrlenの値を足せばよいです。
    sizeofを挟むことでむしろ計算が合わなくなってしまいます。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2019/5/29 19:08:33

丁寧な回答ありがとうございます!りかいできました!

ベストアンサー以外の回答

1〜1件/1件中

2019/5/2918:18:36

>ポインタ変数式での+や*が
* は + より先に計算されるので、
size_t 型の加算(単なる整数値加算)です。

ただし、今回たまたま動いていますが、
sizeof(char) は今回必要ありません。
書くべきでもありません。

ポインタへの整数加算は、加算した数の後のデータを示します。
adr2 + strlen(key);

adr2は、char 型のポインタなので、key の文字数分だけ
後ろの位置を示します。
つまり、文字検索した位置の、strstr 関数で見つけた位置の
文字列の先頭を示しているので、
key で指定した文字列と同じ文字列が今から続きます。
次に同じ文字列を検索しようとした場合、
現在の adr2 から検索したら、最初同じ文字列になるので
同じポインタが返ってきます。
だから、adr2 より後のポインタから検索を始めますが、

その時、adr2 の次の位置から検索を始めるパターンと、
見つかった文字列の次のポインタから始めるパタンがあります。

これは後者です。検索しても見つかった文字列分ポインタをずらして、
次のポインタに移動します。

それが、+ strlen(key); です。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる