如果我理解你的问题,你的第一行上的文件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为行运行总和)。你可以用很多方法来做到这一点。 –