Scanf
入力バッファのクリアはここでは文字列を空読みすることで実現している(入力バッファのクリア方法は状況によって異なる方法が考えられる)。なお主にウェブ上などで、標準入力のバッファクリアの方法に fflush(stdin) や rewind(stdin) とする方法が紹介されることがあるが、ANSI規格ではこれらの動作は未定義であり、正しい動作を保障するものではない。
この方法でエラー処理をする場合には上記の空白文字の取り扱いの関連で問題になることがある。例えば
のようなコードで、異常な入力があった場合エラー処理をしたいとする。これを
という方法で実現すると入力が "1" のみの場合、空白と改行は同一視されてしまうため、変数 "i" に 1 を入力して後、変数 "j"の入力待ち状態となる。もし、このような場合にもエラー処理を実行したい場合には、例えば以下のように一度文字列として読み込んで、その後 sscanf で読み込むことで実装すればよい。
ソース:
出力結果の例:
他の C言語の文字列処理関数と同様に、scanf を使用する際にもバッファオーバーランが発生する可能性がある。例えば
というコードがあった場合、a に入力できる文字列は終了文字を除く、19バイトまでしか入力することが出来ず、それ以上の文字列が入力されるとバッファオーバーランが発生する。a の領域が十分であれば問題はないが、しかし入力されてくる文字列の長さを予測することは不可能であり、結局 a の長さをいくら大きくしても、さらにそれを上回る長さの入力が行われてしまえばバッファオーバーランが発生してしまう危険性がある。 この問題を防ぐ手段として一般的なのは最大フィールド幅を指定することである。上記の例の場合は
とすることで、aには最初の19バイトが読み込まれ入力を終了する。ただしこの場合は残りの文字列はストリーム上に残ってしまうので実際には以下のようにすることで対処される。
これは19バイト読み込みさらに改行文字までの文字列を空読みすることを意味する。
さらに前述の改行コードがストリームに残る問題を考慮すると
となるが、この場合はaに入る文字列が 19バイト以下の場合には、入力ストリームにやはり改行文字が残る。よって実際には、
のように入力終了後、改行文字を空読みするなどの方法がとられる。空白文字の取り扱いも考慮する場合
となる。
バージョン8.0 (2005) 以降のMicrosoft Visual C++コンパイラには、scanf_s() という関数が用意されていて、バッファのサイズを指定することができる。scanf_s はC11規格で標準化されたが、実装は任意である。