- 締切済み
文字列の比較
char *c; scanf("%s",c); で文字列を取得し、もし exit と入力したとき if(/*ココ*/)return(0); としてプログラムを終わらせたいのですが、 /*ココ*/ の部分を c[0]='e' &&c[1]='x' &&c[2]='i' &&c[3]='t' &&c[4]='NULL' とするほかに方法はありますか? c=="exit"ではできませんでした。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- ret
- ベストアンサー率40% (8/20)
#3です。 char* c というのはポインタ変数ですね。 ポインタ変数というのは、どこかのアドレスを 「値として」もつ変数ですね。 このプログラムで、char* cは宣言されているだけで、 値が振り分けられていません。 つまり、どこのアドレスが指されているかわからないわけです。 非常に危険なプログラムと言ったのは、 もし落ちずに動作すればどこのアドレスに書き込むか解らないからです。 スタック領域を壊されると大変です。 (暴走ですね…) scanfですが、 scanfは入力データをバッファリングしていますが 複改文字はそのままバッファに残します。 ですので、次の入力操作が行われた際に予期せぬ誤動作を招くことがあります。 (まぁ、その対応をしていれば問題ないですが…(^^;) また、scanfは読み込み不一致発生時にデータをバッファに残します。 若しwhileループ等でscanfを使っているならば 下手をすれば無限ループに陥る可能性もあります。 (あくまで可能性ですよ…(^^;)。 fgetsで読み込み、sscanfやatoiを使うのが堅実です。 但しfgets使用時はファイルにリダイレクトしていないという前提のもとで 使わなければなりません。 もう少しちなみに… #4の方に… char c[10]; fgets(c, 9, stdin); c[9]='\0'; とありますが、 fgets(c, 9, stdin); としないでfgets(c, 10, stdin); としてかまわないですよ。 fgetsが自動的に9バイトまで埋めてくれて 最後に'\0'を付加してくれます。
char *c; では領域の実体がないので、これをscanf()に使用するとメモリを壊します。 char c[10]; のようにしてください。 しかし、これにしてもscanf()で10文字以上入力されたら領域をはみ出してメモリを壊します。 char c[10]; fgets(c, 9, stdin); c[9]='\0'; とするのが安全です。 意味は考えてみてください。
- ret
- ベストアンサー率40% (8/20)
ども。早速回答ですが、 if( c[0] == 'e' && c[1] == 'x' && c[2] == 'i' && c[3] == 't' && c[4] == '\0') return(0); とNULLではなくNULL文字'\0'にすればいいだけでは? というより、値を振り当てていないchar* cによく scanfを行いましたね?(^^;。 プログラム落ちなかったですか? これって、非常に危険なプログラムですよ…(^^;。
c[4]=='NULL' は間違いです。 c[4]=='\0' が正解です。 それで動くと思いますよ。
お礼
あれ、間違いだったんですね^^; ありがとうございます^^
文字列比較関数があります。 strcmp(c, "exit")==0 でできますよ。
お礼
さっそくのご回答ありがとうございますm(_ _)m なるほど、そんな関数があったんですね! その標準関数を使わずに比較するにはどうすればいいですか? それと間違っていたのですが、 c[4]=='NULL'をいれると出来ませんでした。
補足
訂正です c[0]='e' &&c[1]='x' &&c[2]='i' &&c[3]='t' &&c[4]='NULL' ではなく c[0]=='e' &&c[1]=='x' &&c[2]=='i' &&c[3]=='t' ですNULLを入れるとなぜか出来ませんでした・・ しかしこうしてしまうと exitaaaaaaaa と入力してしまっても真になってしまいます。
お礼
ありがとうございます よくscanfはバグがおき易いって聞きますよね。 普通に動いてしまったのですが、なぜ危険なのか教えてもらえないでしょうか。これを機会に学習しておきたいですm(_ _)m