- ベストアンサー
文字列の比較
このプログラムに問題はあるでしょうか? 2つの文字列に対して,同じ位置にある文字が一致する箇所をカウントするプログラムです. やはりwhile分の||を&&にしなければならないのでしょうか? #include <stdio.h> int main(void) { char mojiA[] = "Please Help Me!" ; char mojiC[] = "eeeeeeeeeeeeeeeee"; char mojiB[] = "Please give me some money" ; int count ; /* 一致した文字数 */ int i ; count = 0 ; i=0; do{ if (mojiA[i] == mojiB[i]) { count++ ; } i++; } while(mojiA[i]!=0 || mojiB[i]!=0); printf("%d\n", count) ; return 0 ; } ;
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
★文字列の最後は NULL 文字です。 ・このため、mojiA、mojiB のどちらか一方が NULL 文字に到達したときに while 文のループを 抜けるようにします。こうしないと NULL 文字以降の文字列ではないメモリとの比較・カウント が行われ正しくカウントされませんよ。 ・よって問題ありです。→回答者 No.1 さんのアドバイスどおりに do-while 文だと mojiA、mojiB が最初から『空文字列』のときに1カウントしたり、do-while 文を抜け出せなくなってしまい 無限ループしてしまうかも…。怖いよ~無限ループは。 ・それではどうするか? ・do-while 文から while 文または、for 文に書き直します。 ・私は、for 文の方が分かりやすいと思います。→for(初期化 ; 条件式 ; 増減式 ){ … } 手直しサンプル: int main(void) { char mojiA[] = "Please Help Me!"; char mojiC[] = "eeeeeeeeeeeeeeeee"; ←これ必要なの? char mojiB[] = "Please give me some money"; int count = 0; ←宣言と同時に初期化も可能 int i; for ( i = 0 ; (mojiA[i] != '\0') && (mojiB[i] != '\0') ; i++ ){ ←『&&』ですね if ( mojiA[i] == mojiB[i] ){ count++; } } printf( "%d\n", count ); return( 0 ); }←ここにあった『;』文字は必要ありません。 最後に: ・質問者さんも『やはり while 文の || を && にしなければ』と分かっているようですね。 ・この場合は『&&』の演算子になります。 ・また、文字列の最後を表す NULL 文字は数値の 0 ですが、一般的に『'\0'』という表現をします。 もちろん、数値の 0 でも動作しますが…。 あと NULL 文字の間違った表現に『NULL』という記号定数を使う人がいますが、こちらは 『NULLポインタ』という意味です。これも、数値的には 0 だったりしますが厳密にはポインタ ですので NULL 文字を表現するのに使ってはいけません。注意。 ・『NULL文字』、『NULLポインタ』、『空文字列』をしっかり区別しましょう。 ・以上。おわり。
その他の回答 (1)
- koko_u
- ベストアンサー率12% (14/116)
>やはりwhile分の||を&&にしなければならないのでしょうか? うん。 これだと mojiB の方が長かった場合に(この場合まさにそう) Please Help Me! を越えてメモリを読みにいっちゃうからね。 mojiC が mojiA と mojiB の間に挟んであるけど、メモリの配置までその順になるとは保証されないと思う。 ついでに do { } while() でループをまわすと mojiA, mojiB が ""(空)の場合に mojiA[0] を終了判定せずに mojiA[1] をアクセスしてしまうので while ループにしましょう。