よくある状況として、
|
0 1 2 3 |
int a; scanf("%d", &a); |
のようにすると、入力バッファに改行文字が残ってしまうため、直後にgetchar関数などを呼び出すと期待した動作にならないことがあります。
これを何とか回避しようとして、fflush(stdin)を使用しているサンプルをよく見かけます。しかし、fflush関数というのは、出力ストリーム、または直前の操作が入力ではない更新ストリームに対して使用するものであり、それ以外の場合は未定義の動作になります。
少なくとも複数の有名な処理系のマニュアルには、fflush(stdin)を入力ストリームに対して使用できる旨の記述があるため、上のように書いてもなかなか信用していただけないかもしれません。そこで、C言語の標準規格から該当部分を引用したいと思います。
7.19.5.2 fflush 関数
形式
#include
int fflush(FILE *stream);
機能 stream が出力ストリーム又は直前の操作が入力でない更新ストリームを指すとき,fflush 関数はそのストリームでまだ書き込まれていないデータをホスト環境に引き渡し,ホスト環境がそのデータをファイルに書き込む。それ以外のときの動作は,未定義とする。
stream が空ポインタのとき,fflush 関数は,この箇条で動作が定義されているすべてのストリームに対して,その定義されている動作を行う。
返却値 fflush 関数は,書込みエラーが発生した場合,エラー表示子をセットし,EOF を返す。その他の場合,0 を返す。
というわけで、入力ストリームに対してfflush関数を使うのは未定義の動作ということになり、少なくとも移植性のあるプログラムにはふさわしくないということになります。
では、入力バッファをクリアするにはどうすればよいのでしょうか?
入力バッファをクリアするための移植性がある確実な方法は、規格では定義されていません。また、setbuf関数やsetvbuf関数で入力ストリームをバッファリング無しに指定したとしても、既に入力されてしまったデータを取り消すことはできません。
結局のところ、移植性を保ちながら確実に入力バッファをクリアするには、必要なだけ空読みするしかなさそうです。

![[迷信] getsは単純にfgetsに置き換えられる](https://www.kijineko.co.jp/wp-content/uploads/2021/06/5063693_s.jpg)
![[迷信] 実数型とは浮動小数点型のことである](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4011255_s.jpg)
![[迷信] 'A'~'Z'の値は連続している](https://www.kijineko.co.jp/wp-content/uploads/2021/05/2120715_s.jpg)
![[迷信] 文字列から整数への変換にはatoi](https://www.kijineko.co.jp/wp-content/uploads/2021/06/5030499_s.jpg)
![[迷信] 識別子に使える文字は英数字と下線のみ](https://www.kijineko.co.jp/wp-content/uploads/2021/06/1210817_s.jpg)
![[迷信] 今どきint型が16ビットの処理系なんて無い](https://www.kijineko.co.jp/wp-content/uploads/2021/05/4618601_s.jpg)