2

I'm working on a program that reads 5x5 matrix from .dat file, performs few tasks and saves outputs of those tasks to separate files. At the moment I've got two functions. One for reading from file and displaying values in console. And one for saving values in a file.

My problem is that those two work fine when I put them in main, but when I call them as functions only read_matrix() goes correct and write_matrix() just creates blank Result.dat. I figured it's because when they're all in main, after reading the matrix all values are in memory and can be written to the file. And when I call them as functions, write_matrix doesn't have any values in A[] and gives me nothing. I've tried creating another array to hold those values, messing with pointers (I'm not very familiar with them), but nothing worked and I'm out of ideas.

  1. How do I fix it? How do I pass entire array of values from first function to the other one?

  2. How could I make program determine dimensions. Matrix I have to work with is 5x5, but I'd like to be able to use this program with other sizes. Currently I prompt user to input height and width, but it's far from perfect, if I input incorrect dimensions output is wrong.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int read_matrix(FILE * fin, int ** A, int x, int y) {
  fin = fopen("mat_A.dat", "r");
  if (fin == NULL)
    printf("Error opening input file.  \n");

  else {
    printf("Number of columns:\n");
    scanf("%d", & x);
    printf("Number of rows:\n");
    scanf("%d", & y);
    // Read the matrix dimensions
    int ** A = (int ** ) malloc(sizeof(int * ) * x);
    for (int i = 0; i < x; i++) {
      for (int j = 0; j < y; j++) {
        A[i] = (int * ) malloc(sizeof(int) * y);
      }
    }

    // Allocate the memory
    for (int i = 0; i < x; i++) {
      for (int j = 0; j < y; j++) {
        fscanf(fin, "%d", & A[i][j]);
        printf("%d   ", A[i][j]);
      }
      printf("\n");
    }

    fclose(fin);
  }
}

int write_matrix(FILE * fout, int ** A, int x, int y) {
  fout = fopen("Result.dat", "w");
  // fprintf( fout, "%d %d \n", x, y );

  for (int i = 0; i < x; i++) {
    for (int j = 0; j < y; j++) {
      fprintf(fout, "%d ", A[i][j]);
    }
    fprintf(fout, "\n");
  }
  fclose(fout);
}

int main() {
  /*  declaration of variables  */
  int x,
      y,
      i = 0, 
      **A;
      FILE * fin,
           * fout;

  read_matrix(fin, A, x, y);

  write_matrix(fout, A, x, y);

  printf("\n\nlul");
  free(A);
  return 0;
}```
5
  • 3
    The pointer A in read_matrix is a local copy. Changing A in read_matrix has no effect on the pointer A in main. You either need to pass the address of A to read_matrix, or return the new value of A from read_matrix and assign it to A in main. Commented Jan 20, 2021 at 22:17
  • 1
    you should use &A or return a int ** from read_matrix Commented Jan 20, 2021 at 22:17
  • 1
    int ** A = (int ** ) malloc(sizeof(int * ) * x); hides the read_matrix function's second parameter int **A. Commented Jan 20, 2021 at 22:39
  • Please post an minimal reproducible example. Commented Jan 20, 2021 at 22:40
  • Thank you @user3386109. You set me on the right track and I found a solution. I don't know how to give you dem reputation points, but thank you. Commented Jan 21, 2021 at 16:24

1 Answer 1

1

I found a solution that returns Result.txt with values inside. In my original code not only I wasn't giving write_matrix() any values, but I also wasn't giving it any dimensions. Here's what I did to get my text file with matrix inside.

  1. In 1st function I added return A; at the end.
  2. I moved asking user for dimensions from 1st function to main. That way they're not lost after 1st function ends.
  3. In main I created another int **B pointer.
  4. I used that pointer when calling 1st function and then used it as an argument when calling second function.

Here's how write_matrix() and main() look after changes.

int **read_matrix(int x, int y)
{
    int ** A = NULL;
    FILE * fin = fopen("mat_A.dat", "r");

    ...

        fclose(fin);
    }
    return A;
}

void write_matrix (int **B, int x, int y)
{
    FILE *fout = fopen( "Result.txt", "w" );

    for( int i = 0; i < x; i++ )
    {
        for( int j = 0; j < y; j++ )
        {
            fprintf( fout, "%d ", B[ i ][ j ] );
        }
        fprintf( fout, "\n" );
    }
    fclose( fout );
}

int main(void)
{
    /*  deklaracja i inicjalizacja zmiennych  */
    int x, y;
    int **B;

    printf("Number of columns:\n");
    scanf("%d", &x );
    printf("Number of rows:\n");
    scanf("%d", &y );
    printf("\n");

    B = read_matrix (x, y);

    if (B != NULL)
        write_matrix (B, x, y);

    printf("\n\nlul");
    free(B);
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is a good step forward. Well done. However, there is a flaw. The variable A in main is not initialized. The read_matrix function doesn't change that. So the line free(A) is not valid. If you're lucky A will be 0, and free(A) will do nothing. If you're unlucky, the line free(A) will cause the program to crash.
The easiest way for me to show how to fix the issue is by editing the answer. You can view the edit history to see the changes. In summary, the read_matrix function doesn't need A as a parameter. It can simply declare A as a local variable. And main doesn't need A at all. The same is true for fin and fout.

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.