Мне нужно написать код на C, который мог бы читать большие файлы csv, содержащие большие матрицы данных со значениями double
. Мне нужно читать столбец за столбцом, и у меня нет предварительной информации о количестве строк и столбцов в файле. Каков наиболее эффективный способ обработки на языке C - с точки зрения времени и памяти? В основном мне нужно обрабатывать каждый столбец отдельно, но я могу читать по строкам, если чтение более эффективно.
Пожалуйста, направьте меня к ответу, если он был задан ранее. Спасибо
2 ответа
Поскольку csv основан на строках (на основе строк), и вам нужно обрабатывать столбцы, лучшим способом было бы взять весь файл в памяти: запросите размер файла и выделите этот кусок памяти с помощью malloc. Прочитайте первую строку и определите количество столбцов, 'numcols'. Теперь повторно обработайте файл и выделите для каждой строки массив с записями 'numcols', которые будут указывать на начало столбца в строке (поскольку каждое число может иметь разное количество цифр, вы не можете предположить, что все столбцы начинаются с одного и того же числа). смещение в строке). Теперь вы готовы к обработке ваших столбцов.
Если файл не помещается в памяти, вы можете открыть 'numcols' дополнительные файлы вывода, в которые вы записываете столбцы из строк ввода (например, вы записываете дубли в двоичном формате в файлы), затем перематываете их и обрабатываете каждый файл , который содержит столбец. Если эти выходные файлы помещаются в память, вы можете прочитать их в массив. (Я не говорил, что это эффективно.)
CSV-файл — это текстовый файл. Обычно каждая строка отделяется символами конца строки, а запятые разделяют столбцы. Вы должны сканировать каждую строку, чтобы идентифицировать столбцы.
Есть много способов решить эту проблему. Ваше решение действительно зависит от подпрограмм, которые вам удобно использовать.
Я бы выделил настолько большой буфер, насколько вы можете себе позволить, используя malloc(), читал CSV-файл по частям, используя fread(), и сканировал его, чтобы найти и обработать столбцы.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
// JFL 11 Feb 15
int main(int argc,char *argv[])
{
int r;
int allocsize,filesize,len;
char *fname;
char *alloc=0;
FILE *fh=0;
if(argc<2)
goto BAIL;
fname=argv[1];
// open file, find size
if(!(fh=fopen(fname,"rb")))
goto BAIL;
fseek(fh,0,SEEK_END); // seek to end
if((filesize=ftell(fh))<0)
goto BAIL;
fseek(fh,0,SEEK_SET);
// alloc buffer
allocsize=16*1024; // max buffer size
if(allocsize>filesize)
allocsize=filesize; // limit to filesize
// 'search' for the largest buffer we can use temporarily
for(;allocsize>1024;allocsize-=1024)
{
if((alloc=malloc(allocsize)))
break; // allocated
} // for
if(!alloc)
{ // try once more, small buffer
allocsize=1024;
if(!(alloc=malloc(allocsize)))
goto BAIL;
}
// read the file
for(;filesize;)
{
len=filesize; // remaining size
if(len>allocsize)
len=allocsize; // limit to buffer size
if(len!=fread(alloc,1,len,fh)) // read
goto BAIL;
filesize-=len; // adjust remaining size
// process len bytes
} // for
r=ftell(fh);
printf("success, read %d bytes\n",r);
BAIL: // common exit point
if(fh)
fclose(fh); // close if opened
if(alloc)
free(alloc); // free if allocated
return 0;
} // main()
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.