みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

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

締切り済みの質問

助けてください! c言語のプログラムです。

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

#define KAMOKU_SUU 5
#define AVE_INDEX KAMOKU_SUU
typedef struct
{
char name[32];
int scor[KAMOKU_SUU]; int mean;
} STUDENT;

int round(double d)
{
if (d < 0)
return (int)(d-0.5);
else
return (int)(d+0.5);
}

#define ARRAY_OF(a) (sizeof (a) / sizeof (a[0]))

int main(int argc,char* argv[])
{
int i, j,k, n;
int nStudets; double avrg[KAMOKU_SUU + 1];
double stdv[KAMOKU_SUU + 1];
STUDENT *mem;
char buff[80];

if (argc < 2)
{
printf("!パラメータ不足\n");
return 1;
}

nStudets = atoi(argv[1]);
mem = (STUDENT*)malloc(sizeof (STUDENT) * nStudets);
if (mem == NULL)
{
printf("!アロケーション\n");
return 2;
}

memset(avrg, 0, sizeof (avrg));
memset(stdv, 0, sizeof (stdv));

printf("生徒 %d 名分の成績を入力してください:\n", nStudets);

for (k = 0; k < nStudets; k++)
{
printf("%d 人目の点数と名前 > ", k + 1);
gets(buff);
strcpy(mem[k].name, strtok(buff," "));

mem[k].mean = 0;
for (j = 0; j < KAMOKU_SUU; j++)
{
int i = mem[k].scor[j] = atoi(strtok(NULL," \n"));
mem[k].mean += i;
avrg[j] += i;
stdv[j] += i * i;
}
mem[k].mean = round(mem[k].mean * 1.0 / KAMOKU_SUU);
}

for(j = 0; j < KAMOKU_SUU; j++)
{
avrg[AVE_INDEX] += avrg[j];
stdv[AVE_INDEX] += stdv[j];
avrg[j] = avrg[j] / nStudets;
stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]);
}

n = nStudets * KAMOKU_SUU;
avrg[AVE_INDEX] = avrg[AVE_INDEX]/ n;
stdv[AVE_INDEX] = sqrt(stdv[AVE_INDEX] / n) - (avrg[AVE_INDEX] * avrg[AVE_INDEX]);

printf("\n成績表\n");
printf("# NAME");
for (i = 1; i <= KAMOKU_SUU; ++i)
printf(" #%d ", i);
printf("MEAN\n");

for (k = 0; k< nStudets; k++)
{
printf("%d %10s",k+1,mem[k].name);

for (j = 0; j < KAMOKU_SUU; j++)
{
printf(" %3d",mem[k].scor[j]);
}
printf(" %3d\n",mem[AVE_INDEX].mean);
}


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

printf(" %10s","average");


for(j = 0; j < ARRAY_OF (avrg);j++)
{
printf(" %3.0f",avrg[j]);
}
printf("\n");


printf(" %10s","st.dev.");
for ( j = 0; j < ARRAY_OF (stdv); j++)
{
printf(" %3.0f",stdv[j]);
}
printf("\n");
printf("正常終了\n");
return 0;
}

 実行してもできません。原因が全く分かりません。
お願いします。
修正してくださるとありがたいです。

投稿日時 - 2011-05-18 23:22:38

QNo.6747396

すぐに回答ほしいです

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

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

回答(5)

ANo.5

>実行してもできません。

「パラメータ」を付けて起動し、
 人目の点数と名前 > aaa 65 56 68 90 88(enter)

のように5科目分、人数分入力したが、「正しい」結果が得られなかった = 「実行してもできません。」

として回答。
-------------------------------------------------
>修正してくださるとありがたいです。

1:考え方として、5科目平均を「第6科目」とすればよいと思います。

  メモリ確保では、そのようになっていますが、処理ではなっていません。

    mem[k].mean = round( (double)mem[k].mean / (double)KAMOKU_SUU );
    avrg[KAMOKU_SUU] += (double)mem[k].mean;  // 第6科目
  }
  double  dSaTotal;  // +++++

  for( j = 0; j <= KAMOKU_SUU; j++ ){  // 第6科目まで

    avrg[j] /= (double)nStudets;  // 科目平均
    dSaTotal = 0.0;

    for( k = 0; k < nStudets; k++ ){  // 差の2乗の集計

      dSaTotal += ( ( mem[k].scor[j] - avrg[j] ) * ( mem[k].scor[j] - avrg[j] ) );
    }
    dSaTotal /= (double)nStudets;
    stdv[j] = sqrt( dSaTotal );  // 'stdv[]' for 構文内初登場
  }
  ・・出力部分も。

2: printf( " %3.0f", stdv[j] ); はマズイです。

    出力直前で、
    avrg[j] = (double)round( avrg[j] );
    などの工夫が必要です。

    標準偏差は、%6.3f などで・・

3:round 関数は、

   int round( double d )
   //
   // 小数点以下四捨五入
   //
   {
     if( d < 0.0 ) return( (int)( d - 0.49999 ) );

     return( (int)( d + 0.50001 ) );
   }
   の方がよろしいかと・・。
   10.5 のはずが内部では、10.4999999・・・999 などもあり得ます。

(全角空白を使用しています)

投稿日時 - 2011-05-19 12:04:19

ANo.4

真ん中くらいの所の
for(j = 0; j < KAMOKU_SUU; j++)
{
avrg[AVE_INDEX] += avrg[j];
stdv[AVE_INDEX] += stdv[j];
avrg[j] = avrg[j] / nStudets;
stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]);
}


{
avrg[j] = avrg[j] / nStudets;
stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]);
avrg[AVE_INDEX] += avrg[j];
stdv[AVE_INDEX] += stdv[j];
}
ではないでしょうか。

あと同じ動作ですが

for(j = 0; j < ARRAY_OF (avrg);j++)
{
printf(" %3.0f",avrg[j]);
}
printf("\n");


printf(" %10s","st.dev.");
for ( j = 0; j < ARRAY_OF (stdv); j++)
{
printf(" %3.0f",stdv[j]);
}
printf("\n");
printf("正常終了\n");
return 0;
}

の ARRAY_OF(avrg) や ARRAY_OF(stdv) は KAMOKU_SUU の方がよいのでは?

投稿日時 - 2011-05-19 00:28:11

ANo.3

これの意味がよく分からないのですが…
int round(double d)
{
if (d < 0)
return (int)(d-0.5);
else
return (int)(d+0.5);
}

投稿日時 - 2011-05-19 00:07:51

ANo.2

>修正してくださるとありがたいです。

って言われましてもね、そのプログラムが何をするためのもので、
どんな風に入力を与えたらどういう出力を得るのかっていう、
プログラムの仕様に関する説明が一切ありませんので、
どうしようもないわけなんです。

投稿日時 - 2011-05-18 23:34:01

ANo.1

最初のほうだけ見ました。
起動時に引数が必要なようですが、どのように起動していますか?

エラー処理は割としっかりしているようなので、どのように入力したら、どのような出力があったのかを補足してください。
また、その際に正しいとされる出力を提示してください。

プログラムコードだけを提示されて修正してくれといわれても、どのような処理が正しいのかわからないので、修正のしようがありません。

投稿日時 - 2011-05-18 23:33:37

あなたにオススメの質問