- 締切済み
ファイル出力について
ファイルの出力について質問させてください。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #define NUM 50 /*構造体宣言*/ struct Students{ int N; /*学籍番号*/ int A; /*科目Aの点数*/ int B; /*科目Bの点数*/ int C; /*科目Cの点数*/ int sum; /*3科目の合計*/ double ave; double dev; }; /*平均の関数*/ double Average(struct Students tmp) { return(double)(tmp.A+tmp.B+tmp.C)/3.0; } /*偏差値の関数*/ double Deviation(struct Students k,double l,double m) { return(double)(NUM+10*(k.ave-l)/m); } int main(void){ struct Students std[NUM]; /*構造型配列*/ int j=0,i,N,A,B,scannum; double csum=0,sdev=0,cave; /*csum:クラスの総合点、sdev:標準偏差値、cave:クラスの一科目あたりの平均*/ FILE*file; /*ファイルのポインタを用意*/ srand((unsigned)time(NULL)); /*乱数の初期化*/ file=fopen("Data.txt","r"); /*Dataファイルのオープン*/ /*ファイルのオープンチェック*/ if(file==NULL){ fprintf(stderr,"cannnot open file 'Data.txt'\n"); exit(1); } /*Studentsにデータを格納*/ for(i=0;i<NUM;i++){ scannum=fscanf(file,"%d%d%d",&N,&A,&B); /*ファイルが読み込めたかチェック if(scannum!=1){ fprintf(stderr,"cannnot read file 'Data.txt'\n"); exit(1); } */ std[i].N=N; std[i].A=A; std[i].B=B; std[i].C=70+(int)(rand()/(RAND_MAX+1.0)*31); std[i].sum=std[i].A+std[i].B+std[i].C; std[i].ave=Average(std[i]); csum=csum+std[i].sum; }fclose(file); /*標準偏差計算*/ cave=csum/150.0; for(i=0;i<NUM;i++){ sdev=sdev+(std[i].sum-cave)*(std[i].sum-cave); } sdev=sqrt(sdev/NUM); /*偏差値の計算,最高偏差値の出力*/ for(i=0;i<NUM;i++){ std[i].dev=Deviation(std[i],cave,sdev); if(std[i].dev > std[j].dev){ std[j]=std[i]; } printf("学籍番号:%d.\n",std[i].N); printf("科目A:%d.\n",std[i].A); printf("科目B:%d.\n",std[i].B); printf("科目C:%d.\n",std[i].C); printf("平均点:%lf.\n",std[i].ave); printf("偏差値は:%lf.\n",std[i].dev); } /*results.txtに書き込み if((file=fopen("results.txt","w"))==NULL){ printf("cannnot open\n"); return 1; } fprintf(file,"%d,%d,%d,%d,%lf,%lf",std[j].N,std[j].A,std[j].B,std[j].C,std[j].ave,std[j].dev); fclose(file); */ return 0; } このプログラムを実行させてみるとdata.txtの一番最初の学生番号のみ 表示されません。そのためファイルの読み込みのエラー確認を入れると ストップしてしまう状態です。学生番号は101~150なんですが実行結果 が102~150で表示されます。学生番号は変数Nに対応してるのでそこを 考えてみたのですがどこが悪いのか 発見できません。アドバイスを お願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- LegaC2
- ベストアンサー率52% (224/428)
No.2です。 プログラムをコピペして、自分で実行してみました。 結果は、問題なく表示されました。 HSCGさんが、表示されないと言っているのは、画面からスクロールされてしまい、見えなくなっているだけだと思います。 ためしに、Nの値を10にしてみると、学籍番号:101からちゃんと表示されるはずです。 推測ですが、50件表示した場合、画面の表示長さが足りないようです。 ファイルに出力するなり、ダイアログを表示して、スクロール付のEditBoxなどで表示すれば、良いのではないかと思います。
- yama5140
- ベストアンサー率54% (136/250)
> i 番目の学生より偏差値が高いときだけ std[ j ] に入力してfor文で >まわし、更新して最終的に最高偏差を持つ学生を特定しようと意図しております。 ☆それでは、出力後、「最高偏差を持つ学生を特定◆」すればよいのでは・・。 なお、std[ j ] とせず、std[ 0 ] と明示する。 for( i = 0; i < NUM; i++ ){ std[ i ].dev = Deviation( std[i], cave, sdev ); (ここにあったものを下に) printf( "学籍番号:%d.\n", std[ i ].N ); printf( "科目A:%d.\n", std[ i ].A ); printf( "科目B:%d.\n", std[ i ].B ); printf( "科目C:%d.\n", std[ i ].C ); printf( "平均点:%lf.\n", std[ i ].ave ); printf( "偏差値は:%lf.\n", std[ i ].dev ); if( std[ i ].dev > std[ 0 ].dev ){ ◆ std[ 0 ] = std[ i ]; ◆ } } 最高偏差を持つ学生が確定 = 学生番号 101 データの破壊 ------------------------------------------ 「偏差値」を求める関数、ウィキペディアでみたら、なんかヘン。 ・ NUM は必要ですか。 ・3教科の「合計」を対象とすべきなのに3教科「平均」になってますよ。 ☆ return( 50.0 + 10.0 * ( k.sum - l ) / m );
- LegaC2
- ベストアンサー率52% (224/428)
偏差値の計算,最高偏差値の出力の部分にある、 std[j]=std[i]; は、何をやっているのでしょうか? jには、常に0が入っているのはずですが、意図したとおりの処理ですか? ちなみに、”一番最初の学生番号のみ表示されません。”とは、どこに表示されないのでしょうか?画面?ファイル?
- asuncion
- ベストアンサー率33% (2127/6289)
ざっとながめただけですけれど…。 > scannum=fscanf(file,"%d%d%d",&N,&A,&B); > /*ファイルが読み込めたかチェック > if(scannum!=1){ N, A, Bの3個のデータを読んでいるのに、 scannnumを1と比べているのはどうしてでしょうか。 また、入力ファイルの中身は、どういったものですか?
補足
投稿ありがとうございます。 >N, A, Bの3個のデータを読んでいるのに、 scannnumを1と比べているのはどうしてでしょうか。 これは参考資料にそのように書かれていたので そのまま適用をしました。決まり文みたいなものだと思って たんですが・・調べてみます。 ファイルの中身なんですが 101 65 78 102 56 89 103 90 78 ・・・・・ ・・・・・ 150 78 90 とうい形のテキストファイルです。 実行結果では101のみが出なくて困ってます;;
補足
投稿ありがとうございます。 std[j]=std[i] についてなんですがこれはstd[j]を最高偏差値を持つ学生情報に したいためにやりました。 i番目の学生より偏差値が高いときだけstd[j]に入力してfor文で まわし、更新して最終的に最高偏差を持つ学生を特定しようと意図 しております。 >どこに表示されないのでしょうか? すいません、言葉足らずでした。 表示されないというのはvisialC++を用いてデバックなしで実行した ときに結果がでるんですが 科目A:80 科目B:60 科目c:70 平均点:70 偏差値は54.378 学生番号:102 科目A:80 科目B:50 科目C:90 :::: :::: という風に学生番号101だけが結果画面にでない状況です。 読み込みのファイルにはちゃんと 101 80 60 102 80 50 ・・・・・ と書いてあるのでプログラムに問題があると考えてるんですが どこがいけないのか見つけられなくて・・