ページ 1 / 1
scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月04日(日) 22:00
by taz
こんにちは。
scanfは予期しない入力があると無限ループに陥るようですが、
文字などが入力された場合どのように無限ループを回避すればよいですか?
実際にコードを示してくださるとありがたいです。
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月04日(日) 22:22
by nil
私も一度困ったことがあります。
コード:
bool run = true;
int data = 0;
while( run ){
char input[ 64 ] = {};
scanf( "%s", input );
if( sscanf( input, "%d", &data ) == 1 ) run = false;
}
テストはしてないのでちゃんと動くかはわからないのですが、自分は結局こうやってクリアしました。
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月04日(日) 22:43
by taz
以下のようにしましたが、うまく動いてくれないようです。
コード:
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;
}
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月04日(日) 23:05
by へにっくす
5行目が%dっておかしいでしょ
涼雅さんのコードはそうなってません。
それにswitchに入れる変数も違うと思います(ってーかコンパイルできないのでは?)。
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月04日(日) 23:34
by かずま
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 です
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月05日(月) 13:59
by taz
コード:
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は予期しない入力があると無限ループに陥る
Posted: 2012年11月05日(月) 16:11
by かずま
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;
}
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月05日(月) 18:24
by nil
5行目
scanf("%s", &select);
ではなく
scanf("%s", select);
が正しいのでは?
Re: scanfは予期しない入力があると無限ループに陥る
Posted: 2012年11月06日(火) 18:02
by needsueda
解決済みとのことなので今更なのですが、ちょっと気になるので意見を述べさせていただきます。
キーボードからの入力は、どんなコードが入ってくるかは判りません。
そもそも「数字」コードが来るとは限りません。
ですから、もしscanfを使われるなら、全て「文字」コードとして処理されるべきです。
つまり一旦文字列として受け取り、しかるべき後に数字に変換しなければなりません。
数字以外のコードは無視し数字コードのみを取り込むのが最も自然だと言えましょう。
scanfを使うと数字以外にも桁オーバーを気にする必要があります。収容する変数のサイズに
制限があることを考慮し、収容できない恐れがある桁オーバーはエラーとして処理する
ルーチンが必要となります。私見ですが、私はscanfは使わず私専用の取り込みルーチンを
関数として製作しており、そちらを使っています。