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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
EDITコントロールで入力できる...
-
if文の条件にscanf関数を使うと…?
-
"scanf"でエンターで改行させな...
-
Userformの入力順序をタブオー...
-
漢字のソートについて
-
VisualStudio2019のコードアナ...
-
入力候補を表示させるには・・・?
-
キーボード入力によるループの終了
-
OpenCV webカメラ同時出力について
-
scanfでの可変引数
-
プログラミングの問題です 「金...
-
scanf が無視されます
-
Linuxで入力待ちなしkeyread関...
-
コマンドプロンプトからのEOFの...
-
数字以外が入力されたらエラー...
-
C言語(構造体)
-
cout関数を使っているのですが...
-
2進数の1の数を数える問題
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
*をユーザーが入力した数字の数...
-
数字以外が入力されたらエラー...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
java初心者です。入力されたの...
-
Excel VBAで、Application.Inpu...
-
ワードで文字を入力する時の変...
-
WindowsでEOF
-
batプログラム上で文字列を入力...
-
getchar()について 教えてくだ...
-
cout関数を使っているのですが...
-
コマンドプロンプトからのEOFの...
-
"scanf"でエンターで改行させな...
-
VisualStudio2019のコードアナ...
-
至急教えてください!プログラ...
-
C言語scanf_sで何故か2回入力に...
-
scanf が無視されます
-
EDITコントロールで入力できる...
おすすめ情報