буферизация набора строк из файла и сохранение его в массиве в C

Вопрос:

Это может быть очень неэффективный способ сделать это, но его вид работы

Этот код читает через файл, сохраняет 8 строк текста за раз в глобальном массиве (хотел бы, чтобы это было лучше, если это возможно) и отправляет для дальнейшей обработки.

здесь код

int count = 0;             //global
char *array_buffer[8];     //global

void line(char *line_char)
{

int lent = strlen(line_char);
array_buffer[count] = line_char;

printf("%d\n",count);

if (count == 8)
{

int row,col;
for(row = 0; row<count; row++){
printf("%d\n",row);
for(col = 0; col<=lent; col++) {
printf("%c", array_buffer[row][col]);
}
printf("\n");
}
count = 0;
}

count++;
}



int main(int argc,char **argv)
{

clock_t start = clock();

FILE *fp = fopen(argv[1], "r");
if(fp == NULL )
{
printf("Couldn't open file %s",argv[1]);
}
char buff[512];

while (fgets(buff, 512, fp) != NULL )
{
line(buff);             /*sending out an array having one line*/
}

return 0;
}

Проблема в том, что при распечатке содержимого массива array_buffer он печатает последнюю строку в буфере 8 раз. (т.е. 8-я строка, ее чтение в каждом цикле). Его довольно очевидно, что

array_buff[0]
....
array_buff[7]

все указывают на адрес строки 8

любая помощь в решении этого? Я знаю, что это может быть неправильный способ вообще что-то заманить!

Лучший ответ:

У вас есть устаревший указатель, здесь я объясню

while (fgets(buff, 512, fp) != NULL )
{
    //buff updated
    line(buff);
    //...
    //inside of the line function
        somepointertopointers[currIndex]=buff;

теперь он смотрит на местоположение в buff, поэтому все элементы смотрят на одно и то же место, вам нужно скопировать символы или сделать более длинный буфер и убедиться, что вы обновляете местоположение, на которое смотрит указатель, вы можете сделать 8 отдельных указателей char []

Это даст вам результат, который вы хотите

buff[512][8];
char** curr = buff;
while(fget(*curr,512,fp)!= NULL)
{
     line(*curr);
     curr++;
}

или, альтернативно, вы можете выделить буфер, который передан

#def BUFF_SIZE 512
#def BUFF_ARRAY_LEN 8


//put this somewhere before calling line 
//to initialize your array_buffer
for(i=0;i<BUFF_ARRAY_LEN;i++)
{
    array_buffer[i]=NULL;
}

...

//update in function line
//makes more sense to just use 
//the max len of a line
if(array_buffer[count] == NULL)
    array_buffer[count]=(char*)malloc(sizeof(char)*BUFF_SIZE);
strcpy(array_buffer[count],line_char);

...

//you will also need to
//clean up after you are 
//done with the memory
for(i=0;i<BUFF_ARRAY_LEN;i++)
{
    free(array_buffer[i]);
}

Ответ №1

Проблема с вашим подходом, которая приводит к поведению, которое вы видите, заключается в том, что ваш код никогда не копирует данные из буфера. Эта строка

array_buffer[count] = line_char;

помещает указатель на тот же char buff[512] из main во всех восьми местах. Последующие вызовы fgets переопределяют содержимое предыдущих чтений, поэтому вы получаете восемь копий последней строки.

Вы можете исправить эту проблему, сделав копию, например, с помощью strdup или путем выделения памяти с помощью malloc и создания копии. Однако вам нужно free все, что вы выделите.

Ответ №2
void line(char *line_char){
if (count == 8){
int row,col;
for(row = 0; row<count; row++){
printf("%2d:",row);
printf("%s", array_buffer[row]);
free(array_buffer[row]);
}
count = 0;
}
int lent = strlen(line_char);
array_buffer[count] = malloc((lent + 1)*sizeof(char));
strcpy(array_buffer[count], line_char);
//printf("%d\n", count);
count++;
}

Оцените статью
TechArks.Ru
Добавить комментарий