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

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

解決済みの質問

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を使用しております。

投稿日時 - 2007-01-22 20:10:57

QNo.2687494

すぐに回答ほしいです

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

scanf()では入力バッファに改行コードが残ってしまいます
scanf(" %c",&c);
とすれば改行コードを含む空白を読み飛ばしてくれます

投稿日時 - 2007-01-22 20:50:14

補足

php504様へ
ご回答ありがとうございました。
charの入力待ちをしてくれない問題については
理解できたつもりですが、どうしてもわからないことが
あります。
scanf()によるcharの入力待ちの後に文字を入力してEnter
した後、どうしてscanf()によるintの入力待ちが問題がなく
行えているのでしょうか?どうかご教授お願いします。

投稿日時 - 2007-01-22 21:36:53

お礼

php504様へ

あれこれと試行錯誤しているうちに問題が解決しました。
シンプルであり、かつ適切なご回答であったことが
今になって気づけました。いろいろとありがとう
ございました。

投稿日時 - 2007-01-23 01:31:38

ANo.1

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

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

回答(2)

ANo.2

 #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)、を呼びだすなど。

 長文になってしまい失礼します。

投稿日時 - 2007-01-22 23:29:34

補足

glphon様へ
ご回答ありがとうございました。
ご丁寧でわかりやすいご説明により、勘違いをしていたことに気づけて
感謝しております。php504様のご説明で理解できなかった
ことに対して、勉強不足を痛感しております。
glphon様のご指摘のとおりにネットで検索しましたところ、
いくつかわかりやすく解説されているサイトを見つけることが
できました。その中でどうしてもひっかかる問題に気づいてしまい
ました。最後に一つだけ質問をさせてください。
glphon様が問題解決方法をご指摘されておられるので恐縮ですが、
どうしても納得しておきたいことがあります。
php504様のご指摘したscanf(" %c",&c)のように””内にスペース
を入れると、確かに問題は回避できるのですが、なぜ、スペースを
入れると、改行コードを読み飛ばせるのでしょうか変な質問で
すみません。どうかご教授お願いします。

投稿日時 - 2007-01-23 00:21:18

お礼

glphon様へ
あれこれ試行錯誤しているうちに解決しました。
いろいろとありがとうございました。

投稿日時 - 2007-01-23 01:27:50