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

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

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

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

Q&A

解決済

4回答

2789閲覧

標準出力でなにも表示されない

grape_ll

総合スコア83

C

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

0グッド

0クリップ

投稿2020/05/21 13:09

編集2020/05/23 08:09

質問内容

コンパイル時にエラーは出ないのですが出力が何も出ないです。

問題

肥満度を知るのに BMI (Body Mass Index) がよく使われる。BMI は、 体重 w Kg, 身長 h m に対してつぎの式で定義される値をいう。

w / h^2

何人かの人について、名前・身長・体重が与えられているとき、 その中で一番 BMI の小さい人を見つけるプログラムを作れ。
入力は、何行かにわたる。各行には、名前(ローマ字姓)、身長(単位 cm)、体重(単位 Kg)が この順に1個以上の空白で区切られて書かれている。標準入力がキーボードから行われるときは、入力の最後に C-d を入力する。出力は、 BMI が最も小さかった人の名前を1行として書き出す。

入力例1

taro 183.3 65.5

syo 177.9 63.8

taisuke 173.1 61.1

ryo 175.4 60.0

出力例1

taro

入力例2

hanako 161.3 47.5

tomo 159.8 45.3

moe 164.2 43.2

出力例2

moe

コード

C

1#include<stdio.h> 2#include<string.h> 3int main(void){ 4 char name[1000][50]; 5 double height[1000],weight[1000]; 6 double BMI[1000]; 7 double ansBMI=10000; 8 char ans[1000]; 9 int i=0,j=0; 10 while(scanf("%s",name[i])!=EOF){ 11 scanf("%lf %lf",&height[i],&weight[i]); 12 BMI[i]=weight[i]/(height[i]*height[i]); 13 if(BMI[i]<ansBMI){ 14 strcpy(ans,name[i]); 15 } 16 i++; 17 } 18 printf("%s\n",ans); 19 return 0; 20}

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

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

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

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

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

thkana

2020/05/21 13:30

> うまくいかなかった ではなく、何が起こったのかをちゃんと書きましょう。 もちろん、どうなったら「うまくいった」ことになるのかの情報も必要です。 なお、「エラーが出る」のはC言語として成り立っていない、話にもならないということであって、「エラーが出ない」というのは当たり前のことでしかありません。エラーが出なかったら、次は警告も出ないようにしましょう。そのうえでやっと「異常な動きをする」対応に入れます。
grape_ll

2020/05/21 13:40

ご指摘ありがとうございます。具体的に書かせていただきました。
PingHermit

2020/05/21 22:52 編集

まずは、動作環境を書きましょう。 PS C:\Users\rokok\proc\01> ./try を見ると、windows の power shell の様に見えます。 行頭で ctrl+d で EOF になるのは、unix系OSです。 windows は 行頭で ctrl+z です。 特に、windows では、EOF が出てきにくい関数とかもあるので要注意です。
grape_ll

2020/05/22 01:38

パソコンのことに疎くて,作業環境なども友人に構築していただいたので細かいことが分からず申し訳ございませんが、貼り付けさせていただいたものはwindowsでvscodeと呼ばれるもので実行したものです。ですが、提出するところではここと環境が違うようでして、他の問題では while(scanf("%d",&a)!=EOF) のようにすれば正解できていました。 足りない情報が多く申し訳ございません。
grape_ll

2020/05/22 01:57

入力がだめなのはおそらくは作業環境によるものでした。提出する場所でためしに実行してみたらきちんと終わったかもしれません。出力がなにもないのでうまくいっていないのかもしれませんが。
grape_ll

2020/05/23 07:49

以下のように書いてみたのですが、出力はなにもないままでした。またwhileのすぐ下にprintf("lll\n");とてきとうに出力を書いても出てこなかったのでそもそもwhileの中に一回も入れていないということになると思うのですが、どこが原因になりそうか教えていただけると助かります。よろしくお願いいたします。 #include<stdio.h> #include<string.h> int main(void){ char name[1000][50]; double height[1000],weight[1000]; double BMI[1000]; double ansBMI=10000; char ans[1000]; int i=0,j=0; while(scanf("%s",name[i])!=EOF){ scanf("%lf %lf",height[i],weight[i]); BMI[i]=weight[i]/(height[i]*height[i]); if(BMI[i]<ansBMI){ strcpy(ans,name[i]); } i++; } printf("%s\n",ans); return 0; }
guest

回答4

0

ベストアンサー

プログラムに正しいところがほとんどないです。

コードはエラーはでませんでした。

実行したらエラーになるはずですが、コンパイルのみで実行してない?

間違っている点:
double値をscanfで読み込むなら%dじゃなくて%lf
・そのとき引数には、変数値じゃなくて変数アドレスを渡す
・文字列の末尾は"\0"じゃなくて'\0'
nameがどういう変数だったか途中で忘れてしまっている
height[i]の2乗はheight[i]*2じゃなくてheight[i]*height[i]
X/Y*ZX/(Y*Z)は別物
・まだあるかも

改善点:
・身長その他に配列は不要。単一の変数でいい
・文字列のコピーは専用の関数strcpyがある
scanfの返り値は必ず正しくチェックする

投稿2020/05/21 14:42

otn

総合スコア84489

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

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

grape_ll

2020/05/22 01:42

確かに細かい部分が間違っていました。 修正させていただこうと思います。ご指摘ありがとうございます。 またstrcpyについて、初めて知ったので試してみようと思います。
grape_ll

2020/05/23 07:49

以下のように書いてみたのですが、出力はなにもないままでした。またwhileのすぐ下にprintf("lll\n");とてきとうに出力を書いても出てこなかったのでそもそもwhileの中に一回も入れていないということになると思うのですが、どこが原因になりそうか教えていただけると助かります。よろしくお願いいたします。 #include<stdio.h> #include<string.h> int main(void){ char name[1000][50]; double height[1000],weight[1000]; double BMI[1000]; double ansBMI=10000; char ans[1000]; int i=0,j=0; while(scanf("%s",name[i])!=EOF){ scanf("%lf %lf",height[i],weight[i]); BMI[i]=weight[i]/(height[i]*height[i]); if(BMI[i]<ansBMI){ strcpy(ans,name[i]); } i++; } printf("%s\n",ans); return 0; }
otn

2020/05/23 07:57

実行するとセグメンテーション違反などのエラーになるはずですが、ならないとしたら実行の仕方が悪いのでしょう。
grape_ll

2020/05/23 08:03

セグメンテーションエラーを今初めて知り、少し調べてきたのですが、どの部分がそのようなエラーになるのか見つけることが出来ないです。よろしければエラーの原因を教えていただけませんか。
grape_ll

2020/05/23 08:12

このようにしたら無事出来ました ありがとうございました。 #include<stdio.h> #include<string.h> int main(void){ char name[1000][50]; double height[1000],weight[1000]; double BMI[1000]; double ansBMI=10000; char ans[1000]; int i=0; while(scanf("%s",name[i])!=EOF){ //printf("6\n"); scanf("%lf %lf",&height[i],&weight[i]); BMI[i]=weight[i]/(height[i]*height[i]); //printf("%f\n",BMI[i]); if(BMI[i]<ansBMI){ strcpy(ans,name[i]); ansBMI=BMI[i]; // printf("1\n"); } i++; } printf("%s\n",ans); return 0; }
otn

2020/05/23 08:22

それで多分直っていると思います。 セグメンテーション違反は、回答に書いた、 > そのとき引数には、変数値じゃなくて変数アドレスを渡す の部分です。
guest

0

scanf("%lf %lf", &height[i], &weight[i]);
にしましょう。
他は見てません。

投稿2020/05/23 08:04

PingHermit

総合スコア478

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

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

grape_ll

2020/05/23 08:09

原因はこれみたいでした。 凄く初歩的なところでした。反省します。 ありがとうございました。
thkana

2020/05/23 08:16

それが原因だとすると、 > またwhileのすぐ下にprintf("lll\n");とてきとうに出力を書いても出てこなかった と矛盾します。
PingHermit

2020/05/23 10:43 編集

scanf の 不正アドレスアクセスで、そのまま止まったからではないですか?
PingHermit

2020/05/23 10:44 編集

それか、スタック使い過ぎで、 領域超過のアクセスエラーで落ちたか。
thkana

2020/05/23 11:10

> whileのすぐ下にprintf("lll\n"); ですよ。止まるとすれば scanf("%lf %lf",height[i],weight[i]); でデータを格納するとき。lllが表示されないというストーリーになりません。
PingHermit

2020/05/23 11:19 編集

関数呼び出しは、スタック使うので、 printf で使うスタックがアクセスエラーを起こしたのでは? という意味。 最初もっとどでかくスタック取ってなかったでしたっけ?
PingHermit

2020/05/23 11:23 編集

double ansBMI=10000; int i=0; スタックの使いすぎであれば。ここでもアクセスエラー起きます。そういえば。 元の大きさに戻してみれば?
thkana

2020/05/23 11:35

前提が抜けていてごめんなさい。 PingHermitさんのところにはありませんが、otnさんと私の回答についている2020/05/23 16:49 の質問者さんの返信をベースにして考えています。(PintHermitさんの回答した時点でもそれが質問のソースになっていたかとは思いますが)
PingHermit

2020/05/23 12:27 編集

そうか。 そこだったら、 82[kb]くらいだからスタック使い過ぎって事は無いか。
PingHermit

2020/05/23 12:16 編集

あ、thkanaさんのコメントだったか。質問者本人のコメントと勘違いしてた。 他の質問だったと思うけど、 printf 入れたのは、まだスタックたくさん積んでた時にもあったので、 その時じゃないかと思いますが・・・ while の下にprintf 入れても表示されないとあったので だから、領域確保を、外部変数にして、もっと減らしなさいってコメントしてます。 本人に聞いてみないとわかりませんが。 まあ、直ったみたいなんでもうどちらでもいいです。
thkana

2020/05/23 12:27

> 直ったみたいなんでもうどちらでもいいです。 どうでしょうね。それを「直った」とするのは地雷を埋める行為になりかねないと私は思いますが。 #仕事上のバグレポートだったら絶対許されない。
PingHermit

2020/05/23 12:52 編集

私は発注側なんで、完璧に治ればそれでいいです。 損失は、賠償してくれればいいです。 レポートは体裁と、請負者のレベルを図るくらいにしか思ってません。
guest

0

入力が全て数字だったらいける

ということなので、今の課題はちょっと棚上げして、数字入力で「いける」プログラムを示して下さい。入力して、その数字を表示することを繰り返してCtrl-Dで抜ける、抜けたときにメッセージを表示する、というもので十分でしょう。
次に、そのプログラムをちょっとだけ変えて文字列を受け付けるようにしてみて(これも、入力した文字列を表示を繰り返してCtrl-Dで抜けるだけ)、「いける」かどうかみてみましょう。

「うまくいかなかった」原因を絞り込みたいので。

投稿2020/05/21 14:11

thkana

総合スコア7629

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

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

grape_ll

2020/05/22 01:41

前の問題に使って正解がでたコードは以下のようになります。 よろしくお願いします。 #include<stdio.h> int main (void){ int a; int i; int sum=0,count=0; double Ave=0; while(1){ if((scanf("%d",&a))==EOF) break; sum+=a; count++; } if(count==0){ printf("No data\n"); return 0; } Ave=sum/count; printf("%d %d %.3f\n",count,sum,Ave); return 0; }
grape_ll

2020/05/22 02:00

急に質問内容が変わってしまって申し訳ないのですが,作業環境の違いによるものかもしれないという結論に至りました。そこで、次の問題は出力で何も出てこないということになりました。質問の箇所に載せたコードを少し修正させていただいたので,お手を煩わせて申し訳ないのですが、ご確認いただければ幸いです。よろしくお願いします。
thkana

2020/05/22 12:12

> 数字入力で「いける」プログラムを示して下さい。 というのはそういう「作業環境の違い」であったりするようなことを識別することも出来るのでそういったのですが。それを確認はしなかったのですね? きっと、 > 入力が全て数字だったらいけるのですが,文字列が入ってくると分からないです。 というのは間違いで、入力が全て数字でもダメであろうことを私は予想していて、確認して欲しかったのですが。 まぁそれはそれとして、追記修正依頼に書いた > そのうえでやっと「異常な動きをする」対応に入れます。 に入ったということになるかと思います。 関数の中で宣言する変数(ローカル変数)は、通常(特別な属性をつけないと)、メモリの「スタック領域」にとられます。関数のなかでちょこっと使うのだからまぁ大した量ではないだろう...という想定です。 最近のシステムであれば、2MB(2,000,000バイト)ぐらい。あちこちでシェアするので実用上はもっと少ないです。 さて、あなたが今回のプログラムでmain関数のなかで宣言しようとしている char name[1000][10100]; はどのくらいの領域になるか、ちょっと考えてみて下さい。
grape_ll

2020/05/22 12:37

そういった意味があったのですね。気づくことが出来なくてすいませんでした。 領域は凄く簡単に見積もっても10^7を超えるのでまずいようですね。今後は気を付けたいと思います。
grape_ll

2020/05/23 07:49

以下のように書いてみたのですが、出力はなにもないままでした。またwhileのすぐ下にprintf("lll\n");とてきとうに出力を書いても出てこなかったのでそもそもwhileの中に一回も入れていないということになると思うのですが、どこが原因になりそうか教えていただけると助かります。よろしくお願いいたします。 #include<stdio.h> #include<string.h> int main(void){ char name[1000][50]; double height[1000],weight[1000]; double BMI[1000]; double ansBMI=10000; char ans[1000]; int i=0,j=0; while(scanf("%s",name[i])!=EOF){ scanf("%lf %lf",height[i],weight[i]); BMI[i]=weight[i]/(height[i]*height[i]); if(BMI[i]<ansBMI){ strcpy(ans,name[i]); } i++; } printf("%s\n",ans); return 0; }
thkana

2020/05/23 08:14

そのプログラムは修正した質問とは同じもの? 違うもの? あちこちに散らばってると何が「本物」かわからなくなるから、あまり散らさないで欲しいのだけれど。 で、 while(scanf("%s",name[i])!=EOF){ printf("lll\n"); と変更してlllが表示されない、ということですか。"lll"ではなく"lll\n"ですね? (なぜそれを気にするかは、'printf バッファリング'あたりで検索してみて下さい) だとすると... ちゃんとコンパイルして、新しく出来たプログラムを走らせていますか? 真面目に、なにかの加減で勘違いして変更する前のプログラムを走らせて「おかしい...」と悩むことってあるんですよ。while()の前になにかprintfで表示してみて、確実に区別がつくようにしてみたらどうなるでしょう。 直接関係ないですが、 char ans[1000]="!!!NOONE"; とでもしておくと、何かの間違いでいきなり最後のprintfに飛んだときにも何かしら表示されるので、状況の把握に役に立つことがあるかも知れません。
guest

0

そもそものはなしになりますが、scanfなどという危険な関数は実務では禁忌です。
これから、なんらかの業務としてC言語を扱うのであれば、この関数は忘れるようにしましょう

投稿2020/05/21 13:14

y_waiwai

総合スコア87747

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

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

grape_ll

2020/05/21 13:29

いままでscanfのやり方しかやってきていなかったのですが、これを使わないとするとどのようなやりかたで取ってくるのがよいのですか? また,scanfを使わないほうがいいということは頭に入れておこうと思うのですが,ひとまずscanfを使った場合のやり方も教えていただけると幸いです。 よろしくお願いします。
y_waiwai

2020/05/21 13:33

scanfを使う限りは、Ctrl+DあるいはCtrl+Cを使うかしかテはないんじゃないでしょうか
grape_ll

2020/05/21 13:44

Ctrl+Dなどを使うことはすでに知っているのですが,今回の問題点はこのコードにおいて入力がきちんと入っていないことだと思っています。ぜひ、この問題点に関する改善点を教えていただければと思います。よろしくお願いします。
y_waiwai

2020/05/21 13:45

それに対する逃げ道はないです。 それも、scanf関数の危険性の一つですね
grape_ll

2020/05/22 01:39

そうなんですね。 新しい知識が増えました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問