野球の対戦表について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nana

野球の対戦表について

#1

投稿記事 by nana » 8年前

こんにちは。
C言語初心者です。
今、野球の対戦成績表をファイルから読み込んで、それぞれの勝数、負数、勝率を計算し、表示するという
プログラムを作っています。
途中までできたのですが、勝数、負数、勝率の計算がうまくいきません。
コンパイルは通るのですが、計算結果がとんでもない数字になってしまいます。
どこが間違っているのか、どなたかご教授いただけませんでしょうか。

ファイル名:taisen.txt
仕様: ・1行につき1チームの成績
    ・先頭がチーム名、2、3番目がteam1との戦績(勝数、負数)
    ・3、4番目がteam2との戦績(勝数、負数)
    ・その後も順にteam6までの戦績
team1 0 0 12 12 14 10 14 10 10 13 12 11
team2 12 12 0 0 7 16 8 15 13 11 9 15
team3 10 14 16 7 0 0 10 14 15 9 12 9
team4 10 14 15 8 14 10 0 0 11 13 14 10
team5 13 10 11 13 9 15 13 11 0 0 16 8
team6 11 12 15 9 9 12 10 14 8 16 0 0

コード:

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

struct taisen{
	char team[10];
	int win_count[6];
	int lose_count[6];
	int win;
	int lose;
	double wpct;
};

int main(void)
{
	FILE * fp;
	char str[256];
	
	struct taisen data[6];
	int i,j,e;
	
	if((fp = fopen("taisen.txt","r")) == NULL){
		printf("ファイルを開くことができませんでした。\n");
		exit(1);
	}
	
	for(i=0;i<6;i++){
		fscanf(fp,"%s",&data[i].team);
		for(j=0;j<6;j++){
			fscanf(fp,"%d ",&data[i].win_count[j]);
			fscanf(fp,"%d ",&data[i].lose_count[j]);

                         data[i].win = data[i].win + data[i].win_count[j];
                         data[i].lose = data[i].lose + data[i].lose_count[j];
                         data[i].wpct = (double)data[i].win / (data[i].win + data[i].lose);
		}
	}

	printf("チーム名 勝 勝率\n");
	
	for(e=0;e<6;e++){
		printf("%s %d %3.f\n",data[e].team,data[e].win,data[e].wpct);
	}

	fclose(fp);
	return 0;
	
}

non
記事: 1097
登録日時: 9年前

Re: 野球の対戦表について

#2

投稿記事 by non » 8年前

1  累計する変数を初期化していない
2 勝率の計算を求める場所が違う。
3 チーム名の読み込みfscanfの書き方
4 勝率の出力書式
non

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

Re: 野球の対戦表について

#3

投稿記事 by bitter_fox » 8年前

nana さんが書きました:

コード:

	for(i=0;i<6;i++){
		fscanf(fp,"%s",&data[i].team);
		for(j=0;j<6;j++){
			fscanf(fp,"%d ",&data[i].win_count[j]);
			fscanf(fp,"%d ",&data[i].lose_count[j]);

                         data[i].win = data[i].win + data[i].win_count[j];
                         data[i].lose = data[i].lose + data[i].lose_count[j];
                         data[i].wpct = (double)data[i].win / (data[i].win + data[i].lose);
		}
	}
問題点としてはdata.winおよびdata.loseを初期化せずに使用していてごみが入っているためです。
for (j = 0; j < 6; j++)にはいる前に初期化してあげてください。

コード:

		data[i].win = 0;
		data[i].lose = 0;
		for(j=0;j<6;j++){
			...
それから

コード:

		for(j=0;j<6;j++){
                         data[i].win = data[i].win + data[i].win_count[j];
                         data[i].lose = data[i].lose + data[i].lose_count[j];
                         data[i].wpct = (double)data[i].win / (data[i].win + data[i].lose);
		}
のdata.wpct = ...;もよろしくありません。
team1のj=0のときの読み込みではdata.winおよびdata.loseが0になるので
data.win+data.loseが0になり0割が発生してしまいます。

また、蛇足ですが、
fscanf(fp,"%s",&data.team);
は誤りです。
&data.teamとするとポインタteamが存在しているアドレスを渡していることになります。
渡すべきは文字列の先頭アドレスなので単純に
data.teamとするべきです。
&をつけるのであれば
&data.team[0]とする必要があります。

[hr][追記]
nonさん>>被ってしまいました、すみません。

nana

Re: 野球の対戦表について

#4

投稿記事 by nana » 8年前

とても丁寧にご教授くださりありがとうございます。

初期化、fscanfの書き方、勝率の出力書式については良く理解できました。

ただ、data.wpct = ・・・ (勝率の計算) のところが、まだよく理解できません。

data.win+data.loseが0になり0割が発生してしまうということは分かったのですが、
どのように書けば良いのか分かりません。

申し訳ございませんが、もう少し詳しくご教授いただけないでしょうか。

よろしくお願いいたします。

maru
記事: 150
登録日時: 9年前

Re: 野球の対戦表について

#5

投稿記事 by maru » 8年前

nana さんが書きました:data.win+data.loseが0になり0割が発生してしまうということは分かったのですが、
どのように書けば良いのか分かりません。

以下の指摘をよく考えて見ましょう。
non さんが書きました:2 勝率の計算を求める場所が違う。


勝率は各チームの勝敗の合計数から求めます。
今の位置では各チームの勝敗の合計を求める途中結果を使用しています。
で、その途中結果が0勝0負から始めるのでゼロ割が発生してしまうのです。
勝率の計算を勝敗の合計数を求め終わった後に移動しましょう。

具体的には

コード:

    for(i=0;i<6;i++){
        fscanf(fp,"%s",&data[i].team);
        for(j=0;j<6;j++){
            fscanf(fp,"%d ",&data[i].win_count[j]);
            fscanf(fp,"%d ",&data[i].lose_count[j]);
 
                         data[i].win = data[i].win + data[i].win_count[j];
                         data[i].lose = data[i].lose + data[i].lose_count[j];
        }
                         data[i].wpct = (double)data[i].win / (data[i].win + data[i].lose);
    }
だけど、このように構造体の配列で処理するなら、

コード:

    struct taisen data[6] = {0};	// 構造体を一気に初期化
    // 中間は省略
    struct taisen* p = data;	// 構造体配列をポインタで処理
    for(i=0;i<sizeof(data)/sizeof(data[0]);++i, ++p){
        fscanf(fp,"%s", p->team);
        for(j=0;j<6;j++){
            fscanf(fp,"%d ",&p->win_count[j]);
            fscanf(fp,"%d ",&p->lose_count[j]);
 
            p->win += p->win_count[j];
            p->lose += p->lose_count[j];
        }
        p->wpct = (double)p->win / (p->win + p->lose);
    }
のほうが分かりやすいと思います。(あくまで個人的な意見です。)

nana

Re: 野球の対戦表について

#6

投稿記事 by nana » 8年前

皆様、とても丁寧にご教授いただきありがとうございました。

皆様のおかげで全てきちんと表示することができました。

本当にありがとうございます!!

閉鎖

“C言語何でも質問掲示板” へ戻る