This might be a very inefficient way to do it, but its sort of working
This code reads through a file, stores 8 line of text at a time in a global array (Would like a better option to do this if possible ) and dispatches for further processing.
here's the code
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;
}
The issue is that while printing out the contents of array_buffer, its printing out the last line in the buffer 8 times. (i.e. the 8th line its reading in every cycle). Its pretty obvious that
array_buff[0]
....
array_buff[7]
all point to the address of line 8
any help in solving this ? I know it might not be the correct way to buffer something at all !
You have a stale pointer, here I will explain
while (fgets(buff, 512, fp) != NULL )
{
//buff updated
line(buff);
//...
//inside of the line function
somepointertopointers[currIndex]=buff;
now it is looking at the location at buff, so all of the elements are looking at the same location, you need to copy the chars, or make a longer buffer and make sure you are updating the location the pointer is looking at, you can make 8 separate char[] pointers as well
This will give you the result you want
buff[512][8];
char** curr = buff;
while(fget(*curr,512,fp)!= NULL)
{
line(*curr);
curr++;
}
or alternatively you could allocate the buffer that is passed
#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]);
}
The problem with your approach that leads to the behavior that you see is that your code never copies the data from the buffer. This line
array_buffer[count] = line_char;
puts a pointer to the same char buff[512]
from main
at all eight locations. Subsequent calls to fgets
override the content of previous reads, so you end up with eight copies of the last line.
You can fix this issue by making a copy, e.g. with strdup
or by allocating memory with malloc
and making a copy. You need to free
everything that you allocate, though.
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++;
}