
C言語初心者です。よろしくお願いします。
早速質問なのですが、while文を使ったscanf()関数による数値連続入力で、
◎1----------------------------------------------
#include<stdio.h>
int main(void)
{
double dt,sum=0.0;
while(scanf("%lf",&dt) !=EOF){
sum=sum+dt;
}
printf("合計=%f\n",sum);
return 0;
}
----------------------------------------------
◎1のようにすれば、Ctrl+ZでEOFが返されたら終了とわかるのですが、今度は「0」が入力されたら処理を終了するというプログラムで、
◎2----------------------------------------------
#include<stdio.h>
int main(void)
{
double dt,sum=0.0;
while(scanf("%lf",&dt) !=0.0){
sum=sum+dt;
}
printf("合計=%f\n",sum);
return 0;
}
----------------------------------------------
◎2のようにすると「0」が入力されても、終了せず、以下に示す◎3のように、しないと終了出来ません。
◎3----------------------------------------------
#include<stdio.h>
int main(void)
{
double dt,sum=0.0;
scanf("%lf",&dt);
while(dt!=0.0){
sum=sum+dt;
scanf("%lf",&dt);
}
printf("合計=%f\n",sum);
return 0;
}
----------------------------------------------
◎2で何故、◎1のように出来ず、◎3のようなscanf()を1回目、2回目と判定を入れなければならないか教えて下さい。
No.4ベストアンサー
- 回答日時:
◎1の書き方では、無限ループする場合があります。
scanfは「正しく変換を行った回数、または、入力が尽きた場合にEOF」を返します。
例えば
1.2[Enter]
3.5[Enter]
kkk[Enter]
と入力すると、kkkを入力してEnterを押した瞬間、無限ループします。
scanfは「kkkは%lfに合わないので、0個を変換しました」と0を返し、入力バッファにkkkを残したままにします。
0はEOFとは違うので、そのままループを繰り返します。
入力バッファにはkkkが残ったまま消費されないので、次の回も、次の次の回も、scanfは永久に0を返し続けます。
そして、プログラムを止める事が出来なくなります。
◎2の書き方でも、やはり無限ループする場合があります。
今度は「kkk」とか「@@@」とか「abcdefgh」とか、実数に変換できない物を入力する事で止まります。
しかし「Ctrl+Z」などを打ち込み「入力が尽きた状態」にすると、scanfはEOFを返します。
0はEOFとは違うので、そのままループを繰り返します。
キーボード入力は「入力が尽きた状態」のままなので、次の回も、次の次の回も、scanfは永久にEOFを返し続けます。
そして、プログラムを止める事が出来なくなります。
◎3の書き方でも、やはり無限ループする場合があります。
今度は「0」を入力する事で止まります。
しかし「Ctrl+Z」などを打ち込み「入力が尽きた状態」にすると、scanfはEOFを返します。
この時、dtはscanfによって値を変更されませんから、dtは前回入力したままの「0以外の値」になっています。
dtが0以外では、ループを終了しません。そのままループを繰り返します。
キーボード入力は「入力が尽きた状態」のままなので、次の回も、次の次の回も、scanfは永久にEOFを返し続けます。
そして、プログラムを止める事が出来なくなります。
そう言った訳で、質問者さんの書いた3つのプログラムはどれも「無限ループする、大変に危険なプログラム」です。
下記のようなプログラムが「無限ループしない、安全なプログラム」です。
#include<stdio.h>
int main(void)
{
double dt,sum=0.0;
while(scanf("%lf",&dt) != 1){ // EOFや0を返したらやめる
if (dt == 0.0) // 正しい入力でも、入力が「0」ならやめる
sum=sum+dt;
}
printf("合計=%f\n",sum);
return 0;
}
もちろん、scanfは1個しかありません。
どれも無限ループが発生してしまうとは、まだ勉強が足りないみたいです。。安全なプログラムまで教えていただいて、ありがとうございます。
返り値などその辺りの知識を身に付け、chie65535さんの回答を参考に完璧に理解していこうと思います。
No.5
- 回答日時:
お礼を頂いてからミスに気付きました。
if (dt == 0.0) // 正しい入力でも、入力が「0」ならやめる
は
if (dt == 0.0) break;// 正しい入力でも、入力が「0」ならやめる
のミスです。「ループを抜けるbreak文」が抜けてました。
No.3
- 回答日時:
◎1 は、Ctrl+Z という特殊な操作によって、scanf が異常終了したため返却値に EOF が戻された
から、式が成立してます。
一方、◎2は、0 を入力した場合の scanf は正常に終了したため、&dtに 0 が入り、戻り値には
入力要素の個数が返却されているはずです。
よって、返却値が 0 と一致しないため、終了しません。
返却値が一致しないという考えは理解できました。
戻り値などの関数はこれから学んでいくので、その後、yuu_yuuさんの回答をもう一度見てみれば、完全に理解が出来ると思います。
もっと関数について理解し努力していきます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# C言語: ポインタ 5 2022/06/01 08:33
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語(高校1年の内容)について
-
エクセルワークシート上で、1、...
-
数字を入力して配列に格納する...
-
Excel VBAで、Application.Inpu...
-
c言語 プログラミング
-
scanfが2回使えない・・・?;
-
cin.get(c)について
-
VBAで2進法から10進法に変換さ...
-
C++流入力の妥当性チェック方法
-
if文で困っています。
-
C++ scanfで止まらない
-
CでのCUIプログラミング 指定...
-
ザウルスSL-C860上での{}の入力
-
c言語です
-
C言語について
-
コマンドラインから引数を渡し...
-
プログラミングの問題です 「金...
-
C言語 キューのキーボード操作
-
C言語(while構文)
-
ダメだ・・・分からない。while...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
*をユーザーが入力した数字の数...
-
java初心者です。入力されたの...
-
正負を反転させて出力するプロ...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
プログラミング初心者です。 Py...
-
C言語でgetchar();が上手く使え...
-
Excel VBAで、Application.Inpu...
-
電卓の小数点
-
cout関数を使っているのですが...
-
"scanf"でエンターで改行させな...
-
小数か整数かを判定する方法
-
至急教えてください!プログラ...
-
getchar()について 教えてくだ...
-
scanf が無視されます
-
batプログラム上で文字列を入力...
-
コマンドプロンプトからのEOFの...
-
IF文で戻ることはできますか?...
-
プログラミングの問題です 「金...
おすすめ情報