OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

入力エラーの処理について。

  • すぐに回答を!
  • 質問No.228258
  • 閲覧数1396
  • ありがとう数6
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 85% (6/7)

Cプログラム初心者です。
例えば、floatの名前をlengthとして、scanfでユーザーに入力させるとします。その時ユーザが間違えて数字ではなく文字を入力した場合、その後のprintfの内容がループしてしまいます。どうしたら、ユーザーが間違えて入力したときに、入力ミスを伝え、もう一回入力をしてもらうことができるプログラムが作れるでしょうか。
以下がエラー処理をする前のプログラムの一部なのですが、、、。

float length;

printf("Enter length of the room in metre and press enter.\n");
scanf("%f", &length);
while (length>300)
{

printf("This programme only caluculate length under 300m.\n");
printf("Please re-enter the length in metre and press enter.\n");
scanf("%f", &length);

}/*End of while (length)*/
通報する
  • 回答数4
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.4
レベル13

ベストアンサー率 37% (570/1525)

どのレベルまでのエラーチェックが必要かが不明ですが…
私ならfgets()->strtod()という手順を踏みます。

・scanf()は入力を消費しない
scanf()はエラーを返したときに入力内容を消去しません。
結果、いとも簡単に無限ループに陥ります。
エラー派生時には入力バッファのフラッシュをする必要があります。
・gets()は入力文字数を制限できない
gets()は文字列入力関数ですが、入力文字数を制限する機能がありません。
結果、想定しない文字数を入力される可能性があります。
これは、scanf()で%sを使ったときも同じです。
(sanf()の場合は回避法アリ)
・atof()は変換不能文字を報告しない
atof()はエラーを報告する手段をもちません。
入力 出力
0.0  0.0
abc  0,0
1.0  1.0
1.b  1.0
abcや1.bという数値はありません。これらはエラーのはずですが、atof()にエラー報告の機能が無いために「変換可能だった文字だけを変換した結果(1.b→1.0)または、0.0(abc→0.0)」が返されます。

char *fgets()は入力文字の最大数を制限できます。
fgets(char *入力文字列用の配列,int 入力可能文字数+1,stdin);
入力可能文字数+1なので単純に配列のよう素数を指定すればオッケーです。
(入力文字の最後に'\0'が付加されるため「入力可能文字数+1」を指定します)
キーボード入力を受け取る場合最後の引数をstdinとします。

strtod()は変換不能文字を発見したときに、その文字のアドレスを報告します。
結果、1.bやabcなどという「数字として認識不能な並び」を発見できます。
double strtod(char *変換する文字列,char **変換不能文字のアドレス);

キーボード入力の場合の例)
double len ;
char str[10], *trm ;

if (fgets(str, sizeof(str), stdin) == NULL){
/* 9文字以内の文字列をキーボードから入力 */
/* fgets()がNULLを返したときは"入力無し”かエラー */
エラー処理
}

len = strtod(str, &trm) ; /* 文字列→浮動小数点変換 */
if (trm != NULL && (*trm != '\0' || *trm != '\n')) {
/* 変換不能文字が'\0'か改行なら入力は数値、それ以外なら数値以外の入力 */
printf("数値以外が入力された:%s", str) ;
エラー処理
}
/* lenに入力を浮動小数点変換したものが設定されている */
お礼コメント
lindamarie

お礼率 85% (6/7)

アドバイスありがとうございます。大変複雑な内容をわかりやすく、砕いて説明していただいて感謝しております。まだ始めたばかりですが、ひとつ、ひとつの関数が持つ利点、マイナス点を理解しながら勉強を続けたいと思います。
ありがとうございました。
投稿日時 - 2002-03-04 09:15:12
-PR-
-PR-

その他の回答 (全3件)

  • 回答No.1
レベル11

ベストアンサー率 33% (131/392)

scanf()は演習用にはよいですが、アプリには使いません。 scanf()は最悪の関数ですから。 文字列として入力させ、入力された文字列が正しいか、チェックして、それを実数に変換します。 文字列入力:gets() チェックには:isdigita() などを使うようです。 ...続きを読む
scanf()は演習用にはよいですが、アプリには使いません。
scanf()は最悪の関数ですから。

文字列として入力させ、入力された文字列が正しいか、チェックして、それを実数に変換します。

文字列入力:gets()
チェックには:isdigita()
などを使うようです。
お礼コメント
lindamarie

お礼率 85% (6/7)

早速アドバイス頂きありがとうございます。scanfは使わないほうがいいんですね。数字が入力できるから、、という単純な理由でscanfを使ってたんですが。エラーの時に大きな落とし穴と変わるんですね。貴重なアドバイスありがとうございました。
投稿日時 - 2002-03-04 05:15:18


  • 回答No.2
レベル9

ベストアンサー率 71% (59/82)

scanf()の戻り値を使えば良いんでは? scanf()系の関数は代入に成功した変数の 数を返します。ですから、 float length; do{ printf("Enter length of the room in metre (<= 300m) and press enter.\n"); } while( scanf("%f" ...続きを読む
scanf()の戻り値を使えば良いんでは?
scanf()系の関数は代入に成功した変数の
数を返します。ですから、

float length;
do{

printf("Enter length of the room in metre (<= 300m) and press enter.\n");

} while( scanf("%f", &length) < 1 || length > 300.0f || length < 0.0f);

面倒臭がりなのでwhileの中の条件式で全部判定させましたが、
見易いように分けた方がいいかも知れません。
お礼コメント
lindamarie

お礼率 85% (6/7)

早速アドバイス頂き、ありがとうございます。試してみます!
投稿日時 - 2002-03-04 07:37:15
  • 回答No.3
レベル13

ベストアンサー率 34% (574/1662)

scanf系の関数は想定外の入力に弱いので、 こういうエラー処理を考えるならまず使わないですね。 getsとatofがいいでしょう。 scanfの戻り値でもある程度はわかりますが、 多少厳密さに欠けます。 例えば,"123ABC"と入力した場合、エラーとするか、 123が入力されたとするかという違いです。 あとgetsよりもfgetsの方がバッファオーバーフローが ...続きを読む
scanf系の関数は想定外の入力に弱いので、
こういうエラー処理を考えるならまず使わないですね。

getsとatofがいいでしょう。
scanfの戻り値でもある程度はわかりますが、
多少厳密さに欠けます。
例えば,"123ABC"と入力した場合、エラーとするか、
123が入力されたとするかという違いです。

あとgetsよりもfgetsの方がバッファオーバーフローがおきなくて本当はいいのですが・・・
お礼コメント
lindamarie

お礼率 85% (6/7)

早速アドバイス頂きありがとうございます。初心者だと、どうしてもscanfを最初に習うので、数字=scanfなんて思ってしまいがちなんですが、実際には文字入力というのが入力エラーを抑える働きとなるんですね。初心者だと考え付かない、発想です。勉強になりました。ありがとうございました。
投稿日時 - 2002-03-04 07:46:52
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ