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:
But when I call setValues()
and set all values to the number 5, its prints counting up from the number 5 like this:
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');
}