- ベストアンサー
scanf()関数の使い方について
はじめまして。 質問があります。 まずは、以下のコードを見てください。 ---------------------------------------------------------------- #include<stdio.h> int main(void) { char c; int i; printf("0を入力すると終了します。\n"); while(1) { printf("文字を入力してください=>"); scanf("%c",&c); printf("入力した文字は %c です。\n",c); printf("数字を入力してください=>"); scanf("%d",&i); if(i==0) { break; } printf("入力した数字は %d です。\n",i); } return 0; } ---------------------------------------------------------------- 上のコードを実行すると、初回はscanf()はcharとintの両方とも 入力待ちになってくれるのですが、2回目以降はcharは入力待ちに なってくれません。これは、なぜなのでしょうか? ご教授お願いします。 現在VC++6.0を使用しております。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
scanf()では入力バッファに改行コードが残ってしまいます scanf(" %c",&c); とすれば改行コードを含む空白を読み飛ばしてくれます
その他の回答 (1)
- glphon
- ベストアンサー率26% (41/152)
#1の方がとても有用な回答をした後で恐縮です。 「scanf バッファ」これで検索するだけでも様々な事が出てくると思います。 どうもphp504様の回答に対してtakeshix100様はscanfに対する勘違いをまだ拭えていないようなので、少し補足いたします。 scanfに"%c"を渡した時と"%d"を渡した時ではまったく挙動が異なります(関数内で分岐させて処理します) ============ 実行のの内容を追って考えて見れば分かります。 例えば最初のscanf("%c",&c)の時に"123456[Enter]"を入力したとします。 すると入力バッファには"123456\n"が入ります。 %cでは1文字取得するので "123456\n" 先頭の'1'が入力バッファから読み出され、残りの入力バッファは"23456\n"になります。 次にscanf("%d",&i)で呼び出すと "23456\n" 先頭の整数(2)から整数でない'\n'の直前(6)までを引き出し、入力バッファには"\n"が残ります。 再度のscanf("%c",&c)では、入力バッファから先頭の'\n'を引き出し入力待ちになる事なく処理を継続します。 ============ 今回の現象は%dで呼び出した直後に%cを呼び出した事が原因となります。 >どうしてscanf()によるintの入力待ちが問題がなく行えているのでしょうか? 変な話ですがscanfは必ずしも鮮度の高い入力を受け取ろうとしません。 scanfは"入力バッファ"から受け取る為、入力バッファに中身がある時はそこから受け取り、無い時にだけ蓄えるために入力待ち状態になります。 scnafで入力待ちが行われる事は自然ですし、入力待ちが無い事もまた自然なのです。 対策としては一旦文字列で入力を受け取り、それ整数に変換(atoi)したり、 scanfの直後に入力バッファを空っぽにさせましょう。 例えばfflush (stdin)、rewind (stdin)、fseek (stdin, 0, SEEK_END)、を呼びだすなど。 長文になってしまい失礼します。
お礼
glphon様へ あれこれ試行錯誤しているうちに解決しました。 いろいろとありがとうございました。
補足
glphon様へ ご回答ありがとうございました。 ご丁寧でわかりやすいご説明により、勘違いをしていたことに気づけて 感謝しております。php504様のご説明で理解できなかった ことに対して、勉強不足を痛感しております。 glphon様のご指摘のとおりにネットで検索しましたところ、 いくつかわかりやすく解説されているサイトを見つけることが できました。その中でどうしてもひっかかる問題に気づいてしまい ました。最後に一つだけ質問をさせてください。 glphon様が問題解決方法をご指摘されておられるので恐縮ですが、 どうしても納得しておきたいことがあります。 php504様のご指摘したscanf(" %c",&c)のように””内にスペース を入れると、確かに問題は回避できるのですが、なぜ、スペースを 入れると、改行コードを読み飛ばせるのでしょうか変な質問で すみません。どうかご教授お願いします。
お礼
php504様へ あれこれと試行錯誤しているうちに問題が解決しました。 シンプルであり、かつ適切なご回答であったことが 今になって気づけました。いろいろとありがとう ございました。
補足
php504様へ ご回答ありがとうございました。 charの入力待ちをしてくれない問題については 理解できたつもりですが、どうしてもわからないことが あります。 scanf()によるcharの入力待ちの後に文字を入力してEnter した後、どうしてscanf()によるintの入力待ちが問題がなく 行えているのでしょうか?どうかご教授お願いします。