我有一个txt文件,该文件由类型为double的制表符分隔的数据组成。数据文件超过10 GB,因此我只希望逐行读取数据,然后进行一些处理。特别地,数据是作为具有1001列和数百万行的矩阵布置的。下面只是一个伪造的示例,用于显示布局。

10.2  30.4  42.9 ... 3232.000 23232.45
...
...
7.234  824.23232 ... 4009.23  230.01
...


对于每一行,我想将前1000个值存储在数组中,并将最后一个值存储在单独的变量中。我是C语言的新手,所以如果您能指出一些主要步骤,那就太好了。

更新:

感谢您提出的所有宝贵建议和解决方案。我只是想出一个简单的示例,我只是从txt文件中逐行读取3×4矩阵。对于每一行,第一3个元素存储在x,和最后一个元素被存储在矢量y。因此,x是带有n-by-pn=p=3矩阵,y1-by-3向量。

以下是我的数据文件和代码。

资料档案:

1.112272    -0.345324   0.608056    0.641006
-0.358203   0.300349    -1.113812   -0.321359
0.155588    2.081781    0.038588    -0.562489


我的代码:

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

#define n 3
#define p 3

void main() {

    FILE *fpt;
    fpt = fopen("./data_temp.txt", "r");

    char line[n*(p+1)*sizeof(double)];
    char *token;
    double *x;
    x = malloc(n*p*sizeof(double));
    double y[n];

    int index = 0;
    int xind = 0;
    int yind = 0;

    while(fgets(line, sizeof(line), fpt)) {
        //printf("%d\n", sizeof(line));
        //printf("%s\n", line);

        token = strtok(line, "\t");
        while(token != NULL) {
            printf("%s\n", token);

            if((index+1) % (p+1) == 0) { // the last element in each line;
                yind = (index + 1) / (p+1) - 1; // get index for y vector;
                sscanf(token, "%lf", &(y[yind]));
            } else {
                sscanf(token, "%lf", &(x[xind]));
                xind++;
            }
            //sscanf(token, "%lf", &(x[index]));
            index++;
            token = strtok(NULL, "\t");
        }
    }

    int i = 0;
    int j = 0;
    puts("Print x matrix:");
    for(i = 0; i < n*p; i++) {
        printf("%f\n", x[i]);
    }
    printf("\n");

    puts("Print y vector:");
    for(j = 0; j < n; j++) {
        printf("%f\t", y[j]);
    }
    printf("\n");
    free(x);
    fclose(fpt);
}


有了上述内容,如果我将data_temp.txt替换为原始的10 GB数据文件(当然,在必要时更改np以及其他一些代码的值),希望一切都会奏效。

如果您能帮助我,我还有其他问题。


我首先初始化char line[]作为char line[(p+1)*sizeof(double)](注意不乘以n)。但是该行无法完全读取。我如何只为一行分配内存?长度是多少?我假定它的(p+1)*sizeof(double)由于存在(p+1)双打中的每一行。我还应该为\t\n分配内存吗?如果是这样,怎么办?
代码对您来说看起来合理吗?由于此代码将在数百万行上执行,因此如何提高效率?
如果我不知道原始10 GB文件中的列数或行数,如何快速计算行数和列数?


再次,我是C的新手,任何评论都非常感谢。非常感谢!

最佳答案

第一种方式

使用fread将文件大块读取到预分配的缓冲区中。

第二路

使用mmap将文件映射到您的进程存储空间,然后将指针移到文件上方。

08-15 23:46
查看更多