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

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

ただいまの
回答率

88.77%

ファイル読み込みから配列にいれてそれを順番に画面表示したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 442

ren_ren_ren

score 1

前提・実現したいこと

"info.txt"というファイルの中に、名前、出身校、時間、距離が人数分書かれています。
それを読み込んで画面に表示し、平均、標準偏差、相関係数等を求めたいです。

発生している問題・エラーメッセージ

共分散:0.00e+000[-]    
a0=-1.#Je+000
a1=-1.#Je+000
距離及び所要時間の平均値
距離:0.00e+000 [km]
時間:0.00e+000 [h]
距離及び所要時間の標準偏差
距離:0.00e+000 [km]
時間:0.00e+000 [h]
相関係数:-1.#Je+000[-]

該当のソースコード

include <stdio.h>

include <math.h>

include <string.h>

include <stdlib.h>

typedef struct{
char name[100]; //名前
char school[100];  //出身校
double distance;  //距離
double time;  //所要時間
}Member;

//一次近似式の係数及び相関係数を計算するプログラム
void lsm(double x[], double y[], int N, double *a0, double *a1)
{
int i;
double A00 = 0, A01 = 0, A02 = 0, A11 = 0, A12 = 0;

for (i = 0; i < N; i++) {
A00 += 1.0;
A01 += x[i];
A02 += y[i];
A11 += x[i] * x[i];
A12 += x[i] * y[i];
}

*a0 = (A00 * A12 - A01 * A02) / (A00 * A11 - A01 * A01);
*a1 = (A02 * A11 - A01 * A12) / (A00 * A11 - A01 * A01);

}

int main(void) {
Member data[20];
int number, i;  //数を調べるための変数
double k; //相関係数
double sum_distance, sum_time;   //距離及び時間のそれぞれの合計
double ave_distance, ave_time;   //距離及び時間の平均
double stdev_distance, stdev_time;   //距離及び時間の標準偏差
double covariance_distance_time;   //距離及び時間の共分散
char filename1[256];//filename2[256];
char r_name[100];  //読み込む名前
char r_school[100];  //読み込む出身校
float f1, f2;
char buf[1000], buf1[500],buf2[500];
FILE *fp; // FILE型構造体

//テキストファイルから情報を読み込む。ファイルがない場合は失敗
/*fp = fopen(fname, "r");
if(fp == NULL) {
printf("Error");
}*/

printf("ファイル名を入力してください\n");
fflush(stdout);
while(1) {
fgets(filename1, sizeof filename1, stdin);
filename1[strlen(filename1) - 1] = '\0';

if((fp = fopen(filename1, "r")) == NULL) {
perror("file is not open!");
}
else if((fp = fopen(filename1, "r")) != NULL) {
break;
}
//情報を読み取るプログラム
number = 0;
while(fgets(buf, 1000, fp) != NULL) {
sscanf(buf, "%s %s %f %f", r_name, r_school, &f1, &f2) ;
strcpy(data[number].name, r_name);
strcpy(data[number].school, r_school);
data[number].distance = f1;
data[number].time = f2;
number++;
}
fclose(fp); // ファイルを閉じる
}
//全員の情報を画面に表示するプログラム
for(i = 0; i < number; i++) {

printf("名前:%s\t",data[i].name);
printf("出身校:%s\t",data[i].school);
printf("距離:%3.2e[km]\t",data[i].distance);
printf("所要時間:%3.2e[h]\n", data[i].time);
}
printf("\n");

//距離と時間の平均値を計算するプログラム
sum_distance = 0;
sum_time = 0;
ave_distance = 0;
ave_time = 0;

for(i = 0; i < number; i++) {
sum_distance += data[i].distance;
sum_time += data[i].time;
if(i == number - 1) {
ave_distance = sum_distance / (double)number;
ave_time = sum_time / (double)number;
}
}

//距離と時間の標準偏差及び共分散を計算するプログラム
stdev_distance = 0;
stdev_time = 0;
covariance_distance_time = 0;

for(i = 0; i < number; i++) {
stdev_time += pow((data[i].time - ave_time), 2.0);
//(data[i].time - ave_time) * (data[i].time - ave_time);
stdev_distance += (data[i].distance - ave_distance) * (data[i].distance - ave_distance);
covariance_distance_time += (data[i].distance - ave_distance) * (data[i].time - ave_time) / (double)number;

if(i == number - 1) {
stdev_distance = sqrt(stdev_distance / (double)number);
stdev_time = sqrt(stdev_time / (double)number);
}
}
//printf("距離の標準偏差:%3.2e[km]\t", stdev_distance);
//printf("時間の標準偏差:%3.2e[h]\n", stdev_time);
printf("共分散:%3.2e[-]\t", covariance_distance_time );
printf("\n");

//相関係数を求めるプログラム
k = 0;
k =  covariance_distance_time / (stdev_distance * stdev_time);

//最小二乗法で一次近似式を求めるために新たに配列に格納する式
double x[20]={};
double y[20]={};
double a0 = 0, a1 = 0;

for (i = 0; i < number; i++) {
x[i] = data[i].distance;
y[i] = data[i].time;
}

int N = number;// データの個数

lsm(x, y, N, &a0, &a1);// 最小二乗法の計算

printf("a0=%3.2e\na1=%3.2e\n", a0, a1);

sprintf(buf, "距離及び所要時間の平均値\n 距離:%3.2e [km]\n 時間:%3.2e [h]\n", ave_distance, ave_time);
sprintf(buf1, "距離及び所要時間の標準偏差\n 距離:%3.2e [km]\n 時間:%3.2e [h]\n", stdev_distance, stdev_time);
sprintf(buf2, "相関係数:%3.2e[-]\n", k);
strcat(buf, buf1);
strcat(buf, buf2);
printf(buf);
printf("\n");

ちなみにこの後ファイルに書き込みをしたいのでbufにいれていますが、それ以前の問題なのでsprintfは気にしないでください…

試したこと

補足情報(FW/ツールのバージョンなど)

Eclips Neon 4.6.3

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2020/06/10 12:10

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

+1

Eclipse使ってるなら、デバッグしましょう
ブレークポイントを設定すれば、実行をそこで中断して、変数のナカミを見ることができます
そこから1行づつ実行させて、変数の値の変化やコードの流れを見ることもできます

そうすれば、アテずっぽでコードを書かなくて済むようになるし、動かない原因を探る事ができるようになります

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/10 12:44

    回答ありがとうございました。
    デバッグで見ていった結果、breakが抜けられていないことが分かり、見たところ、"}"の位置の問題でした。

    キャンセル

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

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る