0

So, I am trying to read a matrix from a file and store it into an array.

The matrix files are as follows:

2 3
1 5 8
6 3 9

With the first two digits on the first line representing Rows x Columns.

I seem to be getting an issue whenever I try to store something into my array, as I am able to simply reprint everything to the screen, but I when I try to reprint, I get different values than intended.

My code is as follows:

double *read_matrix(char *filename){
    FILE *file=fopen(filename, "r");

    if(!file){
        fprintf(stderr, "An error has occurred. Wrong file name?\n");
        exit(errno);
    }
    double *data=malloc(4096*sizeof *data);
    char *buff=malloc(256*sizeof *buff);
    char *curr;
    char *save;
    while(fgets(buff,sizeof(buff),file)){
        curr=strtok_r(buff," ",&save);
        int i=0;
        while(curr!=NULL){

            if(curr==NULL){
               perror("curr is null");
            }
            data[i]=strtod(curr,NULL);
            curr=strtok_r(NULL," ",&save);
            i++;
        }
    }
    free(buff);
    return data;
}

Whenever I run this and try to print the first two values of my array I get the following for my rows and columns:

A: 0.000000 | -1.000000

I am having troubles understanding what I have done wrong, if it's not one problem it's another!

I'm not sure if it helps, but below you can find the method that calls read_matrix():

void executemm(char *file1, char *file2)
{
    double *matrixA = read_matrix("matrix1");
    printf("A: %f | %f\n", matrixA[0], matrixA[1]);
}

All it does is specify the file to read from, and then display the first two elements of the returned array (which should be the dimensions).

EDIT: Update to code block, and updated actual output

EDIT 2: Again, updating code block, and updated actual output

backward forward
  • 429
  • 3
  • 17
  • `,&buff` as your last argument to `strtok_r` is wrong. That pointer is a *context* pointer that should be managed apart from `buff`. Read [the man page](https://linux.die.net/man/3/strtok_r) carefully. – WhozCraig Sep 15 '20 at 19:44
  • buff should be freed before returning, else it is a leak. – stark Sep 15 '20 at 19:48
  • On that unrelated node, it's also ironic that in consecutive lines of code you both cast, and don't cast, `malloc` results. [The latter is preferred in C programs](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc), as the former can subtly hide otherwise-obvious issues. – WhozCraig Sep 15 '20 at 19:52
  • Post-edit: You *still* need a context pointer. You can't double-duty `curr` or `buff`. Your `buff` points to your data buffer, your `curr` points to the current token. A `*third* pointer (call it `ctx` if you like) is needed for managing `strtok_r` context. – WhozCraig Sep 15 '20 at 19:55
  • https://stackoverflow.com/a/15961298/1216776 – stark Sep 15 '20 at 19:55
  • Ah! So I did make some updates to the code, that both fix my save pointer to the char* that I am wanting to store individual tokens in, as well as freeing buff at the end. This helped me understand better where my -1 was coming from in expected output, and also fixed a seg fault error that I was only getting on my local machine vs no issues on a large server. I still am yielding 0 values for my dimensions, however this did solve an issue I would likely have come across in the near future. – backward forward Sep 15 '20 at 19:56
  • You still have the `sizeof(char *)` error commented in the previous question although the over-measure is in your favour. You can avoid such slips by using the type pointed to, e.g. `char *buff = malloc(sizeof *buff * 256);` – Weather Vane Sep 15 '20 at 19:58
  • @WhozCraig I see, I had thought savptr was a place holder for strtok_r to have access to where curr is stored. – backward forward Sep 15 '20 at 19:58
  • Should my third pointer be assigned any value before using it within strtok_r? – backward forward Sep 15 '20 at 20:00
  • @backwardforward Not required, but I never like indeterminate *anything* in my programs. Regardless, [this question](https://stackoverflow.com/questions/15961253/c-correct-usage-of-strtok-r) is probably the simplest answer you're going to find on proper use of `strtok_r`. – WhozCraig Sep 15 '20 at 20:06

0 Answers0