成績処理のプログラムで質問です

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

成績処理のプログラムで質問です

#1

投稿記事 by 紫苑 » 9年前

こんばんは、初めまして。
学校のC言語の講義で、「100人以下の不特定の人数の生徒の学籍番号、英語・数学・国語の得点を読みこんで、読み込んだ順に各人のデータを、さらに、各科目と総得点に関する平均と標準偏差を出力するCプログラムを作成せよ」という課題が出され、そのCプログラムを作成しました。
プログラムは以下の通りです。大変長いプログラムで申し訳ありません。

コード:

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

typedef struct {
  char id[6];
  int Eng,Math,Jap;
  double Total,Ave,Dev;
} Student;

int main(void)
{
  Student student[101],temp;
  int     num,scanf_val,k,i;

  for(num=0; num<101;){
    scanf_val = scanf("%5s %d",&student[num].id,&student[num].Eng,&student[num].Math,&student[num].Jap,&student[num].Total,&student[num].Ave,&student[num].Dev);
    if(scanf_val == 2)
      num++;
    else if(scanf_val == EOF)
      break;
    else{
      printf("Warning:Illegal data appears.(%d-th data)\n",num);
      break;
    }
  }

  if(num == 101){
    printf("Warning:There are 101 or more students.\n"
           "        ==> We process first 101 students.");
  }

  Total = 0;
  for(k=0; k<num; ++k){
    scanf("%lf",&student[k]);
    Total = (student[k].Eng + student[k].Math + student[k].Jap);
  }

  Ave = 0.0;
  for(k=0; k<num; ++k){
    scanf("%lf",&student[k]);
    Ave += student[k];
  }
  Ave /= 100.0;

  Dev = 0.0;
  for(k=0; k<num; ++k){
    Dev += (student[k]-Ave)*(student[k]-Ave);
  }
  Dev /=100.0;

  printf("Id-No   Eng  Math   Jap   Total\n"
         "-----  ----  ----  ----   -----\n");
         for(k=0; k<num; k++)
           printf("55s   %3d\n",student[k].id,student[k].Eng,student[k].Math,student[k].Jap,Total);
  printf("-------------------------------\n"
         "  Ave = %4.4g\n"
         "  Dev = %3.3g\n");
  return 0;
}
このプログラムをコンパイルすると、「Total」、「Ave」、「Dev」が定義されていないというエラーが出てしまいます。
7行目で定義しているつもりなのですが、これでは定義されたことにならないのでしょうか?
Total、Ave、Devが定義されていないというエラーが出る理由や、どう直すべきかを教えて頂けると、非常に助かります。
どうか宜しくお願い致します。

toto

Re: 成績処理のプログラムで質問です

#2

投稿記事 by toto » 9年前

構造体変数を書かないと構造体内の変数は使えませんよ。
student[].ave

toto

Re: 成績処理のプログラムで質問です

#3

投稿記事 by toto » 9年前

もうひとつ、
構造体の中で平均点などの変数を宣言していますが、問題の性質から必要ないのでは?
main文の中にaveなどの変数を入れてはどうですか?

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

Re: 成績処理のプログラムで質問です

#4

投稿記事 by bitter_fox » 9年前

紫苑 さんが書きました:
このプログラムをコンパイルすると、「Total」、「Ave」、「Dev」が定義されていないというエラーが出てしまいます。
7行目で定義しているつもりなのですが、これでは定義されたことにならないのでしょうか?
Total、Ave、Devが定義されていないというエラーが出る理由や、どう直すべきかを教えて頂けると、非常に助かります。
どうか宜しくお願い致します。
totoさんが既に仰ってるように、それらの変数はmain内にあるべきです。

また、

コード:

    scanf_val = scanf("%5s %d",&student[num].id,&student[num].Eng,&student[num].Math,&student[num].Jap,&student[num].Total,&student[num].Ave,&student[num].Dev);
    if(scanf_val == 2)
      num++;
これもおかしいです。
読み込む予定の物は7つなのに対して、フォーマット指示は二つしかされていません。
(また合計、平均、標準偏差を入力してもらう必要はありません)

コード:


  Total = 0;
  for(k=0; k<num; ++k){
    scanf("%lf",&student[k]);
    Total = (student[k].Eng + student[k].Math + student[k].Jap);
  }

  Ave = 0.0;
  for(k=0; k<num; ++k){
    scanf("%lf",&student[k]);
    Ave += student[k];
  }
  Ave /= 100.0;
これらのscanfはおそらく不要です。
また、Aveの計算が間違っています。(student[k]と言う点を除いても・・・)
全科目の平均か科目別の平均が解らないので全科目と仮定すると。
平均は(合計/要素数)になります。
(要素数を人数にした場合は三科合計の平均(一科の最高点が100の場合は(0 <= Ave <= 300))になります。)

次に標準偏差を求めるアルゴリズムですが、

コード:

  Dev = 0.0;
  for(k=0; k<num; ++k){
    Dev += (student[k]-Ave)*(student[k]-Ave);
  }
  Dev /=100.0;
これも正常に動作しません。
標準偏差は分散の平方根です。
分散と言うのは、各々の要素と平均の差を二乗して全部足したものをさらにその要素数で割る値の事です。

最後に出力です。

コード:

         for(k=0; k<num; k++)
           printf("55s   %3d\n",student[k].id,student[k].Eng,student[k].Math,student[k].Jap,Total);
  printf("-------------------------------\n"
         "  Ave = %4.4g\n"
         "  Dev = %3.3g\n");
まず、最初のprintfですが、フォーマット指示が二つしかないのに出力しようとしているものは5つあります。
(ちなみに合計は常に同じ値なので同じものがずらーっと表示されることになります。)
また、最後のprintfはフォーマット指示で二つの物を出力しようとしてますが、第二引数以降が有りません。

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

Re: 成績処理のプログラムで質問です

#5

投稿記事 by maru » 9年前

プログラムの細かな点は他の方々が指摘されているので、別の問題点を指摘させていただきます。
問題文には
紫苑 さんが書きました:「100人以下の不特定の人数」
と有りますが、提示されているプログラムでは100人固定で処理を実行するようになっています。
生徒数は最大で100人なので、その成績を入れる構造体の数は100でかまいませんが、その全てに
有効なデータが入るとは限らないと考える必要があります。
そう考えるとデータの入力を無条件に100回繰り返すのではなく、入力の終了を判定することが
必要になります。また入力が終了したら、その後のデータ(構造体配列)にはデータが無効であ
ることを示すようになっている必要があります。
さらに合計、平均、標準偏差を計算する際には有効なデータだけを使って計算するようにしてお
く必要があります。

ヒント:
入力に終了は学生番号の入力値を利用する。
データの有効・無効の判定も学生番号を利用する。

なお、100のデータを入れるための配列サイズは101ではなく100でいいですよ。
for文も for (num = 0; num < 100 ; ++num) になります。

toto

Re: 成績処理のプログラムで質問です

#6

投稿記事 by toto » 9年前

maruさん20行目でbreakしているので100人固定ではないと思ういますが、

それと細かいですが問題で読み込んでとあるので、ファイルから読み込ませるべきなのでは?
入力はさすがに100人はきついと思うので、例えば別のプログラムでコマンドラインから適当な数字を入力して
成績データをファイルに入れてそれを読み込んでは?

for文内で入力のミスを判定している部分は無駄だと思うので・・・・
もちろん問題でそうなっていれば別ですが

if(scanf_val == 4) //名前 英語 国語 数学
num++

まぁこの部分です。

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: 成績処理のプログラムで質問です

#7

投稿記事 by ISLe » 9年前

ちゃんとEOFをチェックしていますから標準入力にファイルをリダイレクトして使うならこのままでも良いのではないでしょうか。

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

Re: 成績処理のプログラムで質問です

#8

投稿記事 by maru » 8年前

toto さんが書きました:maruさん20行目でbreakしているので100人固定ではないと思ういますが、
Ave /= 100.0;
Dev /=100.0;
を見て100以下の処理をやっていないと短絡的に見てしまいました。

今日は見落としばっかりで残念な私。orz

紫苑

「struct に対して正しくありません」と出てしまいます

#9

投稿記事 by 紫苑 » 8年前

皆さまが助言して下さったことをを参考に少しプログラムを書きなおしてみましたが、
「error C2088: '/' : struct に対して正しくありません。」、「error C2088: '-' : struct に対して正しくありません。」、「error C2088: '-' : struct に対して正しくありません。」と出てしまいました。
どうも、以下の部分がおかしいようですが、調べてみてもどう直すと良いのか分からないです。

コード:

 Ave = 0.0;
  for(k=0; k<num; ++k){
    Ave += student[k]/k;
  }
  Ave /= 100.0;
 
  Dev = 0.0;
  for(k=0; k<num; ++k){
    Dev += (student[k] - Ave)*(student[k] - Ave);
  }
  Dev /=100.0;
エラーが出たのはこの中の3行目(「error C2088: '/' : struct に対して正しくありません」)、9行目(「error C2088: '-' : struct に対して正しくありません。」が2つ)です。
よろしければ、エラーがでないように直す方法を教えて頂けますでしょうか。
なお、標準偏差の方はまだ求める式が分からないので、後で調べて式を書き直します。

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

Re: 「struct に対して正しくありません」と出てしまいます

#10

投稿記事 by bitter_fox » 8年前

紫苑 さんが書きました:

コード:

 Ave = 0.0;
  for(k=0; k<num; ++k){
    Ave += student[k]/k;
  }
  Ave /= 100.0;
 
  Dev = 0.0;
  for(k=0; k<num; ++k){
    Dev += (student[k] - Ave)*(student[k] - Ave);
  }
  Dev /=100.0;
エラーが出たのはこの中の3行目(「error C2088: '/' : struct に対して正しくありません」)、9行目(「error C2088: '-' : struct に対して正しくありません。」が2つ)です。
よろしければ、エラーがでないように直す方法を教えて頂けますでしょうか。

コード:

struct Struct
{
	int test;
};

struct Struct s;
の時、構造体へのアクセスは次のようにします。

コード:

s.test;

toto

Re: 成績処理のプログラムで質問です

#11

投稿記事 by toto » 8年前

せっかくmaruさんが指摘しているのですから、
平均値などの計算を直してはいかがですか?

100で割るのではなくnumではないですか??

それとまずは各学科の合計値、総合点の合計値をだすことをやる必要があります。
ですから少なくともaveは各学科ごとにある必要があると思うのですが?
そして今はどの処理ができないのでしょうか?

紫苑

Re: 成績処理のプログラムで質問です

#12

投稿記事 by 紫苑 » 8年前

bitter_fox さん、構造体へのアクセスについて教えてくださってありがとうございました。
仰るとおりに修正してみたところ、エラーがでなくなりました。
toto さんが書きました:せっかくmaruさんが指摘しているのですから、
平均値などの計算を直してはいかがですか?

100で割るのではなくnumではないですか??

それとまずは各学科の合計値、総合点の合計値をだすことをやる必要があります。
ですから少なくともaveは各学科ごとにある必要があると思うのですが?
そして今はどの処理ができないのでしょうか?
助言ありがとうございます。
AveとDevをnumで割るようになおしましたが、今は、結果が正しい値にならず、
Warning:Illegal data appears.(0-th data)
Id-No Eng Math Jap Total
----- ---- ---- ---- -----
55s -1079292160
-------------------------------
Ave = 1.501e-312
Dev = 0
となってしまい、どうするべきか悩んでいるところです。
AveとDevを求める部分のプログラムを、

コード:

 Ave = 0.0;
  for(k=0; k<num; ++k){
   Ave += (student[k].Eng + student[k].Math + student[k].Jap)/k;
  }
  Ave /= num;

  Dev = 0.0;
  for(k=0; k<num; ++k){
   Dev += ((student[k].Eng + student[k].Math + student[k].Jap)/3 - Ave)*((student[k].Eng + student[k].Math + student[k].Jap)/3 - Ave);
  }
  Dev /=num;
としたのですが、これではやはり間違いでしょうか?

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

Re: 成績処理のプログラムで質問です

#13

投稿記事 by maru » 8年前

紫苑 さんが書きました:

コード:

 Ave = 0.0;
  for(k=0; k<num; ++k){
   Ave += (student[k].Eng + student[k].Math + student[k].Jap)/k;
  }
  Ave /= num;
1. k で割ることの意味は何でしょうか?
2. k は 0~numまで変化しますが、最初で 0 割りが発生すると思いますが、発生していませんか?
[hr][追記]
2.はエラーメッセージがでてましたね。Windowsだと例外でプログラムが停止するので、発生していないのかと思ってしまいました。

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

Re: 成績処理のプログラムで質問です

#14

投稿記事 by maru » 8年前

あと、「各科目と総得点に関する平均と標準偏差を出力」とあるので、少なくとも
英語の平均、数学の平均、国語の平均、(総得点の平均は前3つの平均を合計で可能)
英語の標準偏差、数学の標準偏差、国語の標準偏差、総得点の標準偏差
の7つの変数が必要ですが、それはどの変数に対応していますか?
見たところ、Ave や Dev という変数しかないようですが。

紫苑

#15

投稿記事 by 紫苑 » 8年前

maruさん、ご回答ありがとうございます。
kが最初に0になるということは、maruさんが指摘して下さって初めて気付きました。
Linuxでもエラーは出なかったため、そこには気付けなかったです。
kで割る理由は、平均を出す上で生徒数で割らなければいけないからだと思っていましたが、改めて考え直してみると、kではなく3で割るのが正しそうですね。
また、英語・数学・国語のそれぞれの科目の平均点、それぞれの科目の標準偏差は、まだプログラム内に入れていませんでした。
それらの変数を入れたプログラムを作り次第、結果をここに書かせて頂きます。

閉鎖

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