Search code examples
carraysmatrixstructansi-c

C - Printing elements of a 2d array inside a struct array


Im trying to make a function that sets the values of a 2D array, and then another function that prints those values.

For some reason, with my current implementation, if I create a 3x3 matrix and I set every value to the number 5, it prints the values, but it prints them counting up from 5, so it prints 567, 678, 789, when instead I want it to print the exact value that I set.

Here are the function definitions - what am I doing wrong?:

Struct Definition:

    struct matrix{
        char matrixName[50];
        int rows;
        int columns;
        float* data;
    };
    typedef struct matrix matrix_t;

Matrix Creation:

int create_matrix(matrix_t* matrixP, int matrixLocation){

  char tempName[50];
  int rows, cols;


  printf("Enter a name for your matrix>\n");
  scanf("%s", tempName);

  printf("Enter the number of rows>\n");
  scanf("%d", &rows);

  printf("Enter the number of cols>\n");
  scanf("%d", &cols);

  float * our_matrix = (float *) malloc(rows * cols * sizeof(float));  

  strcpy(matrixP[matrixLocation].matrixName, tempName);
  matrixP[matrixLocation].rows = rows;
  matrixP[matrixLocation].columns = cols;
  matrixP[matrixLocation].data = our_matrix;

  return 0;

}

Set Values:

int setValues(matrix_t* our_matrix, int matrix_index) {
  int counter = 0;
  int row = 0, col = 0;
  for (col = 1; col <= our_matrix[matrix_index].columns; col++) {
    for (row = 1; row <= our_matrix[matrix_index].rows; row++) {
      counter++;

      printf("Enter the value for column number %d of row number %d>\n", col, row);
      scanf("%f", our_matrix[matrix_index].data+(col-1)+(row-1));                
    }
    /* separate rows by newlines */
  }
    return 0;
}

Print:

int printMatrix(matrix_t* our_matrix, int index) {
      int row = 0, col = 0;
      for (col = 1; col <= our_matrix[index].columns; col++) {
        for (row = 1; row <= our_matrix[index].rows; row++) {
      printf(" %2.f ", *our_matrix[index].data+(col-1)+(row-1));   
    }
    printf("\n");
  }
    return 0;
}

If I call the printMatrix() function without first using setValues, it seems to print the relative position of the cell that it's printing like so:

enter image description here

But when I call setValues() and set all values to the number 5, its prints counting up from the number 5 like this:

enter image description here


Solution

  • Your position calculation is incorrect. There's one problem and one 'aconventional notation' issue.

    The problem is the calculation of the array subscripts:

    scanf("%f", our_matrix[matrix_index].data+(col-1)+(row-1));
    printf(" %2.f ", *our_matrix[index].data+(col-1)+(row-1));
    

    You need to multiply the (row - 1) value by our_matrix[matrix_index].cols. You will probably do better with some shorter names for the values:

    int max_col = our_matrix[matrix_index].columns;
    int max_row = our_matrix[matrix_index].rows;
    float *data = our_matrix[matrix_index].data;
    
    for (col = 1; col <= max_col; col++)
    {
        for (row = 1; row <= max_row; row++)
        {
            printf("Enter the value for column number %d of row number %d>\n", col, row);
            if (scanf("%f", data + (col-1) + (row-1) * max_col) != 1)
            {
                …report error and do not continue…
            }
        }
    }
    
    for (col = 1; col <= max_col; col++)
    {
        for (row = 1; row <= max_row; row++)
            printf(" %.2f", data[(col-1) + (row-1) * max_col]);
        putchar('\n');
    }
    

    That deals with the substantive bug. Note the error checking on scanf(). That is important in 'real world' programs (even if you get away without it in classes or in online contests). You could sensibly use the notation &data[(col-1) + (row-1) * max_cols] in place of data + (col-1) + (row-1) * max_cols in the call to scanf() too — that would improve the consistency of the code.

    The 'aconventional notation' issue is that in C, array indexing starts at 0, not 1, and you could avoid the multitude of -1 terms by following the C conventions. This snippet also declares the loop variables when they're needed, minimizing their scope. This is a feature of C since C99 — it may not be available to you on some retrograde (but popular and widespread) platforms.

    for (int col = 0; col < max_col; col++)
    {
        for (int row = 0; row < max_row; row++)
            printf(" %.2f", data[col + row * max_col]);
        putchar('\n');
    }