• ベストアンサー

なぜ2回表示されるのでしょうか?

このたび、諸事情によりC言語から再入門中です。 VisualC++2005を使っています。 do~while文を用いて、キーボードから'q'が入力されるまで、 画面に"qを入力して下さい"と表示し続けるプログラムを 作成してみました。 #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> // キーボードから'q'が入力されるまで、画面に"qを入力して下さい"と表示し続けるプログラム int main(void) { char c = '\0'; do { printf("qを入力して下さい\n"); scanf("%c", &c); if (c == 'q') { break; } }while(1); return 0; } 実行してみると、以下のように動作します。 1."qを入力して下さい\n"が表示される 2.'a'を入力してEnter 3."qを入力して下さい\n"が2行表示される おそらく、2の際に、'a'と'\0'を受け取ってしまい、 それが3の原因になっている気がします。 でも、scanfで"%c"を指定しているのに、こんなこと あり得るのでしょうか? 仮にソースに誤りが無かった場合、 たかが演習とはいえ自分としてはこの動作を回避したいのですが、 どういった対策があるのでしょうか? 初歩的な質問で申し訳ありませんが、よろしくお願いしますm(__)m

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

この現象は有名ですね。 これはscanfに「指定した文字だけを読み込む」という 仕様があるためです。 aをコンソールで入力すると "a\n"   という文字列が入力ストリームの中に入ります。 (ダブルクォートは含まない) scanf("%c", &c);とすると、%cにマッチする'a'が まず読み込まれますが、'\n'は読み込まれずに 入力ストリームに残ったままとなります。 このため、ループして2回目にコールされた scanf("%c", &c);で'\n'が読み込まれ 3回目で入力ストリームが空なので、 また入力を待ちます。 #include <stdio.h> int main(void) {  char c = '\0';  do{   printf("qを入力して下さい\n");   scanf("%c%*[^\n]%*c", &c);   if (c == 'q'){    break;   }  }while(1);  return 0; }

noname#32133
質問者

お礼

aris-wizさんありがとうございます。 有名な現象なんですねー、全然知らなかったです。 仕事でVisualC++やらC#使ってるのにちょっと恥ずかしいです^_^; 実は、上記言語を使って開発はなぜかできちゃってるけど、 (それも危険な話ですよね・・・) 自分で理解してないことに危機感を感じる場面がありまして。 今のうちに手を打たなければと思って、自学で再入門している次第です。 aris-wizさんが回答された内容を踏まえて、 「新ANSI C言語辞典」でscanf関数を調べてみました。 処理内容はaris-wizさんが書かれていたソースと同じですが、 1.1文字入力 2.Enterの直前まで切り捨てる 3.Enterを切り捨てる の3つの処理に分かれていて、それを見てようやく理解できました^_^; 正規表現も覚えきれてないことに気づいて少々凹み気味です。 でも、以前に一緒に仕事した方に言われた 「気づいたときに一歩を踏み出しているんですよ」 という言葉を思い出してモチベーション上がったところです。

その他の回答 (1)

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

入力のときに'a'と'Enter'の2回キーを押しますよね 'a'と'\0'ではなくて'a'と'\n'(改行)を受け取るためにそうなります。 scanf("%c", &c); を scanf(" %c", &c); にしたらとりあえずは回避されると思います。

noname#32133
質問者

お礼

php504さんありがとうございます。 'a'と'\0'ではなくて'a'と'\n'(改行)を受け取るのですね。

関連するQ&A

専門家に質問してみよう