scanf関数を使うことがあまりよくないらしいのですが、なぜでしょうか?
また、scanfのエラーに対する処理としてバッファをクリアすることがあるようですが、
そもそもバッファってなんですか?自分で調べた程度ではバッファ=scanfで入力されたものであり、メモリに入れる前のもの
という解釈なのですが、いまいちわかりません・・・。
用意した文字数以上の文字数を入力された場合、数字のはずが文字を入力された場合に
その、バッファをクリアするわけですよね。勝手にはクリアされないということでしょうか。
勉強しているサイトでは↓のプログラムのようにすればいいということなんですが、
「scanf("%*[^\n]%*c");」の行う意味、なぜこれでクリアされるかがわかりません。
どうか、解説お願いします。
バッファのクリア
Re: バッファのクリア
ここでいうバッファの解釈はそれでいいと思います。
たとえば、提示のプログラムを実行して、scanf()で"aaa"+リターンとか入力すると、scanf()はplaceに入力値aaaを格納できません。
#数値を求めているわけで。
この時読み込めなかったaaaは次のscanf()の読み込み対象となります。
なのでaaaを読み込み対象から外さない限り、scanf("%d",&place)は0を返し続けます。
aaaを読み込み対象から外すためにscanf("%*[^\n]%*c")を使用します。
最初の%*[^\n]で”改行コードまでの文字列”を読み飛ばします。scanf()での%*は読み飛ばしだと思ってください。
次の%*cで1文字読み飛ばします。最初の%*[^\n]で改行以外を全部読み飛ばしているので、次の%*cは改行そのものです。
これによって、aaaと改行を読み込んで(バッファから取り除いて)かつ、次のscanf("%d",&place)では入力を待つようになります。
#と、ここまで解説したのですが、scanf("%d",&place)ならscanf("%*[^\n]")でもバッファクリアできそうですね。
#scanf("%c%d",...)ならscanf("%*[^\n]%*c")としないとダメかな。
たとえば、提示のプログラムを実行して、scanf()で"aaa"+リターンとか入力すると、scanf()はplaceに入力値aaaを格納できません。
#数値を求めているわけで。
この時読み込めなかったaaaは次のscanf()の読み込み対象となります。
なのでaaaを読み込み対象から外さない限り、scanf("%d",&place)は0を返し続けます。
aaaを読み込み対象から外すためにscanf("%*[^\n]%*c")を使用します。
最初の%*[^\n]で”改行コードまでの文字列”を読み飛ばします。scanf()での%*は読み飛ばしだと思ってください。
次の%*cで1文字読み飛ばします。最初の%*[^\n]で改行以外を全部読み飛ばしているので、次の%*cは改行そのものです。
これによって、aaaと改行を読み込んで(バッファから取り除いて)かつ、次のscanf("%d",&place)では入力を待つようになります。
#と、ここまで解説したのですが、scanf("%d",&place)ならscanf("%*[^\n]")でもバッファクリアできそうですね。
#scanf("%c%d",...)ならscanf("%*[^\n]%*c")としないとダメかな。
Re: バッファのクリア
クリアされません。 依然として入力バッファには改行コードが残ります。Poco さんが書きました: #と、ここまで解説したのですが、scanf("%d",&place)ならscanf("%*[^\n]")でもバッファクリアできそうですね。
scanf("%d", &hoge"); というコードが実行され、
"aaa+\n" という文字列が入力された時、
"aaa+\n" は数字では無いので読み込まれません。
入力バッファには、"aaa+\n" がそのまま残ります。
続く、scanf("%*[^\n]"); というコードが実行され、
改行コード以外の、"aaa+" が読み飛ばされます。
入力バッファには、"\n" が残ります。
原則として、入力バッファは頭から順番に読まれます。
Re: バッファのクリア
[quote="Poco"]
aaaを読み込み対象から外すためにscanf("%*[^\n]%*c")を使用します。
最初の%*[^\n]で”改行コードまでの文字列”を読み飛ばします。scanf()での%*は読み飛ばしだと思ってください。
次の%*cで1文字読み飛ばします。最初の%*[^\n]で改行以外を全部読み飛ばしているので、次の%*cは改行そのものです。
これによって、aaaと改行を読み込んで(バッファから取り除いて)かつ、次のscanf("%d",&place)では入力を待つようになります。
1、%*[^\n]によって入力された文字列の改行まで飛ぶ
2、%*cによって改行
(3、continueで次のループへ飛ぶ)
(4、次のscanfを行う)
ということでしょうか?
]
aaaを読み込み対象から外すためにscanf("%*[^\n]%*c")を使用します。
最初の%*[^\n]で”改行コードまでの文字列”を読み飛ばします。scanf()での%*は読み飛ばしだと思ってください。
次の%*cで1文字読み飛ばします。最初の%*[^\n]で改行以外を全部読み飛ばしているので、次の%*cは改行そのものです。
これによって、aaaと改行を読み込んで(バッファから取り除いて)かつ、次のscanf("%d",&place)では入力を待つようになります。
1、%*[^\n]によって入力された文字列の改行まで飛ぶ
2、%*cによって改行
(3、continueで次のループへ飛ぶ)
(4、次のscanfを行う)
ということでしょうか?
]
Re: バッファのクリア
そうです。
またこの場合、%*cを指定しなくても4のscanfで改行を読み飛ばします。
#へろりんごさんの指摘通り、バッファクリアが行われる訳ではなく、結果として問題なく動作するという意味で書きました。
#誤解させるようなことを書いてすみません。
#指摘ありがとうございます。>へろりんごさん
またこの場合、%*cを指定しなくても4のscanfで改行を読み飛ばします。
#へろりんごさんの指摘通り、バッファクリアが行われる訳ではなく、結果として問題なく動作するという意味で書きました。
#誤解させるようなことを書いてすみません。
#指摘ありがとうございます。>へろりんごさん