读取 250MB 文件时 C 中的代码被杀死

Leo*_*llo 2 c file dataset

我正在尝试使用 C 中的脚本处理一个 250MB 的文件。该文件基本上是一个数据集,我只想读取其中的一些列,并且(更重要的是)将其中的一个(最初是一个字符串)分解为一系列人物。

但是,即使我有足够的 RAM 可用,每次运行时代码都会被 konsole(使用 KDE Neon)杀死。

来源如下:

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

int main() {

FILE *arquivo;
char *line = NULL;
size_t len = 0;
int i = 0;
int j;
int k;
char *vetor[500];
int acertos[45];

FILE *licmat = fopen("licmat.csv", "w");

//creating the header
fprintf(licmat,"CO_CATEGAD,CO_UF_CURSO,ACERTO09,ACERTO10,ACERTO11,ACERTO12,ACERTO13,ACERTO14,ACERTO15,ACERTO16,ACERTO17,ACERTO18,ACERTO19,ACERTO20,ACERTO21,ACERTO22,ACERTO23,ACERTO24,ACERTO25,ACERTO26,ACERTO27,ACERTO28,ACERTO29,ACERTO30,ACERTO31,ACERTO32,ACERTO33,ACERTO34,ACERTO35\n");

if ((arquivo = fopen("MICRODADOS_ENADE_2017.csv", "r")) == NULL) {
    printf ("\nError");
    exit(0);
} 

//reading one line at a time
while (getline(&line, &len, arquivo)) {

    char *ptr = strsep(&line,";");
    j=0;
    //breaking the line into a vector based on ;
    while(ptr != NULL)
    {
        vetor[j]=ptr;
        j=j+1;
        ptr = strsep(&line,";");
    }

    //filtering based on content
    if (strcmp(vetor[4],"702")==0 && strcmp(vetor[33],"555")==0) {
        //copying some info
        fprintf(licmat,"%s,%s,",vetor[2],vetor[8]);   
        //breaking the string (32) into isolated characters
        for (k=0;k<27;k=k+1) {
            fprintf(licmat,"%c", vetor[32][k]);
            if (k<26) {
                fprintf(licmat,",");
            }
        }
        fprintf(licmat,"\n");

    }

    i=i+1;
}

free(line);
fclose(arquivo);
fclose(licmat);

}
Run Code Online (Sandbox Code Playgroud)

输出是完美的,直到脚本被终止。输出文件只有 640KB 长,只有大约 10000 行。

可能是什么问题?

Ste*_*edl 5

在我看来,您似乎错误地处理了由 管理的内存缓冲区getline()- 根据需要分配/重新分配 - 通过使用strsep(),这似乎操纵了相同的指针值。

一旦line已更新,以反映该行一些其他的元素,它不再指向分配内存的开始,然后下一次getline()需要用它做任何事情。

使用不同的变量传递给strsep()

while (getline(&line, &len, arquivo) > 0) { // use ">=" if you want blank lines
    char *parseline = line;

    char *ptr = strsep(&parseline,";");
    // do the same thing later
Run Code Online (Sandbox Code Playgroud)

这里的关键是:你不允许在最后(你这样做)使用lineother的值free(),并且你也不能让任何其他例程这样做。

编辑:更新以反映getline()在错误时返回 <0 (h/t to @user3121023)