みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語プログラミング 初心者

現在2つの文字列を比較するstrcmp()関数と同じ動作をするプログラムを制作しています。
もちろん、strcmp()は一切用いません。
何とか作ってみたものの、文字列が等しいときなどにはうまく作動しません。
分かる方アドバイスお願いします。
以下のプログラムでは2つの50文字以下の文字列を入力することを想定しています。

#include<stdio.h>

int main(void)
{
char str1[50],str2[50];
int a,b,i;


printf("第1の文字列を入力してください: ");
gets(str1);
printf("第2の文字列を入力してください: ");
gets(str2);

/*文字列の長さを確認します*/
for(a = 0;str[a];a++)
;

for(b = 0;str2[b];b++)
;


printf("%s ha %d mozinonagasadesu\n",str1,a);
printf("%s ha %d mozinonagasadesu\n",str2,b);

/*文字列を比較します*/
for(i = 0;;i++){
if(str1[i] > str2[i])
printf("%s は %s より大きい\n"str1,str2);
else if(str1[i] < str2[i])
printf("%s は %s より小さい\n"str1,str2);

if(str1[i] > str2[i] || str1[i] <str2[i])
break;
}
for(i=0;str1[i] && str2[i];i++)
if(str1[i] == str2[i] )
printf("文字列は等しい\n");

/*上のプログラミングだとstr1がaab、str2がaacのときも文字列が等しいと表示してしまうので、ぴったり等しいときのみ表示するにはどのように条件付けしたらよいでしょうか?*/

return 0;
}

ちなみにstr1[0]=a ,str1[1]=b, str2[0]=a, str[1]=b, str[2]=cが格納されていた場合、str1 < str2になると思うのですが正しいでしょうか?
もし正しければこの場合str1[2]にはヌル文字が入っており、それがstr2[2]のcと比較されたためなのでしょうか?

いろいろと質問してしまいましたが、分かる方解答お願いします。

投稿日時 - 2010-11-16 18:14:44

QNo.6323750

すぐに回答ほしいです

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

まず、最初のforループに終了条件がありません。
文字列に相違があればループを抜けますが、等しい場合は永遠に繰り返します。(実際は領域外のゴミを拾って相違となるか、アクセス禁止領域にアクセスしてエラーになるかしますが)
どちらかの文字列が終端まで至ったところで比較を終了する必要があります。

次に、等しいかどうかの判定はループを出た時の文字の比較のままでいいのに、最初からループをやり直し、等しい時に抜け出てるので、1文字目が等しい文字列はすべて「等しい」となってしまいます。

以上のところに気を付ければ良いかと。

投稿日時 - 2010-11-16 18:35:44

お礼

forループの終了条件が抜けていましたか。気づきませんでした。
コンパイルできてしまったので。
プログラムが動いたのは解答していただいた理由によるものなんですね。
しっかり覚えておきたいと思います。
>次に、等しいかどうかの判定はループを出た時の文字の比較のままでいいのに、
そうですね。よく考えたらループを抜け出たものが等しければそれでいいんですよね。

大変分かりやすい説明ありがとうございました。

投稿日時 - 2010-11-16 19:00:56

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

タイトルはせめて「strcmpの自作」とかなんとか付けましょう。

すでに色々言われていますが、方針として

1.先頭から一つずつ要素を比較。いずれかの要素がヌル文字になるまで繰り返し
2.途中で異なる要素にヒットしたら、その大小により「大きい」もしくは「小さい」結果を返す
3.繰り返し終了まで到達したときに両方がヌル文字なら「等しい」、片方だけヌル文字ならそちらが「小さい」

という流れになります。
文字列長の差異と要素の差異でどちらが優先されるかはmanには書いてなかったのでとりあえず要素優先で書いてあります。

投稿日時 - 2010-11-17 09:48:41

お礼

解答ありがとうございます。
ご指摘を参考にして、何とかうまくプログラムを作り、実行することができました。

投稿日時 - 2010-11-17 15:50:25

ANo.4

for(i = 0;str1[i] != \0 || str2[i] != \0;i++){

これって本当に動かしてみましたか?
...初頭でナルかどうかを判断しているんで、思うような判断処理はできないと思いますが。
for()を使ったサンプルプログラムを↓に示しておきます。
トレース付きにしてありますのでいろいろ試してみてください。そして、あなたのやり方とどこが違うのかを調べてください。
なお、片方がナル文字の場合はうまく処理してくれません。その理由とその処置に対処できれば、完成します。


#include<stdio.h>
#define EQUAL"%s=%s\n"
#define GREATE"%s>%s\n"
#define SMALL"%s<%s\n"

int main(void)
{
char str1[50],str2[50];
int i;

printf("第1の文字列を入力してください: ");
gets(str1);
printf("第2の文字列を入力してください: ");
gets(str2);

for(i=0; i<50 && (str1[i] !='\0' || str2[i]!='\0'); i++) {
printf("\ttrace(%d): %c, %c\n", i, str1[i], str2[i]);
if(str1[i]>str2[i]){
printf(GREATE, str1,str2);
break;
} else if(str1[i]<str2[i]){
printf(SMALL, str1,str2);
break;
} else if(str1[i+1]=='\0') {
printf("\ttrace(%d): %s, ", i+1, "NULL");
if(str2[i+1]=='\0') {
printf("%s\n", "NULL");
printf(EQUAL, str1,str2);
} else {
printf("%c\n", str2[i+1]);
printf(SMALL, str1,str2);
}
break;
} else if(str2[i+1]=='\0') {
if(str1[i+1]!='\0') {
printf("\ttrace(%d): %c, %s\n", i+1, str1[i+1], "NULL");
printf(GREATE, str1, str2);
}
break;
}
}

return 0;
}

投稿日時 - 2010-11-17 07:39:07

お礼

>for(i = 0;str1[i] != \0 || str2[i] != \0;i++){
すいません。正しくは'\0'でした。
また、最後のprintfの部分ですが、うまく条件付けしたら、コンパイル出来てforループもきちんと成立しました。
ご指摘ありがとうございました。

投稿日時 - 2010-11-17 15:48:17

ANo.3

#1 です。

> ちなみにstr1[0]=a ,str1[1]=b, str2[0]=a, str[1]=b, str[2]=cが格納されていた場合、str1 < str2になると思うのですが正しいでしょうか?

 とくに条件が付けられているのでなければ、それで正しいと思います。

> もし正しければこの場合str1[2]にはヌル文字が入っており、それがstr2[2]のcと比較されたためなのでしょうか?

 上記のプログラム上ではそうなります。

投稿日時 - 2010-11-16 18:39:58

お礼

再びの解答ありがとうございます。
解答していただいたことで、疑問は解消できました。
一応プログラムを変更してみたのですが、forの条件式はこれで大丈夫でしょうか?
何度も分かりやすく解答していただいているので、もう一度解答していただけると本当に助かります。
/*文字列を比較します*/
for(i = 0;str1[i] != \0 || str2[i] != \0;i++){
if(str1[i] > str2[i])
printf("%s ha %s yoriookii\n"str1,str2);
else if(str1[i] < str2[i])
printf("%s ha %s yoritiisai\n"str1,str2);

if(str1[i] > str2[i] || str1[i] <str2[i])
break;
}

printf("moziretuhahitosii\n");

投稿日時 - 2010-11-16 19:21:34

ANo.2

まず日本語の問題から指摘しておこう. 最後に
「もし正しければこの場合str1[2]にはヌル文字が入っており、それがstr2[2]のcと比較されたためなのでしょうか?」
と書いているが, 「比較されたため」なんだといっている?

あとはプログラムの問題:
比較のところで最初の for に終了条件がないのはなぜ?
あと, 次の for で i をまた 0 から回す必然性が分からんし, なんで毎回表示するの?

投稿日時 - 2010-11-16 18:39:25

お礼

ご解答ありがとうございます。
forの終了条件が抜けていました。
修正したいと思います。
また、次のforループを修正したいと思います。

投稿日時 - 2010-11-16 18:56:08

あなたにオススメの質問