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

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

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

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

Q&A

解決済

3回答

9944閲覧

無限ループをControl+Dで抜け出したい

Teemro_431265

総合スコア29

C

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

0グッド

0クリップ

投稿2018/10/08 05:19

点数と単位を入力してControl+DでGPAを算出するプログラムを作っているのですが、EOFで抜け出す時にどこにif(tensu==EOF)break;やif((tensu==EOF) || (tani==EOF))break;を書いても一番最後に入力した点数と単位の無限ループになってしまいます。

評定と単位数を入力してください:100 2
100 点の評定は A で、Grade Point (GP) は 4 です。 (2単位)
評定と単位数を入力してください:88 1
88 点の評定は A で、Grade Point (GP) は 4 です。 (1単位)
評定と単位数を入力してください:
ここでControl+Dを入力すると
評定と単位数を入力してください:88 点の評定は A で、Grade Point (GP) は 4 です。 (1単位)
が無限に表示されてしまいます。
何がダメか教えていただきたいです。以前は配列の無限ループを質問させていただいたのですが、その時とは違うので解決策が見つかりませんでした。

c

1#include<stdio.h> 2 3char grade_char(int);//点数を渡して評定を返す 4int char_point(char);//評定を渡してGPAを返す 5 6int main(){ 7 int tensu,tani,tanisu,gp,cnt; 8 double gpa; 9 char hyotei; 10 while(1){ 11 printf("評定と単位数を入力してください:"); 12 scanf("%d %d",&tensu,&tani); 13 if(tensu==EOF)break; 14 hyotei=grade_char(tensu); 15 gp=char_point(hyotei); 16 printf("%d 点の評定は %c で、Grade Point (GP) は %d です。 (%d単位)\n",tensu,hyotei,gp,tani); 17 18 gp+=gp; 19 tanisu+=tani; 20 cnt++; 21 } 22 gpa=(double)(gp*tanisu)/cnt; 23 printf("Grade Point Average(GPA):%f, 単位数:%d\n",gpa,tanisu); 24 return 0; 25} 26 27char grade_char(int score){ 28if(0<=score && score<=34){ 29 return 'F'; 30} 31else if(35<=score && score<=49){ 32 return 'D'; 33} 34else if(50<=score && score<=64){ 35 return 'C'; 36} 37else if(65<=score && score<=79){ 38 return 'B'; 39} 40else { 41 return 'A'; 42} 43} 44 45int char_point(char point){ 46 if(point=='F'){ 47 return 0; 48 } 49 else if(point=='D'){ 50 return 0; 51 } 52 else if(point=='C'){ 53 return 2; 54 } 55 else if(point=='B'){ 56 return 3; 57 } 58 else { 59 return 4; 60 } 61} 62 63

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

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

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

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

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

guest

回答3

0

scanf ではEOFは帰りません。
scanfの戻り値を使えばどうでしょうか(未確認ですが)

投稿2018/10/08 05:24

y_waiwai

総合スコア87719

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

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

Teemro_431265

2018/10/08 08:17

そうなんですね!ちょっとやって見ます
guest

0

ベストアンサー

簡単には、

if (scanf("%d %d",&tensu,&tani) < 2) break;

でしょうか。
ctrl-D 入力後に、 Enterで終了します。

scanf()の戻り値は、読み込んだ数。

if(tensu==EOF)break;

で、判定しているのは、最初の数字が EOF(-1)かどうかとなります。

あと、tanisu と cnt が初期化されていません。その結果、最後の Grade Point Average .... が不適な結果となるようです。 コンパイル時に警告が出ていませんか?

[追記]
Linux/Unixでは、Enterが不要との指摘がありました。
Windowsでは、Enterが必要なようです。
幾つか試したところ、 ctrl-D だけでなく、ctrl-A, X, O, V とかでも次にEnterで、終了。
ctrl-L, Jは、入力待ちのまま、(ctrl-J は当然か)
で、scanf()の戻り値は、 0 (= 入力無し)。

投稿2018/10/08 05:47

編集2018/10/08 11:19
pepperleaf

総合スコア6383

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

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

Teemro_431265

2018/10/08 08:20

Ctrl+Dを入力した時点で終了したいのですが・・ なるほど、そういうことをやっているのですね、ありがとうございます。 いや、エラーは出てこなかったので修正します。
pepperleaf

2018/10/08 08:39

改行(Enterを押す)しないと、scanf()にデータが渡りません。 ctrl-D のみで終了するには、別の方法が必要です。
otn

2018/10/08 10:56

Unix/Linuxだと、先頭でctrl-Dを押すと、その段階で空(≠空行)(=EOF相当)が入力されて、scanfからリターンします。
pepperleaf

2018/10/08 11:03

> Unix/Linuxだと、 Enterが必要なのは、Windowsだけでしたか。 言われてみれば、そんな気も、、最近、メインで使ってないので、失礼しました。Windowsの標準入力がテキストオープンだから? ... 未確認なので、知っている人がいたら、よろしく。
Teemro_431265

2018/10/09 01:47

otnさんpepperleafさんありがとうございます。
guest

0

下記コードで抜けましたd^^

c

1usr~/test/c % ./a.out 21 32 43 5 ←此処でCtl-D 6usr~/test/c % cat ft.c 7#include <stdio.h> 8 9int main() 10{ 11 int a; 12 int r; 13 14 do{ 15 r= scanf("%d", &a); 16 }while( r != EOF ); 17 18 return 0; 19} 20usr~/test/c %

投稿2018/10/08 11:02

cateye

総合スコア6851

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

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

cateye

2018/10/08 13:07

WindowsはEnter必要・・・そうなんだ・・・失礼しましたm(_"_)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問