如何在C中汇总不同文件的列?

时间:2019-02-19 09:59:17

标签: c file sum multiple-columns

我有8个文件(文件%d-%d.dat),每个文件有2列和1000行:

  Route::match(['get', 'post'],'/admin/categories/create','CategoriesController@create');

我想逐行求和每个文件File%d-1的第二列,并将总和写入新文件中:Filesum1;对于File%d-2相同,依此类推,

 File1-1     File1-2    File1-3     File1-4
 x1a y1a     x1b y1b    x1c y1c     x1d y1d 
 x2a y2a     x2b y2b    x2c y2c     x2d y2d
 x3a y3a     x3b y3b    x3c y3c     x3d y3d
 .           .          .           .
 .           .          .           .


 File2-1     File2-2    File2-3     File2-4   
 x1e y1e     x1f y1f    x1g y1g     x1h y1h 
 x2e y2e     x2f y2f    x2g y2g     x2h y2h
 x3e y3e     x3f y3f    x3g y3g     x3h y3h
 .           .          .           .
 .           .          .           .

我创建了4个新文件:

Filesum1                           Filesum2                and so on  ..
x1a+x1e     y1a+y1e                 x1b+x1f   y1b+y1f           .
x2a+x3e     y2a+y2e                 x2b+x2f   y2b+y2f           .
.           .                       .         .
.           .                       .         .                 . 

然后我已经尝试过了,但是无法正常工作:

#include <stdio.h>
int main(void)  
{          
int numfiles=4;
int numfileread=8;
int i,yy1, yy2, x0, x1;

FILE *files[numfiles];
FILE *f[numfileread];

for (int n = 0; n < 4; n++)
{
    char filename[4];
    sprintf(filename, "filesum%d.dat", n);
    files[n] = fopen(filename, "w");
}

如果我有相同的作业,但是要读取50个文件:

for (int n = 0; n < 4; n++)
{
   yy1=0;
   yy2=0;
   for(int r=1;r<4;r++)
   {
       char file[8];
       sprintf(file, "file%d-%d.dat", r, n);
       f[i] = fopen(file, "r");
       fscanf(f," %d  %d",&x0,&x1);
       yy1+=x0;
       yy2+=x1;
       fclose(f);
       i++;
   }
   fprintf(files,"%d %d\n",yy1, yy2);
   fclose(files);
}

如何更改代码?

2 个答案:

答案 0 :(得分:0)

有多个问题:

  1. 该循环只会运行3次,我想您打算运行4次。

    for(int r = 1; r <4; r ++)

  2. 字符数组file没有足够的空间来容纳字符串"file%d-%d.dat"

  3. fclose(f);需要更改为fclose(f[i]);

  4. 您需要为files指定一个索引。

    fprintf(files,"%d %d\n",yy1, yy2);

这是我想出的。您可以尝试一下。

#include <stdio.h>

int main(){
        FILE *readFile1;
        FILE *readFile2;
        FILE *writeFile;
        char inFile1[32] = {0};
        char inFile2[32] = {0};
        char sumFile[32] = {0};
        int i,xa,xb,ya,yb;
        int ret1;ret2;
        for(i=0;i<4;i++){
                sprintf(inFile1, "File1-%d", i); 
                sprintf(inFile2, "File2-%d", i); 
                sprintf(sumFile, "sumFile%d", i); 
                readFile1 = fopen(inFile1, "r");
                readFile2 = fopen(inFile2, "r");
                writeFile = fopen(sumFile, "w");
                while(1){
                        ret1 = fscanf(readFile1, "%d %d", &xa, &ya);
                        ret2 = fscanf(readFile2, "%d %d", &xb, &yb);
                        if( (ret1 != 2) || (ret2 != 2) )
                                break;
                        fprintf(writeFile, "%d %d", xa+xb, ya+yb);
                }   
                fclose(readFile1);
                fclose(readFile2);
                fclose(writeFile);
        }   
        return 1;
}

答案 1 :(得分:0)

好的,因此您有大量文件,并且希望对这些文件上的两列数据求和。您还知道每个文件中将有1000行数据。您可以尝试使用文件句柄数组使所有文件保持打开状态并依次读取它们,但这太复杂了。相反:

  • 为每列定义一个数组并将其初始化为零;
  • 一次打开​​一个文件,读取数据,将其添加到阵列中并关闭该文件;
  • 将汇总数据写入结果文件。

此解决方案始终最多有一个打开的文件。

代码如下:

#include <stdlib.h>
#include <stdio.h>

enum {
    nData = 1000,       // number of rows
    nFiles = 50,        // number of files per block
    nBlocks = 4         // number of blocks
                        // nomenclature: file{file}-{block}.dat
};

int main(void)
{
    for (int j = 0; j < nBlocks; j++) {
        double col1[nData] = {0.0};
        double col2[nData] = {0.0};

        char outn[32];
        FILE *out;

        for (int i = 0; i < nFiles; i++) {
            char fn[32];
            FILE *f;

            snprintf(fn, sizeof(fn), "file%d-%d.dat", i, j);

            f = fopen(fn, "r");
            if (f == NULL) {
                fprintf(stderr, "Could not open '%s'.\n", fn);
                exit(1);
            }

            for (int k = 0; k < nData; k++) {
                char line[80];
                double x, y;

                if (fgets(line, sizeof(line), stdin) == NULL) break;
                if (sscanf(line, "%lf %lf", &x, &y) != 2) continue;

                col1[k] += x;
                col2[k] += y;
            }

            fclose(f);
        }

        snprintf(outn, sizeof(outn), "filesum-%d.dat", j);

        out = fopen(outn, "r");
        if (out == NULL) {
            fprintf(stderr, "Could not write to '%s'.\n", outn);
            exit(1);
        }

        for (int k = 0; k < nData; k++) {
            fprintf(out, " %15g %15g\n", col1[k], col2[k]);
        }

        fclose(out);        
    }

    return 0;
}

调味的季节。