C: scanf()関数の連続使用は注意

scanf()関数を2回(以上)連続で使用した場合、意図しない動作になることがあります。

scanf()関数

scanf()関数は文字列を読み込む関数ですが、以下のように2回連続で使うと、(プログラマが意図した通りには)うまく動いてくれません。

  char c, *str;

  printf("文字列を入力してください: ");
  scanf("%s", str);
  printf("文字を入力してください: ");
  scanf("%c", &c);

これを実行し、例えば「abc」と入力してリターンキーを押してみましょう。
すると2つ目のscanf()関数で止まらずに、そのまま進んでしまいます。


原因

scanf()関数は、入力された文字を一度バッファに溜め、そのデータを読み込みます。
さらに、%sを指定すると、空白やタブ、改行文字などは読み込みません。
上記の例でバッファに溜められるのは'a''b''c''\n'という4文字分がバッファに溜まっています。

すると、1つ目のscanf("%s")では"abc"という文字列が変数*strに代入されます。
が、まだ改行'\n'がバッファに残っているのです。
そして2つ目のscanf("%c")がバッファに残っている'\n'を読み込んでしまい、処理が次へ移ってしまいます。

つまり問題点は、「scanf()関数を連続使用するときに、2つ目以降に%cを指定するときは注意」ということです。
2つ目以降のscanf("%c")の代わりに、gets()やgetchar()を使ってもまずいでしょう。


対策

上記の問題を解消するには、以下のような方法があります。

  1. scanf("%c")の代わりにscanf("%s")を使い、1文字目を取り出す。
  2. scanf("%c")の代わりにscanf("%*c%c")を使う。
  3. scanf()関数とscnanf()関数の間に、fflush(stdin)関数を使う。(ただし、この関数は定義されていないことがある?)

とにかく、バッファに溜まっている余分な文字を一度吐き出してあげれば良いです。

参考



miniminisoftトップへ
THLAND ホームへ