scanf()を使用して、入力で例えば「5462fa」数字ではなく文字を入力してしまった場合エラー(無限ループ)になりますが、
これをscanf()を使用したまま再入力を促すことが可能でしょうか?よろしくお願いします。
#include <stdio.h>
int main(){
int a , kazu;
for(a=0;a<1;){
printf("値入力せよー>");
scanf ("%d", &kazu);
if( kazu >= 1 && kazu <=100 ){
a = a + 1 ;
}else{
printf("1から100で入力せよ\n");
}
}
printf ("kazu = %d", kazu);
return 0;
}
No.2
- 回答日時:
まず第1に、scanfの返り値がvoidでなくintになってる理由を考えてみましょう。
第2に、scanfの返り値が「想定外」だった時の処理も含めてループの終了条件を考えましょう。
第3に、scanfは「書式に合わない入力があると、スキャンをその時点で中断し、ストリームに入力を残す」と言う特性があるので、ストリームに入力を残さない方法を考えましょう。
なお「正しい値が来るまで繰り返し」と言う処理は
for (;;) {
入力を促す画面出力
入力処理
if文で入力処理が行われたか判定 {
異常入力の警告出力
異常入力を除去するなどのエラー後処理
continue;
}
if文で入力値の範囲の判定 {
範囲外入力の警告出力
continue;
}
if文でその他の再入力の判定1 {
再入力の警告出力1
continue;
}
if文でその他の再入力の判定2 {
再入力の警告出力2
continue;
}
break; /* 正常ならループ脱出 */
}
のように書きます。
こうすれば「再入力の判定」は幾つでも書く事が出来ます。
どの再入力判定にも引っ掛からなかった場合のみ正常に入力されたと考え、ループの最終位置で無条件にbreak文でループを抜けます。
また、質問文にあるような「終了フラグを判定するループ文」だと
・終了フラグを初期化する必要がある
・ループ終了の為の判定を行い、終了フラグを立てる
・ループ終了フラグを判定してループを繰り返すか決める
と言うように、1つの条件に対してif文とfor文の2ヶ所で判定が行われ、二度手間を行っていて処理が無駄です。
こういう場合は
・終了フラグは使わない
・判定式の無い無限ループを使う
・ループ終了と判定したら、そのif文の中で(後処理をしてから)break文を使ってループを終らせる
・ループ再開(やり直し)が必要と判定したら、そのif文の中で(後処理をしてから)continue文を使ってループの最初に戻る
と言う書き方をしましょう。
No.4
- 回答日時:
scanf(3)は、対話入力に不適当な関数です。
想定外の入力に対する挙動が、人間にはとても理解しにくい仕様になっています。
sscanf(3)で書き換えたほうがよいです。
-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
#include <stdio.h>
int
main()
{
char buf[BUFSIZ], moji[BUFSIZ];
int n, kazu;
while (1) {
printf("値入力せよー> ");
fgets(buf, BUFSIZ, stdin);
n = sscanf(buf, "%d%s", &kazu, moji);
if (kazu >= 1 && kazu <= 100 && n == 1) {
break;
}
else {
printf("1から100で入力せよ\n");
}
}
printf("kazu = %d\n", kazu);
return 0;
}
No.5
- 回答日時:
がると申します。
・scanfの類は一切使わない
これに尽きます。
少なくとも、業務ないしそれに近しいところでscanf使ってたら問答無用で雷落とします。
っつか、何ゆえにあんな物騒な関数つかうのでしょう?
# 「課題で使えと書いてある」とか言われると言い返せないのですが。…無論「そんな戯けた問題だす教師」には限りなく疑問です。
C言語にはscanf以外にも「絶対に使ってはいけない」関数が複数あります。
そういった部分について学ばれることを強くお勧めいたします。
ご指導ありがとうございます。
業務では使わないのですか、学校レベルの勉強用関数ってところですかね。
独学で勉強中なので、結構つらいです。また、こちらで質問させていただきます。ありがとうございました
No.6ベストアンサー
- 回答日時:
がるです。
なるほど、独学でなさっているのですね。scanfの経緯は…もう一つ不明ですが。前述したとおり、C言語の関数には「使ってはいけない」ものが色々と転がっております(苦笑
scanfは「意図しない文字列によって容易に暴走する」「バッファにデータを残しっぱなしにすることがある」など、問題児として筆頭に上げられてしまうような関数です。
あと、入力周りでNGなのがgetsという関数。これは、引数のバッファサイズ指定が無いために、容易にバッファオーバフロウを引き起こします。
多少手間でも、fgetsを用いるべきです。
こういった関数の見分け方としては
・異常な入力に対してどのような挙動をしめすか
が第一点(scanfはここでNG)。
もう一つは
・引数で渡したポインタにデータを格納する場合、そのバッファサイズが引数として付随しているか
が第二点目になります(getsはここでNG)。
大変だと思うのですが、頑張ってください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# C言語 3 2022/10/04 15:07
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
数字以外が入力されたらエラー...
-
C言語について
-
C言語 逆ピラミッドの作り方
-
漢字のソートについて
-
プログラミングの問題で、キー...
-
4桁の数字以外を入力したらエラ...
-
入力候補を表示させるには・・・?
-
double型が正常に認識されてい...
-
プログラムC言語の整数の約数に...
-
C言語 While文(ループ)内の...
-
c言語でひらがなのしりとりをで...
-
if文の条件にscanf関数を使うと…?
-
java初心者です。入力されたの...
-
scanf("%s", buf);でスペースを...
-
VBでの日付入力値のフォーマッ...
-
getchar()について 教えてくだ...
-
Linuxで入力待ちなしkeyread関...
-
cout関数を使っているのですが...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
数字以外が入力されたらエラー...
-
プログラミング初心者です。 Py...
-
double型が正常に認識されてい...
-
java初心者です。入力されたの...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
C言語scanf_sで何故か2回入力に...
-
if文の条件にscanf関数を使うと…?
-
プログラミングの問題です 「金...
-
Linuxで入力待ちなしkeyread関...
-
ワードで文字を入力する時の変...
-
cout関数を使っているのですが...
-
batプログラム上で文字列を入力...
-
Userformの入力順序をタブオー...
-
scanf が無視されます
-
C言語 逆ピラミッドの作り方
-
gets_sがうまく動かない
-
Excel VBAで、Application.Inpu...
おすすめ情報