基本上第一行是100 100 100 100,但我不知道如何实际读取每一行,并将它们加在一起打印到屏幕上。第一列有20个整数,我还需要将它们相加。我意识到我需要一个数组,但我需要两个数组还是只需要原始的网格数组?
#include <stdio.h>
#define ROWS 20
#define COLS 5
int main() {
// Open the input file and read in the number of cases to process.
FILE* ifp;
FILE* marketOut;
ifp = fopen("marketing.txt", "r");
marketOut = fopen("marketing.out.txt", "w");
int loop, numCases;
fscanf(ifp, "%d", &numCases);
// Go through each input case.
for (loop=0; loop<numCases; loop++)
{
// Get this input grid.
int grid[ROWS][COLS], i, j, x;
int a=0;
int nums[100];
x=0;
for (i=0; i<ROWS; i++)
for (j=0; j<COLS; j++)
fscanf(ifp, "%d", &grid[i][j]);
// Will store best value for row or column.
int best = 0;
while (i<ROWS)
{
x=grid[i]+i;
}
printf("x=%d", x);
// Output result.
printf("%dn", best);
}
fclose(ifp);
fclose(marketOut);
return 0;
}
如果我理解你的问题,你有一个文件marketing.txt,它在第一行有一个不相关的值(至少在我看来),后面是每行包含5-values
的500-rows
。挑战是计算每组20-lines
的各种总计(每行和每组的row
和col
小计),最后计算文件的row
和col
总计,以及其他各种最大/分钟。
您将获得一些基本文件营销脚手架.c,其中包含您发布的代码的基本子集。为了处理数据,您需要填充/重新填充2D阵列,然后计算总和。我将把2D数组的处理留给你,因为这似乎是项目的笑话,但将有助于组织循环结构来处理重复求和。
首先,2D数组不是计算行/列和的必需数组。在那里,您只需要继续运行20行块和整个文件的总计。每行的行和就是每行中每个元素的和。
读取文件需要读取/丢弃第一行(fgets
和其他任何东西一样有意义)。丢弃第一行之后,基本上每行读取五个整数值,二十个一组,直到遇到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 | %3dn",
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
即可
将这些部分放在一起,使用tsum
表示文件的列和行总数,idx
表示行索引,csum
表示20行的行和列总数,并将每行的值读取到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 | %3dn",
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 | %3dnn", 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 | %3dn",
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
看一下结构,根据需要实现2D数组(因为您希望它对20行进行分组,在for
循环范围内声明它并在那里初始化它将为每组重置它)。如果你遇到问题,请告诉我。一开始它可能看起来很多,如果你只是把它分解成几块(行、组、文件等),然后从行(你输入的地方)开始构建,这将有助于它就位。