如果我理解你的問題,你的第一行上的文件marketing.txt具有單值無關(至少我的理解),然後是包含5-values
每行500-rows
。面臨的挑戰是計算每個組的20-lines
(row
和col
小計每個行和組)的各種總計,最後爲文件計算總計row
和col
以及各種其他最大/最小值。
您將獲得一些基本文件marketing-scaffold.c帶有您發佈的代碼的基本子集。爲了處理數據,您要填充/重新填充二維數組,然後計算總和。我將把二維數組處理給你,因爲這看起來是項目的開場白,但將有助於組織循環結構來處理重複的總和。
首先,2D數組對於計算行/列總和不是強制性的。在那裏,你只需要保持20行塊和整個文件的總計運行總數。每行的行總和只是每行中每個元素的總和。
讀取文件,需要讀取/丟棄第一行(fgets
和其他任何東西一樣)。丟棄第一行後,您將基本上以每20行爲一組讀取五個整數值,直到遇到EOF
。對於你可以做類似的東西:
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行組的一種基本方法。其餘部分存儲所需的總和,以便計算20行小計以及文件總數。雖然有很多方法可以做到這一點,但您知道每個column
以及每個row
的總數都需要1個。簡單地讀取每行的5個值將提供行總和的值。如果您只是考慮區塊範圍並保留每個代碼塊的每個代碼塊的總計(例如,每個循環的代碼塊在{ ... }
之間),則您將獲得所需的值,小計和總計。
要記住的另一件事是重置(或歸零)每組20行重複行的每組值。只需聲明相關變量並在每個塊的開始處初始化爲0
即可。
把拼在一起,使用用於20行的行和列總計tsum
爲文件總列和行總和,idx
爲行索引,csum
和讀取的值,從各行到row
陣列(沿用幾個簡單的計數器變量),你可以做類似如下的內容:
#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線,在for
環路範圍內聲明並初始化它會重置它爲每個組)。如果遇到問題,請告訴我。起初看起來很多,如果你把它分解成小塊(線,組,文件等等),並從行(你輸入的地方)構建出來,它會幫助它落到位。
您的輸入文件有20行,每行有5個值。看來你需要讀取所有的100個值,並將它們存儲起來。然後按行排序以獲得每行的最佳值。最後按列順序進行操作,以獲得每列最佳值。 – bruceg
您需要至少5個變量(或一個5元素數組)來讀取每行(或者您可以跳過並保持總和)。另外,您需要爲每個* sum *需要一個* sum *變量。如果我總結所有的行和列,我會使用一個5元素的數組來保存從每行讀取的值,一個6元素的數組保存所有的總和(列總和爲0-4,元素5爲行運行總和)。你可以用很多方法來做到這一點。 –