質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

840閲覧

c言語 whileを使った文について教えて下さい。 初心者で初歩的な質問かもしれませんがよろしくお願いします。

EEE

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/05/24 15:29

C言語について質問です。初心者なので、初歩的な質問ですがよろしくお願いいたします。
点数(point)を入力すると最高得点(max)と最低点(min)を表示するプログラムを作っています。
ifでもできるのですがwhileを使いたいです。
内容としてはwhile(1)でctrl+cするまで終わらないプログラムで、入力した値とmax,minと比較して条件にあったら代入するといったプログラムを書いたつもりです。
しかし、結果は画像の右下の通りで、1回目はうまくいってるのですが、2回目から『前の点数→点数を入力→結果』といって順番で表示されてしまいます。一回めのように結果を表示し、改行で点数を入力といった表示にしたいのです。
イメージ説明

#include <stdio.h> int main(void) { int max = 0, min = 100; while(1) { int point; printf("点数を入力 >>"); scanf("%d\n", &point); if(point >= 0) { if(point>max){max = point;} if(point<min){min = point;} } printf("最高点%d:最低点%d\n", max, min); } return(0); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

この例に関してだけいうと、

scanf("%d\n", &point);

scanf("%d", &point);

に変えたら動きますよね。
"%d" は、空白や改行文字は読み飛ばしてくれるので。

こういう練習問題と解いている段階(かなりの初心者)でしたら、それでいいんでは?
他の方が助言しているとおりscanfなどの返り値チェックは本当は必要ですけども。

投稿2018/05/25 07:09

a_saitoh

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

EEE

2018/05/25 13:50

ありがとうございます \nなくしたら動きました。
otn

2018/05/25 14:13

誤って数字以外の文字を入力すると困った事態に。
a_saitoh

2018/05/27 06:16

whileの使い方を学ぶ自主課題ですよね。課程の進度がI/Oエラーの正しい処理にはほどとおいので問題ないでしょう。 EOFを入れても困ったことになります。
guest

0

scanf を含む入出力の動作には注意が必要です。
プログラムの動作を1ステップずつ追ってみましょう。

c

1printf("点数を入力 >>"); 2scanf("%d\n", &point); 3// 1. scanf で入力を待機 4// → ユーザが "20 -1\n" と入力 5// 2. stdin のバッファに "20 -1\n" が蓄えられる 6// 3. stdin のバッファから "20 " までを読み取る 7// ※scanf は空白を改行と同一視します 8// 4. point に 20 が代入される 9if(point >= 0) { /* ... ここの処理は狙い通り行われる */ } 10printf("最高点%d:最低点%d\n", max, min); /* ここも OK */ 11 12/* while ループの最初に戻る */ 13 14printf("点数を入力 >>"); 15scanf("%d\n", &point); 16// 5. scanf で入力を待機 17// → ユーザが "60 -1\n" と入力 18// 6. stdin のバッファに "60 -1\n" が追加され、"-1\n60 -1\n" となる 19// 7. stdin のバッファから "-1\n" までを読み取る 20// 8. point に -1 が代入される 21if(point >= 0) { /* 通過しない! */ } 22printf("最高点%d:最低点%d\n", max, min); /* if 文を飛ばすので前と同じ値が出力される */ 23 24/* while ループの最初に戻る */ 25 26printf("点数を入力 >>"); 27scanf("%d\n", &point); 28// ⑦ stdin のバッファに "60 -1\n" があるので、scanf はそこから読み取る(入力を待機しない) 29// ⑧ point に 60 が代入される 30if(point >= 0) { /* ... 今回は通過する */ } 31printf("最高点%d:最低点%d\n", max, min); /* => 60:20 */ 32// 以下略

ポイントは、scanf は空白を改行と同一視するということと、stdin のバッファです。
そもそも入力に -1 を付けているのは「そうしないとうまくプロンプトが出ないから」みたいな理由だと思いますが、そういう「めんどくさいし、とりあえず狙い通り動いてるからいいや」という所にこそバグがあるものです。
まあ、今回の場合はそもそも狙い通り動いていなかったわけですけど……。

投稿2018/05/24 16:32

pute

総合スコア134

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

EEE

2018/05/25 13:52

ありがとうございます。 とてもわかりやすく、助かります。 今後の勉強にもなりました。 また機会があればよろしくお願いします。
EEE

2018/05/25 13:53

確かに-1はよくわからずつけていたので今後はちゃんと気をつけて、プログラムを作っていこうと思います。
guest

0

C

1#include <stdio.h> 2 3int main(void) 4{ 5 int max = 0, min = 100; 6 char line[100]; 7 8 while(1) 9 { 10 int point; 11 printf("点数を入力 >>"); 12 fgets(line, sizeof line, stdin); 13 sscanf(line, "%d\n", &point); 14 15 if(point >= 0) 16 { 17 if(point>max){max = point;} 18 if(point<min){min = point;} 19 } 20 printf("最高点%d:最低点%d\n", max, min); 21 } 22 23 return(0); 24}

scanfは使い方が難しいので、fgets + sscanfを使いましょう。

投稿2018/05/24 15:58

編集2018/05/24 15:59
otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/05/24 22:31

今回は単純なので良いですが、一般的にはscanf/sscanf/fscanfなどでは返り値をチェックする必要があります。
EEE

2018/05/25 13:51

ありがとうございます。 一応完成しましたので、 今後の参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問