我有一个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-p
的n=p=3
矩阵,y
是1-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数据文件(当然,在必要时更改n
,p
以及其他一些代码的值),希望一切都会奏效。如果您能帮助我,我还有其他问题。
我首先初始化
char line[]
作为char line[(p+1)*sizeof(double)]
(注意不乘以n
)。但是该行无法完全读取。我如何只为一行分配内存?长度是多少?我假定它的(p+1)*sizeof(double)
由于存在(p+1)
双打中的每一行。我还应该为\t
和\n
分配内存吗?如果是这样,怎么办?代码对您来说看起来合理吗?由于此代码将在数百万行上执行,因此如何提高效率?
如果我不知道原始10 GB文件中的列数或行数,如何快速计算行数和列数?
再次,我是
C
的新手,任何评论都非常感谢。非常感谢! 最佳答案
第一种方式
使用fread
将文件大块读取到预分配的缓冲区中。
第二路
使用mmap
将文件映射到您的进程存储空间,然后将指针移到文件上方。