dポイントプレゼントキャンペーン実施中!

EXELEファイルから値を読みこんで、各自のBMIと全体の身長・体重の平均値を求めるプログラムを作成したいんですが…C言語で…。途中までで混乱してしまい、あっているかも分からないのでお願いしたいです。よろしくお願いします。ヒントだけでもありがたいです。

下がそのファイルです。
heightweight
170.752.9
166.871.3
171.458.5
173.476.7
176.180.2
18489.1
17964.7
177.278.5
177.780.7
173.864
167.760.3
181.672.3
162.453
177.469.6
17876.4
17477.2
185.486
17268.5
172.760
166.562
171.369.6
17779
174.882.6
167.569.2
176.880.1
181.576
177.376.4
169.451.8
165.273.2
175.372.3
181.572.4
171.568.8
17673.2
18699.8
167.365.5
176.178
183.377.2
177.559.5
180.362
171.274.7
17587.2
17680
171.850.6

平均身長の値を出すプログラムは出ているので…これもあわせてBMIと平均体重出してくれるとうれしいです。

/* basic claculation */
#include <stdio.h>
#include <math.h>

int main(void)
{
int i, ii;
int ntotal;
double sum_height;
double weight[50], height[50];
double mean_height;
char w[6],h[6];
FILE *fp;

/* initial setting */
/* ntotal: total word number */
/* sum : total character number */
ntotal = 0;
sum_height = 0;

/* file open */
/* my data file is weight-height.data */
/* which is in my root directory */
fp = fopen("./weight-height.data","r");
/* skip character reading. */
fscanf(fp,"%s,%s",w,h);

/* ntotal: total number */
/* sum : total value */
for (i=0;i<=47;i++)
{
if (feof(fp)) break;
fscanf(fp,"%lf,%lf",&weight[i],&height[i]);
printf(" weight = %lf height = %lf \n",weight[i],height[i]);
sum_height = sum_height + height[i];

}
fclose(fp);
ntotal = i;
printf(" 全人数 = %d \n",ntotal);

mean_height = sum_height /ntotal;

printf(", 平均身長 = %lf \n",mean_height);
return(0);
}

A 回答 (2件)

どうぞ。



#include <stdio.h>
#include <string.h>
#include <math.h>

int main()
{
double totalHeight = 0.0;
double totalWeight = 0.0;
int count = 0;
char buffer[ 64 ];

FILE* stream = fopen( "./weight-height.data", "r" );
if( !stream )
return -1;

/*先頭はコメント行がくるものという前提で*/
if( !fgets( buffer, sizeof( buffer ), stream ) )
{
fclose( stream );
return -1;
}

while( fgets( buffer, sizeof( buffer ), stream ) )
{
char* token = NULL;

/*身長(多分cm単位っぽいよね?)を取得する*/
/*セパレータはタブか,(カンマ)ということで*/
token = strtok( buffer, "\t," );
if( !token )
{
printf( "format invalid\n" );
break;
}
double height = atof( token );

/*体重(kg)を取得する*/
token = strtok( NULL, "\t," );
if( !token )
{
printf( "format invalid\n" );
break;
}
double weight = atof( token );

/*それぞれの身長、体重、BMIを出力する*/
printf( "height=%.1f weight=%.1f BMI=%.1f\n",
height,
weight,
weight / pow( height / 100, 2.0 ) );

/*身長と体重の総和を計算する*/
totalHeight += height;
totalWeight += weight;

++count;
}

fclose( stream );

printf( "----------------------------------\n" );

/*平均身長と平均体重を出力する*/
printf( "height(ave.)=%.1f\nweight(ave.)=%.1f\n",
totalHeight / count,
totalWeight / count );

return 0;
}
    • good
    • 0

○コメント、英語で書いてますが、自分その内容を理解できてますか?


コメントというのは、後で混乱しないように書いておく覚えがきです。
見てすぐにわからない程度の英語力なら、素直に母国語で書いたらどうです?

○入力はデータがタブで区切られているのでしょうか?(タブだとここに投稿するときに消されてしまいます)
それともカンマでしょうか?
プログラム中では、fscanfでカンマ区切りのデータとして処理しているようですが。

> if (feof(fp)) break;

fscanfで今回のように%f,%s等で文字列を読むと、読み込んだ箇所のすぐ後にある改行文字や空白文字は、まだ読み込まれない状態で残っています。
最後の行を読み終えると、その後の改行は残っているので、ファイルの最後では無いのでfeofは偽です。
しかし、fscanfではもうデータを取り出せません。一応、データが読み込めなかった場合は、対象の変数の値は変わらないことになっていますが、今回はそもそも初期化していないので、何が入っているかわかりません。
しかも、その「何が入っているかわからない」 値をsum_heightに加えてしまいます。
総人数も、「最後の行の後」の分も加わっています。

あと、breakで止まったときのループカウンタiの値を人数に使おうとしてますが、これも混乱のもとだと思います。

終了はfscanfの戻り値で判定する。
fscanfで成功したら人数を増やす、というプログラムにすると、もうすこしすっきりすると思います。

---
あとは
> printf(" weight = %lf height = %lf \n",weight[i],height[i]);
scanfとprintfで使われる書式はよく似てますが、同じではありません。
printfではdoubleには%fです。lは不要です。
もともとはどうなるか規定が無く、たまたま動作していた状態でした。最近では規格の方が折れて l を付けても、付いて無いもの同じに処理する、となりました。

> for (i=0;i<=47;i++)
なんで47?

> mean_height = sum_height /ntotal
人数が0のときのエラー処理を入れてもよいでしょう
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!