• ベストアンサー

大量のファイルを読み込み、その各ファイルの中の最大値と最小値の出力の仕方

各ファイルの名前はinput_0.txtからinput_4.txtまであるとします。これらのファイルには(1)ナンバー(2)身長(3)体重がスペースをはさんで入力されています。 例:input_0.txt 1 172.3 65.3 2 164.3 54.6 3 176.4 55.4 4 170.2 70.4 5 167.4 63.8 この例では3番目の176.4が最大値として認識し2番目の164.3を最小値として出力させたいのですが、うまくいきません。プログラムを以下のように作りました。どこがいけないでしょうか?ご教授の方よろしくお願いします。 FILE *fpr,*fpw; int no[N],i,j,max_j,min_j; char fname[30]; float height[N],weight[N],max=0,min=0; for(i=0;i<4;i++) //file題名用ループ { sprintf(fname,"input_%d.txt",i); if((fpr=fopen(fname,"r"))==NULL) {puts("file open error!!");return 0;} for(j=0;j<5;j++){ //ファイル内容用ループ while((fscanf(fpr,"%d%f%f",&no[j],&height[j],&weight[j]))!=EOF) if(height[j]>max){ max=height[j];max_j=j; printf("number=%d__height=%.2f__weight=%.2f\n",no[max_j],max,weight[max_j]); } if(height[j]<min){ min=height[j];min_j=j;} printf("number=%d__height=%.2f__weight=%.2f\n",no[min_j],min,weight[min_j]); } fclose(fpr); }

質問者が選んだベストアンサー

  • ベストアンサー
  • minus273
  • ベストアンサー率75% (15/20)
回答No.1

うまくいかないとは、具体的にどういう結果になってしまうのかを 書いてくだされば原因を特定しやすいのですが……。 ざっと見て思ったのは以下のとおり。これで直ればよいのですが……。 ○2つめのファイルを読み込むとき、たとえば一つ目のファイルの  最大値が max に代入されたままです。  ループの最初でmaxやその他の変数に初期値を代入しましょう。 ○if(height[j]>max) と if(height[j]<min) の閉じ括弧の位置が違う。 ○最大値や最小値を発見するたびに表示してしまっているので  ファイル内容用ループのあとにprintfを移動する。 ○fscanf(fpr,"%d %f %f",&no[j],&height[j],&weight[j])  と、第二引数に半角スペースを空ける。

dai92_1981
質問者

補足

ご指摘ありがとうございます。 一点目、ループの始めでmaxの値が初期化されていない。max=0、min=0、max_j=0、min_j=0;をファイル内容ループ前に付け加えました。 二点目の閉じ括弧の位置が違う意味がわかりません。 もう少し詳しく教えてもらえないでしょうか? 三点目、printfはファイル内容ループが終了してから入力しました。 四点目、fscanf()はスペースをデータの区切りと解釈するそうです。読み取りはこのままでOKでした。 これで実行したところ、input_0.txtでは(最大値)3番目の176.4 55.4と出力してほしいのですが、4番目の176.4 70.4と出力されてしまいます。身長の最大値は認識されていますが、身長に対するno[max_j],weight[max_j]が一致しません。(一つ下の数字を認識)max_jの考え方を教えてもらえないでしょうか?

その他の回答 (3)

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.4

色々と突っ込みどころがあるような気がするが…… とりあえず、下のは動くので、自分のものと何が違うのか比べてみて欲しい。 多少方法を変えてはいるが、ね。 尚、インデントを全角スペースでつけているので、コピペの際は気をつけて。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _Data_t {  int  nNo;  float fHeight;  float fWeight; } Data_t; int main(void) {  FILE *fp;   // ファイルポインタ  int  i,j;   // ループ用変数  Data_t tMax;   // 最大値  Data_t tMin;   // 最小値  Data_t tTmp;   //  char szFname[256]; // ファイル名  char szBuf[256];  // 作業用バッファ  char *p;    // 作業用ポインタ  char *pToken;  // トークン用ポインタ  for(i = 0; i < 5; i++) {   sprintf(szFname, "input_%d.txt", i);      if((fp = fopen(szFname, "r")) == NULL) {    fprintf(stderr, "ファイル %s が開けません\n", szFname);    return 0;   }   // 初期化   tMax.fHeight = -1;   tMin.fHeight = 9999;   while(fgets(szBuf, 256, fp) != NULL) {    // 改行コード対策    p = strchr( szBuf, '\n' );    if( p != NULL ){     *p = '\0';    }    // 番号    pToken = strtok(szBuf, " ");    if(pToken == NULL) {     continue;    }    tTmp.nNo = atoi(pToken);    // 身長    pToken = strtok(NULL, " ");    if(pToken == NULL) {     continue;    }    sscanf(pToken, "%f", &tTmp.fHeight);    // 体重    pToken = strtok(NULL, " ");    if(pToken == NULL) {     continue;    }    sscanf(pToken, "%f", &tTmp.fWeight);    // 比較    if(tTmp.fHeight > tMax.fHeight) {     tMax = tTmp;    }    if(tTmp.fHeight < tMin.fHeight) {     tMin = tTmp;    }   }   // 表示   printf("ファイル %s\n", szFname);   printf("最大:Number=%d Height=%.2f Weight=%.2f\n", tMax.nNo, tMax.fHeight, tMax.fWeight);   printf("最小:Number=%d Height=%.2f Weight=%.2f\n", tMin.nNo, tMin.fHeight, tMin.fWeight);   fclose(fp);  }  return 0; }

  • R32C
  • ベストアンサー率39% (115/290)
回答No.3

while文のループ範囲が、最大値判定のif文のみ繰り返されますね。 しかもj==0のまま、その後の動作は、j==1の時は、EOF読み取り後 さらに読み出しに行くので、システムによってはそこで、暴走しますね。 number=1__height=172.30__weight=65.30 number=3__height=176.40__weight=55.40 セグメンテーション違反です maxの方は、#1さん指摘のように、今より大きいのが見つかるたびに表示 するようになっていますね。 minは上記の理由で、到達しないかもしくは、値が[0]にしか入って いませんが、 minは、0の身長より低い人を探すことになりますが、該当者がいないようですね。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.2

そもそも,heightとweigjhtを配列に入れる必要がないですね. 「これまで調べた中での最大値」,と「いま読み取った値」などを単純変数で持てばそれで良いのでは.

関連するQ&A

  • 複数ファイルの出力

    質問があります。1600個のデータを読み込んで(16個ずつの組で100組)、1番目、3番目、5番目、7番目のデータをss[1].txtとして出力し、同様に2番目、4番目、6番目、8番目のデータをsk[1].txt、9番目、11番目、13番目、15番目のデータをks[1].txt、10番目、12番目、14番目、16番目のデータをkk[1].txtとして出力させます。以下、ss[2].txt,sk[2].txt,ks[2].txt,kk[2].txt・・・に関してはそれぞれ直前のファイルに16を足したデータ(例えばss[2].txtなら、17番目、19番目、21番目、23番目のデータを出力)を出力させるというプログラムです。 以下に自分で作ったプログラムを掲載します。 void ecg_rr(fp,data_max) FILE *fp; { int i,j=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i,j=0;i<100,j<100;i++,j++) { sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0+j*16]); fprintf(fp,"%8.8f\n",data[0][2+j*16]); fprintf(fp,"%8.8f\n",data[0][4+j*16]); fprintf(fp,"%8.8f\n",data[0][6+j*16]); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1+j*16]); fprintf(fp,"%8.8f\n",data[0][3+j*16]); fprintf(fp,"%8.8f\n",data[0][5+j*16]); fprintf(fp,"%8.8f\n",data[0][9+j*16]); fclose(fp); /*ks,kkに関しても同様*/ } } これだと100個ずつファイルを出力できるのですが、データが全て0として出力されてしまいます。

  • 複数テキストファイルを読み込み、複数テキストファイルの出力

    質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。 以下が僕の作ったファイル出力部分のプログラムです。 /************/ void ecg_rr(fp,data_max) FILE *fp; { int b,i=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i=0;i<100;i++) sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0]); fprintf(fp,"%8.8f\n",data[0][2]); fprintf(fp,"%8.8f\n",data[0][4]); fprintf(fp,"%8.8f\n",data[0][6]); fclose(fp); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1]); fprintf(fp,"%8.8f\n",data[0][3]); fprintf(fp,"%8.8f\n",data[0][5]); fprintf(fp,"%8.8f\n",data[0][9]); fclose(fp); } 複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を 16_4 読み込むテキストファイル名1.txt ss[1] 16_4 読み込むテキストファイル名1.txt sk[1] 16_4 読み込むテキストファイル名2.txt ss[2] 16_4 読み込むテキストファイル名2.txt sk[2] ・・・ とやったのですが、うまくいきませんでした。 どうすればよいのでしょうか。

  • 最大値と最小値を表示したいのですが・・・

    double numに入っている数字から最大値と最小値を求めたいのですが、このままだと両方とも1.000になってしまうんです・・・ どうやったらちゃんと最大値と最小値が表示されるのでしょうか?? 初心者なものでスイマセンが教えてください!! #include<stdio.h> int main(void) { int i,j; double num[]={4.5,3.1,7.0,9.2,1.0,5.7,9.3,2.3,0.3,1.0}; double max,min; for(i=0; i<10; i++) { for(j=0; j<10; j++) { if(num[i]>num[j]) max=num[i]; } } for(i=0; i<10; i++) { for(j=0; j<10; j++) { if(num[i]<num[j]) min=num[i]; } } printf("最大値は%fです。",max); printf("最小値は%fです。",min); return 0; }

  • プログラムが動きません。

    以前動いていたプログラムが動かなくなりました。 プログラムは3個のtxtファイル(2×2のデータ)で第1列の絶対値和、第2列の絶対値和を求め、1つのtxtファイルとして出力するものです。 #include <stdio.h> #define DATA_MAX 4 #define CH 2 static double data[CH][DATA_MAX]; int read_data(fp) FILE *fp;{ int i,j=0; while(1){ for(j=0;j<DATA_MAX;j++){ for(i=0;i<CH;i++){ fscanf(fp,"%lf",&data[i][j]); } if(feof(fp)!=0) break; } return j; } } void ecg_rr(fp,data_max) FILE *fp; { int i=0; char fname[64]; char fname1[64]; for(i=0;i<3;i++) { sprintf(fname1,"k%d.txt",i+1); fp = fopen(fname1,"r"); read_data(fp); fclose(fp); sprintf(fname,"sum.txt"); fp = fopen(fname,"a"); if(data[0][0]<0){data[0][0]=-data[0][0];} else{data[0][0]=data[0][0];} if(data[0][1]<0){data[0][1]=-data[0][1];} else{data[0][1]=data[0][1];} if(data[1][0]<0){data[1][0]=-data[1][0];} else{data[1][0]=data[1][0];} if(data[1][1]<0){data[1][1]=-data[1][1];} else{data[1][1]=data[1][1];} data[0][i]=data[0][0]+data[0][1]; data[1][i]=data[1][0]+data[1][1]; fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); fclose(fp); } } メイン関数には問題がないので省略しましたが、ここまでで問題というところはあるでしょうか?

  • C言語 最大値と最小値を求めて表示するプログラム

    はじめまして。 C言語を学習中です。 下記の問題演習の解答として記載されているプログラムがどうしても理解できません。 特にプログラムの最後の方のwhile文で最大値と最小値の判定をしているのかと思いますが、どのような計算をして判定しているのでしょうか。 while (array[i] != -1) { if (array[i] > *max) *max = array[i]; if (array[i] < *min) *min = array[i]; i++; 具体的に教えてください。 よろしくお願い致します。 ●問題 0~100の範囲で入力された複数の数値の中から、 最大値と最小値を求めて表示するプログラムを作成せよ。 -1が入力された場合は入力の終わりと判定する。 ただし、最大値と最小値はmain関数以外の一つの関数の中で求める。 また、入力された数値を記憶する配列の要素数は10とし、 それ以上入力された場合はエラーが起きても仕方ないこととする。 ヒント:配列の中に -1 があればデータの終わりだと判断できる。 ヒント:最小値を探すには、最大値を記憶した変数との比較を繰り返せば良い。 ●解答 #include <stdio.h> void maxmin(int array[],int *max,int *min); int main(void) { int i = 0,array[10],max,min; do { printf("%d 番目の数:",i + 1); scanf("%d",&array[i]); i++; } while (array[i - 1] != -1); maxmin(array,&max,&min); printf("最大値 %d : 最小値 %d\n",max,min); return 0; } void maxmin(int array[],int *max,int *min) { int i = 0; *max = 0; *min = 100; while (array[i] != -1) { if (array[i] > *max) *max = array[i]; if (array[i] < *min) *min = array[i]; i++; } }

  • Perl5で同時刻のデータを統合したい

    perl初心者です。 下記のような同時刻の2つのデータを1つのデータに統合させたいのですが うまく出来ず困っています。 どうかお知恵を貸していただけないでしょうか。 データは時刻(時:分:秒), 値1, 値2になっています。 test1.txtの同時刻の後ろにtest2.txtの値1と値2を入れ、 欠測値には-999を入れるプログラムを作っています。 厄介なのは、 開始時刻がtest1.txtよりtest2.txtが早い場合や 終了時刻がtest2.txtよりtest1.txtが遅い場合がある事です。 test1.txt 10:13:14, 3.1, 0.1 10:13:15, 6.1, 0.3 10:13:16, 8.7, 0.2 10:13:17, 12.8, 0.3 10:13:18, 13.4, 0.5 10:13:19, 15.2, 0.4 test2.txt 10:13:16, 32.5, 0.01 10:13:17, 33.1, 0.03 10:13:18, 36.2, 0.02 10:13:19, 34.3, 0.01 10:13:20, 33.8, 0.04 10:13:21, 32.6, 0.09 10:13:22, 32.1, 0.08 希望結果 test.txt 10:13:14, 3.1, 0.1, -999.0, -999.00 10:13:15, 6.1, 0.3, -999.0, -999.00 10:13:16, 8.7, 0.2, 32.5, 0.01 10:13:17, 12.8, 0.3, 33.1, 0.03 10:13:18, 13.4, 0.5, 36.2, 0.02 10:13:19, 15.2, 0.4, 34.3, 0.01 10:13:20, -999.0, -999.0, 33.8, 0.04 10:13:21, -999.0, -999.0, 32.6, 0.09 10:13:22, -999.0, -999.0, 32.1, 0.08 以下が自分が作成したプログラムです。 open IN_1, "test1.txt"; open IN_2, "test2.txt"; open OUT, ">test.txt"; while ($input1 = <IN_1>) { # test1.txtの処理 chomp $input1; # 改行削除 @input1 = split(/,/, $input1); # カンマ区切り $n = $n + 1; $time1[$n] = @input1[0]; @time1 = split(/:/, $time1[$n]); # 時刻をコロン区切り @hours1[$n] = @time_l[0]; @min1[$n] = @time_l[1]; @sec1[$n] = @time_l[2]; @a[$n] = @input1[1]; # 値1 @b[$n] = @input1[2]; # 値2 } while ($input2 = <IN_2>) { # test2.txtの処理 chomp $input2; @input2 = split(/,/, $input2); $m = $m + 1; $time2[$m] = @input2[0]; @time2 = split(/:/, $time2[$m]); @hours2[$m] = @time2[0]; @min2[$m] = @time2[1]; @sec2[$m] = @time2[2]; @c[$m] = @input2[1]; # 値1 @d[$m] = @input2[2]; # 値2 } # 開始と終了時刻の計算 # test1.txtの時刻 $hours1_S = @hours1[1]; # 開始時 $hours1_E = @hours1[$n]; # 終了時 $min1_S = @min1[1]; # 開始分 $min1_E = @min1[$n]; # 終了分 $sec1_S = @sec1[1]; # 開始秒 $sec1_E = @sec1[$n]; # 終了秒 $time1_S = $hours1_S*3600 + $min1_S*60 + $sec1_S; # 開始時刻を秒に計算 $time1_E = $hours1_E*3600 + $min1_E*60 + $sec1_E; # 終了時刻を秒に計算 # test2.txtの時刻 $hours2_S = @hours2[1]; $hours2_E = @hours2[$m]; $min2_S = @min2[1]; $min2_E = @min2[$m]; $sec2_S = @sec2[1]; $sec2_E = @sec2[$m]; $time2_S = $hours2_S*3600 + $min2_S*60 + $sec2_S; $time2_E = $hours2_E*3600 + $min2_E*60 + $sec2_E; if($time1_S <= $time2_S){ # 開始時刻の比較 $starttime = $time1_S; }else{ $starttime = $time2_S; } if($time1_E <= $time2_E){ # 終了時刻の比較 $endtime = $time2_E; }else{ $endtime = $time1_E; } $j = $endtime - $starttime; # 全体のデータ個数 # test.txtへ出力 for($i=1; $i<=$j; $i++){ if(@hours1[$i] != @hours2[$i] && @min1[$i] != @min2[$i] && @sec1[$i] != @sec2[$i]){ printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n", @hours1[$i], @min1[$i], @sec1[$i], @a[$i], @b[$i], -999, -999; }elsif(@hours1[$i] == @hours2[$i] && @min1[$i] == @min2[$i] && @sec1[$i] == @sec2[$i]){ printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n", @hours1[$i], @min1[$i], @sec1[$i], @a[$i], @b[$i], @c[$i], @d[$i]; }else{ printf OUT "%2d:%2d:%2d %5.1f% 5.1f %5.1f %7.2f\n", @hours2[$i], @min2[$i], @sec2[$i], -999@, -999, @c[$i], @d[$i]; } } close IN_1; close IN_1; close OUT; とても汚いプログラムになってしまいました… このプログラム以外でも構いませんのでどうかよろしくお願い致します。

    • ベストアンサー
    • Perl
  • c言語でのダイクストラ法の実装

    大学の課題で、c言語におけるダイクストラ法について以下のようなものが出たのですが出力のためにどのようなコードを書けばいいかわかりません。どなたかコードや実装方法を教えていただけないでしょうか。 (入力例) 7 -1 7 3 6 -1 -1 4 7 -1 5 -1 6 -1 -1 3 5 -1 4 1 3 5 6 -1 4 -1 -1 -1 7 -1 6 1 -1 -1 2 -1 -1 -1 3 -1 2 -1 9 4 -1 5 7 -1 9 -1 1 1行目は頂点の数、2行目以降の各行は隣接行列の各要素を空白区切りで表し、最後の行の数はスタートの頂点の番号 [出力] 1. スタートとして選択した頂点から各頂点への最短経路とコストを以下の形式で 出力する.ここで s はスタートの頂点, g はゴールの頂点, c は合計のコス トを表す.また s ... g は最短経路の各頂点を空白区切りとして表す. s-->g : c ( s ... g ) 以下は上記の入力例の場合の出力例 Input>1 <-- スタートとして選択した頂点番号 1-->0 : 7 ( 1 0 ) 1-->1 : 0 ( 1 ) 1-->2 : 5 ( 1 2 ) 1-->3 : 9 ( 1 2 3 ) 1-->4 : 6 ( 1 4 ) 1-->5 : 8 ( 1 2 5 ) 1-->6 : 10 ( 1 2 6 ) ↓自分の書いたコード #include <stdio.h>#include <limits.h>#define FALSE 0 #define TRUE (!FALSE) #define INFINITY INT_MAX #define MAXSIZE 100 int dijkstr(int number_of_vertex, int weight[][MAXSIZE], int start_vertex){ int is_in_mst[MAXSIZE], d[MAXSIZE]; int i, j, number_of_edges, min_d, v; printf("Input>%d\n", start_vertex); for (i = 0; i <number_of_vertex; i++) is_in_mst[i] = FALSE; for (i = 0; i <number_of_vertex; i++) d[i] = INFINITY; d[start_vertex] = 0; for(number_of_edges = 0; number_of_edges<(number_of_vertex-1); number_of_edges++) { min_d = INFINITY; v = INFINITY; for (i = 0; i <number_of_vertex; i++) { if(is_in_mst[i] == FALSE &&d[i] <min_d) { min_d = d[i]; v = i;}} if(v != INFINITY) is_in_mst[v] = TRUE; for (i = 0; i <number_of_vertex; i++) { if(is_in_mst[i] == FALSE &&weight[i][v] != INFINITY &&(weight[i][v] + d[v]) <d[i]) d[i] = weight[i][v] + d[v];}}} int main(void){ int weight[MAXSIZE][MAXSIZE]; int i, j, data, n, start; printf("Input data size>"); scanf("%d", &n); printf("%d\n", n); for (i = 0; i <n; i++) { for(j = 0; j <n; j++) { printf("Input data>"); scanf("%d", &data); printf("%d\n", data); weight[j][i] = data; if(weight[j][i] == -1) weight[j][i] = INFINITY;}} printf("\n"); printf("Input start vertex>"); scanf("%d", &start); return 0;}

  • C言語(データ数の読み取り)

     input.txtというファイルの内容が 2 5 3 だとして、この3つの数字の最大値を求める以下のプログラムをコンパイルして実行すると、ファイルを読み込む前にデータ数「3」を入力しなければなりません。  データ数を入力することなくファイルからデータ数を読み取る方法を教えてください。大変お手数ですが、よろしくお願いします。 #include <stdio.h> main() { int i,max,max_no,N,a[1000]; FILE *fpi; printf("データ数を入力してください: "); scanf("%d",&N); if((fpi=fopen("input.txt","r"))==NULL) { fprintf(stderr,"ファイルを開けません\n"); exit(1); } for(i=0;i<N;i++) { fscanf(fpi,"%d",&a[i]); } max_no=0; max=a[max_no]; for(i=1;i<N;i++) { if(a[i]>max) { max=a[i]; max_no=i; } } printf("最大値は %d 番目のデータ %d です。\n",max_no+1,max); }

  • プログラムが間違っているようなのですが

    ファイルからデータを読み込み、そのファイル内のデータの最大値・最小値を求めるプログラムを作ろうとしているのですが、実行結果が 最大値:0 最小値:0 となり、max2とmin2にうまく値が入っていないようなのです。 main関数にsub_main;を追記してみたりと色々試しているのですが、うまくいきません。 ファイルの読み込みがうまくいっていないのでしょうか。 もしくはポインタの使い方がまずいのでしょうか。 ファイルの内容は 20 40 30 ・ ・ ・ という感じの、不規則な数字の羅列で、今は10個入っています(データ個数が分からない場合も考えているのですが・・・)。 プログラム初心者なので難しいことはあまり分からないですが、助言を頂ければ嬉しいです。 #include<stdio.h> int sub_main(int *tensu,int *max,int *min) { int i=0; FILE *fp; fp = fopen("11.txt","r"); while(fscanf(fp,"%d",&*tensu)!=EOF); { for(i=0;i<10;i++) { if(*tensu+i>*max) *max=*tensu+i; if(*tensu+i<*min) *min=*tensu+i; } } fclose(fp); } main() { int max2=0,min2=0; int *max=&max2; int *min=&min2; printf("最大値:%d\n最小値:%d\n",max2,min2); }

  • ファイル出力について

    ファイルの出力について質問させてください。 #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に対応してるのでそこを 考えてみたのですがどこが悪いのか 発見できません。アドバイスを お願いします。

専門家に質問してみよう