3

I've got a file which I need to store in a 2-D array so I can perform matrix operations on it. All I know is that the doubles will be separated by spaces and line breaks, e.g:

2.04 3.0 4.0
5.0 6.1 7.0
8.0 9.03 10.0

I won't know how many numbers there will be, so I need a scalable parsing function. So far I have:

int main(int argc, char* argv[])
{
    FILE *fp;
    char ch;
    fp = fopen("matrix.dat","r");
    if ( fp == NULL )
    {
        puts ( "Cannot open source file");
    }

    /*count the number of lines*/
    int lines=1;
    char c;
    while((c = fgetc(fp)) != EOF)
    {
        if(c == '\n')
            lines++;
    }
    printf("lines= %i\n",lines);

    /*reopen the file to reset the pointer*/
    fclose(fp);
    fp = fopen("matrix.dat","r");
    double m[lines][lines];

    /*Load file into array*/
    int i,j;
    for(i=0;i<lines;i++)
    {
        for(j=0;j<lines;j++)
        {
            fscanf( fp, "%lf", &(m[i][j]));
        }
        fscanf(fp, "\n", NULL);
    }

    /*print out stored matrix*/
    for(i=0;i<lines;i++)
    {
        for(j=0;j<lines;j++)
        {
            printf("%lf ",m[i][j]);
        }
        printf("\n");
    }
}

My issues with this method are

  1. It makes the assumption that the number of rows equals the number of doubles per line, which may not be true.**

  2. Any missing doubles in the file will cause the program to load the wrong matrix into memory (remaining values offset by 1).

  3. I'm currently loading the file into memory twice to count the lines.

Is there a more sensible way to input this data into a 2D array? I need to ensure that the input matrix is square and that my program can handle a square matrix of any order. I'm quite new to C, so examples and naming functions will be much appreciated :) (Apologies for the dodgy indenting)

** Sorry for being so vague, I wanted some error handling, i.e making sure the input is not accepted unless there are exactly nxn doubles.

2
  • When you say that your matrix is square, then you have for sure that you'll always receive n^2 numbers? But you are unsure if they are evenly distributed along lines? Commented Nov 23, 2011 at 18:02
  • The numbers are supposed to be formatted in the example, and the program calculates the inverse of the matrix, so if the matrix in the file is not square then the program should exit, as there is nothing left to do. The numbers should be evenly distributed, but I want to make sure the program doesn't accept anything that isn't nxn. If one line has n-1 numbers then I don't want the program to treat the missing number as 0, it should terminate instead. Commented Nov 23, 2011 at 18:17

2 Answers 2

4

Like Nicolas, I'm curious what you mean by point (1)...if the matrix is square, then won't the number of rows always equal the number of doubles per line? If not, then I suppose you could look through the file for the row with the most values.

Here's your code modified to do that:

/* count the number of lines */
int lines = 1;
int maxValues = 0;
int count = 0;
char junk;
while((junk == fgetc(fp)) != EOF) {
    if(junk == '\n') {
        lines++
        if(maxValues <= count) {
            maxValues = ++count;
        }
        count = 0;
    }
    else if(junk == 0x20) {
        count++;
    }
}

To address point (2), maybe try this modification:

/* load file into array */
int i, j;
for(i = 0; i < lines; i++) {
    j = 0;
    do {
        fscanf(fp, "%lf", &(m[i][j]));
        j++;
    } while((junk = fgetc(fp)) != '\n');
}

Finally for point (3), I'm pretty sure you can use rewind(fp); to reset the pointer to the beginning of the file.

Sign up to request clarification or add additional context in comments.

Comments

0
  • read the first line with fgets
  • count the values, let's say they're n
  • make an array of n * n
  • read n - 1 lines of n values each
  • calculate the inverse

Voila!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.