Search code examples
carraysfgetsscanf

Reading a 2D array from a file in C


I'm attempting to create a program to read a 2D array from a file and then print it out.

The file is set out so that the first line has the number of rows and then the number of columns. After that the array is plotted. An example is as follows:

3 5
10.4 15.1 18.5 13.3 20.8
76.5 55.3 94.0 48.5 60.3
2.4 4.6 3.5 4.6 8.9

My problem is that i only know how to read the first element of each line using fgets and sscanf so the following numbers are ignored.

#include <stdio.h>
#include <string.h>

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

FILE* f = fopen("plottestdata", "r");
char size[20];
int height, width,ii=0,cc,jj,kk;
float array[100][100];
char horiz[500];

if(fgets(size, 20, f)!= NULL){

    sscanf(size,"%d %d", &height, &width);
    printf("%d %d\n",height, width);
}
while(fgets(horiz, 500, f)!=NULL)
{

    if(ii<height)
    {
        for(cc=0;cc<width;cc++)
        {
        sscanf(horiz, "%f", &array[ii][cc]);
        }
    ii++;
    }
}
for(jj=0;jj<width;jj++)
    {
        for(kk=0;kk<height;kk++)
        {
        printf("%f ", array[jj][kk]);
        }
    }
fclose(f);
return 0;
}

This gives me an output of the first element of each line repeated multiple times and I understand why but am unsure how to fix it. The file it is reading from is actually a 20x20 array although set out in the same format as the example.

Also, i have left out my error checking for the sake of trying to shortening a long question.


Solution

  • I could not resist tweaking and simplifying your code, it was so close, to avoid the use of fgets and use fscanf to read the values directly. Plus basic error checking.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MWIDTH  100
    #define MHEIGHT 100
    
    int main(void){
    
        FILE* f;
        int height, width, ii, jj;
        float array[MHEIGHT][MWIDTH];
    
        if((f = fopen("plottestdata.txt", "r")) == NULL)
            exit(1);
    
        if(fscanf(f, "%d%d", &height, &width) != 2)
            exit(1);
        if (height < 1 || height > MHEIGHT || width < 1 || width > MWIDTH)
            exit(1);
    
        for(jj=0; jj<height; jj++)
            for(ii=0; ii<width; ii++)
                if(fscanf(f, "%f", &array[jj][ii]) != 1)
                    exit(1);
        fclose(f);
    
        for(jj=0; jj<height; jj++){
            for(ii=0; ii<width; ii++)
                printf ("%10.1f", array[jj][ii]);
            printf("\n");
        }
        return 0;
    }
    

    Program output:

      10.4      15.1      18.5      13.3      20.8
      76.5      55.3      94.0      48.5      60.3
       2.4       4.6       3.5       4.6       8.9