I have a file data.csv
which contains float
type data:
0.22,0.33,0.44
0.222,0.333,0.444
I need to read this file into a two dimensional dynamic array. But I am not able to read the full line with fgets
. Not sure why?
Here is my C code which I used on Ubuntu:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp;
float **data;
int i,j,rows=2,cols=3;
char * token;
fp=fopen("data.csv","r");
if(fp==NULL) {
fprintf(stderr,"Can't open input file");
exit(1);
}
data= malloc(rows * sizeof(float*));
char *rowbuffer=malloc( cols * ( sizeof(float)+sizeof(char) ) );
i=0;
while(fgets(rowbuffer,sizeof(rowbuffer),fp) !=NULL) {
data[i] = malloc(cols * sizeof(float));
j=0;
printf("\n %s",rowbuffer);
for (token = strtok(rowbuffer,","); token != NULL; token = strtok(NULL, ",")) {
data[i][j++] = atof(token);
/*printf("%s",token);*/
}
i++;
}
free(rowbuffer);
for(i = 0; i < rows; i++)
free(data[i]);
free(data);
fclose(fp);
}
The output is like:
0.22,0.
33,0.44
0.222,0
��
444
Error in `./test': double free or corruption (out): 0x0000000000adf270
Aborted (core dumped)
Can anyone tell why is this error? :( Or is there a better way to read this kind of data file?
Your coding problem is in :
fgets(rowbuffer,sizeof(rowbuffer),fp)
sizeof(rowbuffer)
will give you only the size of the pointer, not the size of the memory allocated to the pointer.
To resolve the issue, you need to supply the proper size of the allocated memory [cols * ( sizeof(float)+sizeof(char)
] to fgets()
.
Your logical problem is in :
You assumed that a printed represntation of a float
value will take the same amount of memory as it takes for that of a float
variable. No, that's not true. In the printed representation, each digit (including the decimal point and any leading or trailing 0
after the decimal) will consume one byte of memory each. You should keep that in mind while allocating memory for the destination buffer.