バグ:scanfで無限ループ!!簡単に起きるけど対策は・・・

Posted: 2013年04月22日

文字列操作(入力文字)で書いてしまうバグを紹介します。

プログラムプログラム:

#include <stdio.h>

int main(void)
{
    int n = 0;
    while (n != -1) {
        puts("input:");
        scanf(" %d", &n);
        printf("result: %dn", n);
    }

    return 0;
}

このプログラムにどのように文字列操作(入力値)にバグが存在すると思いますか?

  • 入力値が数値以外だと無限ループする

改善版プログラム改善版プログラム:

#include <stdio.h>

int main(void)
{
    int n = 0;
    while (n != -1) {
        puts("input:");
        while (scanf(" %d", &n) != 1) {
            scanf("%*s");
            if (feof(stdin) != 0) {
                return 1;
            }
        }
        printf("result: %dn", n);
    }

    return 0;
}

解説解説:

scanfは、対象の文字列以外は無視します。
無視した場合は、入力バッファーに値を残すため
入力した状態になったままです。

次のループ処理では、入力状態のため
現在の入力値で処理が行われ、無視されるを繰り返し
無限ループします。

修正版では、
scanfの返却値を見て
エラーの場合は、
入力バッファーをクリアし
処理を続けます。
正常にクリアできない場合は、
処理を中断します。

このバッファーのクリア方法は、
一例であり正しい処理方法ではありません。(ANSI C標準ではない)
バッファのクリア方法は、決められておらず
様々な方法(fflush)をもちいて対応しているようです。

極力scanfを使用しないことが一番いいかもしれません。
fgetsを使用することを個人的には推奨します。

カテゴリー: バグ, プログラム | タグ: , , | コメント無し »

コメント