• ベストアンサー

strstr()を使ったプログラムについて

上のプログラムでは正しい結果がでて、下のプログラムでは正しい結果がでない理由を教えてください。 <上のプログラム> #include<stdio.h> #include<string.h> main() { char *str = "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"; int i = 0;     while((str = strstr(str,"Apple")) != NULL){ str++; i++; }     printf("文字列の中にAppleは%d個含まれます。",i); return 0; } <下のプログラム> #include<stdio.h> #include<string.h> main() { char *str = "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"; int i = 0;     while(strstr(str,"Apple") != NULL){      str++; i++; } printf("文字列の中にAppleは%d個含まれます。",i); return 0; } 実行環境はBorland C++、上のプログラムでは正しく3と表示されますが、 下のプログラムでは33と表示されてしまいます。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

上のプログラム 1回目のstrstr "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 見付かるので "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返され、それがstrになる。 strは "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 strとiがインクリメントされる。 結果、strは "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 2回目のstrstr "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 見付かるので "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返され、それがstrになる。 strは "Apple,Orange,Grape,Apple,Lemmon" を指す。 strとiがインクリメントされる。 結果、strは "pple,Orange,Grape,Apple,Lemmon" を指す。 3回目のstrstr "pple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 見付かるので "pple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返され、それがstrになる。 strは "Apple,Lemmon" を指す。 strとiがインクリメントされる。 結果、strは "pple,Lemmon" を指す。 4回目のstrstr "pple,Lemmon"から"Apple"を探す。 見付からないのでNULLが返る。 NULLが返るとwhile文をやめる。 iは3回インクリメントされているので 「文字列の中にAppleは3個含まれます。」 と表示される。 下のプログラム 1回目のstrstr "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 見付かるので "Apple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返される。 strとiがインクリメントされる。 結果、strは "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 2回目のstrstr "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 見付かるので "pple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返される。 strとiがインクリメントされる。 結果、strは "ple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 3回目のstrstr "ple,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 2回目で見付かった"Apple"がまた見付かるので "ple,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返される。 strとiがインクリメントされる。 結果、strは "le,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 4回目のstrstr "le,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す。 2、3回目で見付かった"Apple"がまた見付かるので "le,Lemmon,Apple,Orange,Grape,Apple,Lemmon" の中にある最初の"Apple"の位置が返される。 strとiがインクリメントされる。 結果、strは "e,Lemmon,Apple,Orange,Grape,Apple,Lemmon" を指す。 5回目のstrstr "e,Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す(以下同文) 6回目のstrstr ",Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す(以下同文) 7回目のstrstr "Lemmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す(以下同文) 8回目のstrstr "emmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す(以下同文) 9回目のstrstr "mmon,Apple,Orange,Grape,Apple,Lemmon"から"Apple"を探す(以下同文) (中略) 32回目のstrstr ",Apple,Lemmon"から"Apple"を探す(以下同文) 33回目のstrstr "Apple,Lemmon"から"Apple"を探す(以下同文) 34回目のstrstr "pple,Lemmon"から"Apple"を探し、見付からないのでwhile文をやめる。 iは33回インクリメントされているので 「文字列の中にAppleは33個含まれます。」 と表示される。

eques130
質問者

お礼

とてもよく分かる回答ありがとうございました。

その他の回答 (2)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

思った動作にならないときは printf("%d回目のstr=%s\n", i, str); とか書いて確認してみましょう。

eques130
質問者

お礼

そうすることでプログラムの動きが分かるんですね。 ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「正しい結果が出ない」のは「正しい結果が出ないプログラムを書いたから」ですね. どっちもプログラムに書いてある通りの動作をしてます. strstr がどのような動作をするかがわかれば明らかだと思う.

関連するQ&A