 
 
 
 
 
 
 
  
そもそも scanf というのは、お節介と言ってもいいくらい、複雑な処理を することが出来る関数なんです。そういう奴が間違った入力を受けとると、ず いぶんと間抜けなことをしてくれます。 scanf() は正常に読みとれた値の個 数を返しますから、それをチェックすればいいと考える人もいるでしょうが、 実は駄目です。
| 
/* とりあえず正しいつもりのプログラム */
#include <stdio.h>
int main()
{
    double a;
    while (1) {
        if (scanf("%lf", &a) == 0) {
            fprintf(stderr, " scanf() で 0 個しか正常に読み込めませんでした。\n");
        }
        else {
            printf("%f\n", a);
            exit(0);
        }
    }
    return 0;
}
 | 
| oyabun% test-scanf 1.2 1.200000 oyabun% test-scanf 0.000000 oyabun% scanf 1,2 1.000000 oyabun% scanf ,2 scanf() で 0 個しか正常に読み込めませんでした。 scanf() で 0 個しか正常に読み込めませんでした。 scanf() で 0 個しか正常に読み込めませんでした。 略 scanf() で 0 個しか正常に読み込めませんでした。 scanf() で 0 個しか正常に読み込めませんでした。 ^C scanf() で 0 個しか正常に読み込めませんでした。 oyabun% | 
では正しい入力はというと、
| #include <stdio.h>
#include <stdlib.h>             /* atof() のため */
#include <floatingpoint.h>        /* strtod() */
int main()
{
    double a;
    char input[100];
    if (fgets(input, sizeof(input), stdin) == NULL) {
        fprintf(stderr, "input error?\n");
    exit(1);
    }
    /* atof() の利用 */
    a = atof(input);
    printf("%f\n", a);
    /* sscanf() の利用 */
    if (sscanf(input, "%lf", &a) == 0) {
        fprintf(stderr, " sscanf() で 0 個しか正常に読み込めませんでした。\n");
    }
    else
        printf("%f\n", a);
    /* strtod() の利用 */
    {
    char *p;
    a = strtod(input, &p);
    if (input == p) {
        fprintf(stderr, " strtod() が読み込みに失敗しました\n");
        exit(1);
    }
    printf("%f\n", a);
    }
    return 0;
}
 | 
どうですか?めんどい、やってらんない、と思う人が多いと想像します。筆 者は、普通の数値計算実行者が作る、いわゆるシステム・プログラムでないプ ログラムでは、それほど神経質になる必要はなく、「あ、入力を間違えた!し かたないから、最初からやりなおそう」でいいと思います。ただし、長い計算 の後にユーザーのキーボードからの指示を読んで態度を決めるようなプログラ ムでは、それまでの計算結果を無駄にしないように、それなりの注意がいるで しょう。その場合も sscanf() でチェックする程度でよいと思います。
 
 
 
 
 
 
