scanfは予期しない入力があると無限ループに陥る

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taz
記事: 35
登録日時: 13年前
住所: 兵庫

scanfは予期しない入力があると無限ループに陥る

#1

投稿記事 by taz » 13年前

こんにちは。

scanfは予期しない入力があると無限ループに陥るようですが、
文字などが入力された場合どのように無限ループを回避すればよいですか?
実際にコードを示してくださるとありがたいです。

nil
記事: 428
登録日時: 14年前

Re: scanfは予期しない入力があると無限ループに陥る

#2

投稿記事 by nil » 13年前

私も一度困ったことがあります。

コード:

bool run = true;
int data = 0;
while( run ){
    char input[ 64 ] = {};
    scanf( "%s", input );
    if( sscanf( input, "%d", &data ) == 1 ) run = false;
}
テストはしてないのでちゃんと動くかはわからないのですが、自分は結局こうやってクリアしました。

taz
記事: 35
登録日時: 13年前
住所: 兵庫

Re: scanfは予期しない入力があると無限ループに陥る

#3

投稿記事 by taz » 13年前

以下のようにしましたが、うまく動いてくれないようです。

コード:

bool run = true;
	int data = 0;
	while( run ){
    char select[ 64 ] = {};
    scanf("%d", &select);
    if( sscanf( select, "%d", &data ) == 1 ) run = false;
	} 


    //scanf("%d", &select);

    switch(select){
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:

            PMP_write_indication(s_pmp_schedule[select-1]);
            PMP_execution(s_pmp_schedule[select-1]);

            break;

        case 20:

            PMP_display_performance();
            break;

        case 99:

            return -1; /* 終了 */

        default:

            return 0;

    };

    return 0;
}

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: scanfは予期しない入力があると無限ループに陥る

#4

投稿記事 by へにっくす » 13年前

5行目が%dっておかしいでしょ
涼雅さんのコードはそうなってません。
それにswitchに入れる変数も違うと思います(ってーかコンパイルできないのでは?)。
written by へにっくす

かずま

Re: scanfは予期しない入力があると無限ループに陥る

#5

投稿記事 by かずま » 13年前

taz さんが書きました:scanfは予期しない入力があると無限ループに陥るようですが、
文字などが入力された場合どのように無限ループを回避すればよいですか?
実際にコードを示してくださるとありがたいです。

コード:

#include <stdio.h>
 
int main(void)
{
    int n, a;

    while (printf("a? "), (n = scanf("%d", &a)) != EOF)
        if (n != 1)
            scanf("%*[^\n]");
        else
            printf("a = %d\n", a);
    return 0;
}
実行結果

コード:

a? 123
a = 123
a? abc
a? 456
a = 456
a? 
Unix なら ^D、Windows なら ^Z で EOF です

taz
記事: 35
登録日時: 13年前
住所: 兵庫

Re: scanfは予期しない入力があると無限ループに陥る

#6

投稿記事 by taz » 13年前

コード:

bool run = true;
    int data = 0;
    while( run ){
    char select[ 64 ] = {};
    scanf("%s", &select);
    if( sscanf( select, "%d", &data ) == 1 ) run = false;
    } 
 
 
    //scanf("%d", &select);
 
    switch(data){
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
 
            PMP_write_indication(s_pmp_schedule[select-1]);
            PMP_execution(s_pmp_schedule[select-1]);
 
            break;
 
        case 20:
 
            PMP_display_performance();
            break;
 
        case 99:
 
            return -1; /* 終了 */
 
        default:
 
            return 0;
 
    };
 
    return 0;
} 

以上のようなコードでうまく動かす事が出来ました。ありがとうございました!

かずま

Re: scanfは予期しない入力があると無限ループに陥る

#7

投稿記事 by かずま » 13年前

scanf("%*[^\n]"); (行末まで読み飛ばす)が敬遠されたのかな。
scanf("%*s"); (予期せぬ文字列だけを読み飛ばす)でどうでしょうか?

コード:

#include <stdio.h>

int main(void)
{
    int select = 0;

    while (scanf("%d", &select) == 0) scanf("%*s"); // たった、これだけ

    if (feof(stdin)) select = 99;                   // 念のため

    printf("  select = %d\n", select);              // 確認

    switch (select) {
    case 1: case 2: case 3: case 4: case 5:
        printf("PMP_write_indication(s_pmp_schedule[select-1]);\n"
               "PMP_execution(s_pmp_schedule[select-1]);\n");
        break;
    case 20:
        printf("PMP_display_performance();\n");
        break;
    case 99:
        return -1; /* 終了 */
    default:
        return 0;
    }
    return 0;
}

nil
記事: 428
登録日時: 14年前

Re: scanfは予期しない入力があると無限ループに陥る

#8

投稿記事 by nil » 13年前

5行目
scanf("%s", &select);
ではなく
scanf("%s", select);
が正しいのでは?

needsueda

Re: scanfは予期しない入力があると無限ループに陥る

#9

投稿記事 by needsueda » 13年前

解決済みとのことなので今更なのですが、ちょっと気になるので意見を述べさせていただきます。
キーボードからの入力は、どんなコードが入ってくるかは判りません。
そもそも「数字」コードが来るとは限りません。
ですから、もしscanfを使われるなら、全て「文字」コードとして処理されるべきです。
つまり一旦文字列として受け取り、しかるべき後に数字に変換しなければなりません。
数字以外のコードは無視し数字コードのみを取り込むのが最も自然だと言えましょう。
scanfを使うと数字以外にも桁オーバーを気にする必要があります。収容する変数のサイズに
制限があることを考慮し、収容できない恐れがある桁オーバーはエラーとして処理する
ルーチンが必要となります。私見ですが、私はscanfは使わず私専用の取り込みルーチンを
関数として製作しており、そちらを使っています。

閉鎖

“C言語何でも質問掲示板” へ戻る