Search code examples
cfilemallocscanfrealloc

fscanf() and realloc() - reading file to matrix


I have a problem with reading file dynamically to 2D array. I've been reading about it for a long time but I still don't know how to force my code to work.

My code: http://codepaste.net/3hcbtn

#include <stdio.h>
#include <stdlib.h>
int main(){
//This program reads a file consisting of 5 columns of numbers.
//We assume that we don't know the number of rows of that file. 
double **x,**t;    
int i,j,COL=5;

x=malloc(COL*sizeof(double*));
        for(i=0;i!=COL;i++){x[i]=calloc(1,sizeof(double));}

t=malloc(COL*sizeof(double*));

FILE *f;    
f=fopen("realloc2.dat","r");

j=0;
        for(;;){
                for(i=0;i!=COL-1;i++){
                        fscanf(f,"%lf, ",&x[i][j]);
                        t[i]=realloc(x[i],sizeof(x[i]+1));
                        x[i]=t[i];
                }
                fscanf(f,"%lf\n",&x[COL-1][j]);
                        if(feof(f)!=0){break;}
                t[COL-1]=realloc(x[COL-1],sizeof(x[COL-1]+1));
                x[COL-1]=t[COL-1];

                j++;
        }

for(i=0;i!=COL;i++){
        free(x[i]);
}
free(x);
free(t);
fclose(f);

return 0;
}

Output:

*** Error in `./realloc2_2': realloc(): invalid next size: 0x0000000001d9d040 ***
[...]
Segmentation fault

I have a file that has COL columns but we don't know how many rows it has, that's why I'm trying to use realloc(). I spend so much time trying to fix it... Could you help me?

Thank you.


Solution

  • fix like this:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void){
        double **x;
        int ROW = 5;//Provisional value
        int COL = 5;
        int c, r = 0, rows;
    
        FILE *fp = fopen("realloc2.dat","r");
        if(fp == NULL){
            perror("file can't open");
            exit(EXIT_FAILURE);
        }
    
        x = malloc(ROW * sizeof(double*));//malloc(ROW * sizeof(*x));
        for(;;++r){
            if(r == ROW){
                ROW += 5;//fitly size expansion. e.g ROW *= 2
                if((x = realloc(x, ROW * sizeof(*x))) == NULL){
                    perror("failed realloc");
                    exit(EXIT_FAILURE);
                }
            }
            if((x[r] = malloc(COL * sizeof(double))) == NULL){
                perror("failed malloc");
                exit(EXIT_FAILURE);
            }
            for(c = 0; c < COL; ++c){
                if(1 != fscanf(fp, "%lf", &x[r][c]))
                    goto readend;
            }
        }
    readend:
        rows = r;
        if(c != 0){
            puts("data are insufficient.");
        } else {
            //test print
            for(r = 0; r < rows; ++r){
                for(c = 0; c < COL; ++c){
                    if(c)
                        putchar(' ');
                    printf("%5.2f", x[r][c]);
                }
                puts("");
            }
        }
        fclose(fp);
        //deallocate
        for(r = 0; r <= rows; ++r){
            free(x[r]);
        }
        free(x);
    
        return 0;
    }