私はあなたの問題を理解していれば、あなたは行ごと5-values
を含む500-rows
続く最初の行上の単一の無関係な値を(少なくとも私の理解に)、持っているファイルmarketing.txtを持っています。課題は、20-lines
(各行とグループごとにrow
とcol
小計)のグループごとにさまざまな合計を計算し、最後にrow
とcol
合計をさまざまな他の最大/最小値とともに計算することです。
marketing-scaffold.cには、投稿したコードの基本サブセットが含まれています。データを処理するには、2D配列を塗りつぶし/再塗りつぶしてから合計を計算します。 2D配列の処理はプロジェクトの冗談に見えますが、ループ構造を整理して繰り返しの合計を処理するのに役立ちます。
開始するには、2D配列は行/列の合計を計算するために必須ではありません。そこでは、20行ブロックとファイル全体の合計を実行し続けるだけです。各行の行合計は、単純に各行の各要素の合計です。
ファイルを読み取るには、最初の行の読み取り/破棄が必要です(fgets
)。最初の行を破棄した後は、基本的に、1行につき5つの整数値を、EOF
になるまで20のグループで読み込みます。そのためにあなたに似た何かができる:かかわらず、コードを探し
enum { NCOL = 5, NSUM, NROW = 20, MAXC = 256 }; /* constants */
...
int idx = 0; /* row index */
...
for (;;) { /* for all 20 line blocks in file */
int row[NCOL] = {0}, /* row values */
n = NROW, rtn = 0;
...
while (n-- && (rtn = fscanf (fp, " %d %d %d %d %d", &row[0], &row[1],
&row[2], &row[3], &row[4])) == NCOL && rtn != EOF) {
int rsum = 0;
/* compute row/col sums
... */
} /* output row values | row sum */
printf (" row [%3d] %3d %3d %3d %3d %3d | %3d\n",
idx++, row[0], row[1], row[2], row[3], row[4], rsum);
}
if (rtn == EOF) break; /* if EOF, break outer loop */
}
、グローバルスコープでenum
は、単にあなたのコードの残りの部分によって使用される複数の定数を宣言するための方法を提供します。外側のfor (;;)
ループは、壊れるまでループします。外側のループ内に、値'n'
はNROW
(20
)に設定され、while
ループは、最もn
回実行またはfscanf
までNCOL
(5
)値またはEOF
を読み取ることができないであろう遭遇します。 while
ループはEOF
で中断しますが、外側ループを破ることはありません。したがって、fscanf
の戻り値はrtn
に取り込まれ、while
ループ終了後にチェックされます。 rtn
がEOF
の場合、外側ループは終了します。
これは、marketing.txtを20行のグループに分割する基本的なアプローチの1つです。残りは、20行の小計とファイル合計を計算できるように、必要な合計を格納しています。これを行うにはいくつかの方法がありますが、column
ごとに1つの合計と各row
の合計が必要であることがわかります。各行から5つの値を読み取るだけで、行の合計の値が得られます。 ブロックスコープの点で考えて、各コードブロック(たとえば、各ループのコードブロックが{ ... }
の間)のそれぞれの合計を保持する場合は、必要な値、小計、合計があります。
注意しなければならないことは、20行の行グループが繰り返されるたびに保持する各値の値をリセット(またはゼロ設定)することです。関連する変数を宣言し、個々のブロックの先頭に0
に初期化するだけです。
沿っ(row
配列に各行の値を20行、行および列の合計のためのファイルの合計行と列の和のためtsum
、行インデックスのidx
、csum
を使用して、一緒にピースを置くと読み出しシンプルなカウンタ変数のカップル)で、次のような何かを行うことができます。)
#include <stdio.h>
enum { NCOL = 5, NSUM, NROW = 20, MAXC = 256 };
int main (int argc, char **argv) {
char buf[MAXC] = "";
int idx = 0, tsum[NSUM] = {0}; /* row index, total sum */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
fgets (buf, MAXC, fp); /* read/discard first line w/25 */
for (;;) { /* for all 20 line blocks in file */
int row[NCOL] = {0}, /* row values */
csum[NSUM] = {0}, /* col & row sums */
i, n = NROW, rtn = 0, beg = idx;
/* for each line in 20 line block, read values int row */
while (n-- && (rtn = fscanf (fp, " %d %d %d %d %d", &row[0], &row[1],
&row[2], &row[3], &row[4])) == NCOL && rtn != EOF) {
int rsum = 0;
for (i = 0; i < NCOL; i++) { /* for each value in row */
rsum += row[i]; /* compute row sum */
csum[i] += row[i]; /* 20 line col sum */
tsum[i] += row[i]; /* total col sum */
} /* output row values | row sum */
printf (" row [%3d] %3d %3d %3d %3d %3d | %3d\n",
idx++, row[0], row[1], row[2], row[3], row[4], rsum);
csum[NCOL] += rsum; /* 20 line row sum sub-total */
tsum[NCOL] += rsum; /* file row sum total */
}
if (rtn == EOF) break; /* if EOF, break outer loop */
printf ("-------------------------------------\n"); /* 20 ln sub-total */
printf (" rows[%3d-%3d] %3d %3d %3d %3d %3d | %3d\n\n", beg, idx - 1,
csum[0], csum[1], csum[2], csum[3], csum[4], csum[NCOL]);
}
printf ("=====================================\n"); /* file totals */
printf (" total %3d %3d %3d %3d %3d | %3d\n",
tsum[0], tsum[1], tsum[2], tsum[3], tsum[4], tsum[NCOL]);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
は、最初の引数としてmarketing.txtを与える(あるいは単にstdin
にコンテンツをリダイレクトし、コードが読み取られます行の値を20行のグループに合計し、ファイル合計。
使用例/出力
$ ./bin/marketing_custom <dat/marketing.txt
row [ 0] 100 100 100 100 100 | 500
row [ 1] 1 1 2 1 2 | 7
row [ 2] 2 2 3 4 5 | 16
row [ 3] 3 5 5 3 3 | 19
row [ 4] 4 2 2 0 0 | 8
row [ 5] 5 0 0 2 2 | 9
row [ 6] 6 1 1 1 1 | 10
row [ 7] 7 4 3 2 1 | 17
row [ 8] 8 4 3 2 1 | 18
row [ 9] 9 10 10 10 10 | 49
row [ 10] 10 4 5 4 2 | 25
row [ 11] 11 4 3 2 1 | 21
row [ 12] 12 1 2 3 4 | 22
row [ 13] 13 4 3 2 1 | 23
row [ 14] 14 4 3 2 1 | 24
row [ 15] 15 1 2 3 4 | 25
row [ 16] 16 13 3 4 4 | 40
row [ 17] 17 100 100 100 182 | 499
row [ 18] 18 17 18 19 20 | 92
row [ 19] 228 13 14 15 16 | 286
-------------------------------------
rows[ 0- 19] 499 290 282 279 360 | 1710
row [ 20] 100 100 100 100 100 | 500
row [ 21] 1 1 2 1 2 | 7
row [ 22] 2 2 3 4 5 | 16
row [ 23] 3 5 5 3 3 | 19
row [ 24] 4 2 2 0 0 | 8
row [ 25] 5 0 0 2 2 | 9
row [ 26] 6 1 1 1 1 | 10
row [ 27] 7 4 3 2 1 | 17
row [ 28] 8 4 3 2 1 | 18
row [ 29] 9 10 10 10 10 | 49
row [ 30] 10 4 5 4 2 | 25
row [ 31] 11 4 3 2 1 | 21
row [ 32] 12 1 2 3 4 | 22
row [ 33] 13 4 3 2 1 | 23
row [ 34] 14 4 3 2 1 | 24
row [ 35] 15 1 2 3 4 | 25
row [ 36] 16 13 3 4 4 | 40
row [ 37] 17 100 100 100 182 | 499
row [ 38] 18 17 18 19 20 | 92
row [ 39] 230 13 14 15 16 | 288
-------------------------------------
rows[ 20- 39] 501 290 282 279 360 | 1712
<snip>
row [499] 100 100 100 100 100 | 500
-------------------------------------
rows[480-499] 499 290 282 279 1251 | 2601
=====================================
total 12477 7949 7550 7668 9891 | 45535
あなたがグループに20行をそれをしたいでしょうから、(必要に応じて、あなたの2次元配列を実装し、構造を見てみましょうfor
ループ範囲内でそれを宣言して初期化しますグループごとにリセットされます)。問題が発生した場合は、私に知らせてください。それは最初にたくさんのように見えるかもしれません、もしあなたがちょうどそれを細かく分割して(ライン、グループ、ファイルなど)、ラインから(あなたが入力を取って)ビルドすれば、それはそれが落ちるのに役立ちます。
入力ファイルには20行あり、各行には5つの値があります。 100個の値をすべて読み込んで保存する必要があるようです。次に、各行に最適な値を得るために、行順に進みます。各列の最適な値を得るために、最後に列順に進みます。 – bruceg
各行を読み込むには、最小5つの変数(または5つの要素の配列)が必要です(または、スキップして合計を保持するだけです)。さらに、* sum *変数ごとに1つの* sum *変数が必要です。すべての行と列を合計した場合、各行から読み取った値を保持するために5要素の配列を使用し、すべての合計を保持する1つの6要素配列を使用します(列の合計は0〜4、行を実行する行の合計)。あなたはいくつかの方法でそれを行うことができます。 –