こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

fileのデータを読みこむ

あるファイルのデータの、平均と標準偏差を求める課題をやっているのですが、途中でいきずまってしまいました。。

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

void average_stddev(double *data, int count);

int main(void){

/*
int i, count;
double *data;

data = (double *)malloc(sizeof(double));

printf("input count: ");scanf("%d", &count);
printf("input data: \n");

for(i=0 ; i<count ; i++){
printf("data[%d] = ", i+1);scanf("%lf", data+i);
}

average_stddev(data, count);

free(data);


*/


FILE *fp;
int count;
double *data;

count=0;

if((fp = fopen("data_for_1.33.txt", "r")) == NULL){
printf("\a can't open this file.\n");
}
else{
while(fscanf(fp, "lf", data) == 1){
printf("%.16f\n", data);


}
average_stddev(data, count);
}




return 0;
}


void average_stddev(double *data, int count)
{
double a, a_square, mean, var, std_dev;
int i;
a = a_square = 0.0;
for (i=0; i<count; i++){
a += data[i];
a_square += data[i]*data[i];
}

mean = var = std_dev = 0.0;
if ( count > 0 ){
mean = a / (double)count;
var = fabs(a_square / (double)count - mean * mean);
std_dev = sqrt(var);
}
printf("mean = %.16f std_dev = %.16f\n", mean, std_dev);
}

コメントの中は、普通のscanfでやったら…ということを考えてたので気にしないでください(^_^;)

分からないのは、fopenからで、whileの中でcountやdataの総和はインクリメントしていれば出ると思うのですが、
関数と混ざってしまうと良くわかりません(>_<)

課題はこの関数を使う(修正可)形で出さないといけないので困っています。
よろしくお願いします!

投稿日時 - 2007-04-21 12:27:38

QNo.2938121

すぐに回答ほしいです

質問者が選んだベストアンサー

★malloc、free について
int main( void )
{
 double *data;
 
 if ( (data = (double*)malloc(sizeof(double) * MAX_COUNT)) != NULL ){
  /*
  ここに[データ読み込み]~[平均と標準偏差の表示]を記述
  */
  free( data );
 }
 return( 0 );
}

解説:
・最初に、全データが格納できるだけの数で malloc 関数でメモリを確保します。→1000個分など。
 その後、最大 1000 個分のデータを for 文内で fscanf より取得します。
・データの取得する fscanf の指定は『fscanf( "%lf", &data[i] );』の方が分かりやすい気がします。
 もちろん、ポインタですので『data + i』でも構いませんがカッコくらいは付けましょう。
 int max;
 
 for ( max = 0 ; max < MAX_COUNT ; max++ ){
  if ( fscanf(fp,"%lf",&data[max]) != 1 ){
   break;
  }
  printf( "%.16f\n", data[max] );
 }
 average_stddev( data, max ); ←ここで平均と標準偏差
・上記を参考に頑張って下さい。

投稿日時 - 2007-04-21 15:45:38

お礼

ありがとうございます!出来ました(*^_^*)

MAX_COUNTとかにしてbreak;でやれば簡単ですね!
とても参考になりました!

投稿日時 - 2007-04-21 17:02:27

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

まず、fscanfの第2引数は"%lf"にしないと動かない気がします。

そして、そのfscanfで何度も同じポインタdataにデータを読み込んでも、
最後に読み込んだ1個だけしか残りません。
十分大きな配列を用意して、順に格納しましょう。
(もしくはmalloc, callocを使う)

投稿日時 - 2007-04-21 12:42:05

補足

%がなかったですねっ(>_<)
すみませんっ!

No.1の方にも言われたのでmallocも使いました!
ですが、関数と合わせると良くわからなくなってしまいます。

投稿日時 - 2007-04-21 12:50:32

ANo.1

とりあえず、data の指す場所に double いっこ分の領域しか確保していないのですが。
しかもコメントアウトされてしまっているし。

投稿日時 - 2007-04-21 12:34:07

補足

あ、すみません…
忘れてました(^_^;)

投稿日時 - 2007-04-21 12:38:11