Это может быть очень неэффективный способ сделать это, но его вид работы
Этот код читает через файл, сохраняет 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]);
}
Проблема с вашим подходом, которая приводит к поведению, которое вы видите, заключается в том, что ваш код никогда не копирует данные из буфера. Эта строка
array_buffer[count] = line_char;
помещает указатель на тот же char buff[512]
из main
во всех восьми местах. Последующие вызовы fgets
переопределяют содержимое предыдущих чтений, поэтому вы получаете восемь копий последней строки.
Вы можете исправить эту проблему, сделав копию, например, с помощью strdup
или путем выделения памяти с помощью malloc
и создания копии. Однако вам нужно free
все, что вы выделите.
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++;
}