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

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');
}

Related

Adding only row values of a matrix

int a[3][4], i, j;
int row_total;
printf("Enter matrix values : \n");
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 4; j++)
scanf("%d", &a[i][j]);
}
row_total *= a[i][j];
if (row_total > 0) {
printf("%d\n", row_total);
}
The matrix in the example has 3 rows and 4 columns. The values of this matrix are determined by the user. There are examples everywhere in the form of the product of 2 matrices. But I couldn't find how to process the values in rows of a single matrix. I need to multiply the values that the user enters for the row. How can I find the product of the values written in the rows of the matrix?
In the last part, I just tried to print the values to see if I could read the matrix multiplication of the code. But I could not read the values and get any multiplication result.
initialization
Always initialize your variables
because when you don't initialize it, it will have a "garbage" value.
You had problems reading the values because of the garbage value in row_total.
https://stackoverflow.com/a/1597426/17652416
Arrays
Pay attention that arrays start from 0 not 1 so if the amount of rows is 4 for
example, the rows will be - 0, 1, 2, 3 and not 1, 2, 3, 4.
So the iterations should start from i = 0; i < 4 and not i = 1; i <= 4.
More about arrays in C
Fixed initialization
Defines
#define ROWS 3
#define COLS 4
int a[ROWS][COLS] = { 0 };
int row = 0, col = 0;
int row_total = 1;
printf("Enter matrix values : \n");
//Get the values for the matrix from the user
for (row = 0; row < ROWS; row++)
{
for (col = 0; col < COLS; col++)
{
scanf("%d", &a[row][col]);
}
}
Iterating on the rows - the answer
//Print the product of every row
for (row = 0; row < ROWS; row++)
{
row_total = 1;
for (col = 0; col < COLS; col++)
{
row_total *= a[row][col];
}
printf("The product of row %d is: %d\n", row, row_total);
}

Setting values of a dynamically allocated array

I am trying to create and store values inside a matrix, represented as a 1 dimensional array.
When I try to set the values, my output comes out wrong.
Matrix Struct
struct matrix{
char matrixName[50];
int rows;
int columns;
float* data;
};
typedef struct matrix matrix_t;
matrix_t our_matrix[MAX_MATRICES];
Creating the matrix:
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 * data = (float *) malloc(rows * cols * sizeof(float));
int row = 0, col = 0;
for (row = 1; row <= rows; row++) {
for (col = 1; col <= cols; col++) {
data[(row-1) + (col-1) * cols] = 0;
}
}
strcpy(matrixP[matrixLocation].matrixName, tempName);
matrixP[matrixLocation].rows = rows;
matrixP[matrixLocation].columns = cols;
matrixP[matrixLocation].data = data;
return 0;
}
Setting Values:
int setValues(matrix_t* our_matrix, int number_of_matrices) {
int i, matrix_index;
for(i = 0; i < number_of_matrices; i++){
printf("Matrix %i\t %i Rows\t %i Columns - Name: %s\n", i+1, our_matrix[i].rows, our_matrix[i].columns, our_matrix[i].matrixName);
}
printf("\nWhich matrix would you like to set the values for?\n");
printf("Select a matrix number from the list above>\n");
scanf("%d", &matrix_index);
while(matrix_index < 1 || matrix_index > number_of_matrices){
printf("Enter a number from the list of available matrices - number must be greater than zero and less than or equal to the number of available matrices:\n");
scanf("%d", &matrix_index);
}
int max;
matrix_index -= 1;
max = our_matrix[matrix_index].columns;
float *data = our_matrix[matrix_index].data;
int row = 0, col = 0;
for (row = 0; row < our_matrix[matrix_index].rows; row++) {
for (col = 0; col < our_matrix[matrix_index].columns; col++) {
printf("Enter the value for column number %d of row number %d>\n", col+1, row+2);
scanf("%f", &data[(row) + (col) * (max)]);
}
/* separate rows by newlines */
}
our_matrix[matrix_index].data = data;
return 0;
}
When I try call setValues on a 5 x 2 matrix and I give it the values 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 these are the values that I get:
I honestly can't fathom how it stores those values and not the 1:10 that i'm passing it.
You have one little confusion in address computation: You inverted row ans col in multiplication.
You write (I replaced max by its value) in setValues
scanf("%f", &data[(row) + (col) * (our_matrix[matrix_index].columns)]);
the same in create_matrix function:
data[(row-1) + (col-1) * cols] = 0;
You should have written:
scanf("%f", &data[(col) + (row) * (our_matrix[matrix_index].columns)]);
and
data[(col-1) + (row-1) * cols] = 0;
You can do the math to be convinced:
If rows is 2 and cols is 10, with your method, the max index is 2 + 9 * 10 = 90, it's too big for a 2x10 matrix.
One more thing:
The function create_matrix can be simplified:
int create_matrix(matrix_t* matrixP, int matrixLocation){
int rows, cols;
printf("Enter a name for your matrix>\n");
/* Warning, you should test what scanf returned! */
scanf("%s", matrixP[matrixLocation].matrixName);
printf("Enter the number of rows>\n");
/* Warning, you should test what scanf returned! */
scanf("%d", &rows);
printf("Enter the number of cols>\n");
/* Warning, you should test what scanf returned! */
scanf("%d", &cols);
matrixP[matrixLocation].rows = rows;
matrixP[matrixLocation].cols = cols;
/* Warning, you should test what calloc returned! */
matrixP[matrixLocation].data = calloc(rows * cols, sizeof(float));
return 0;
}

How to access elements of a Matrix using loops

I have two 4x4 multidimensional arrays, and the rows and columns are marked as being A, B, C and D. When the user inputs the co-ordinates, the value of known_location_info selected is changed to the value of bomb_location_info. So for example, if AA was input then the value of [1][1] on known_location_info is changed to the value of [1][1] on bomb_location_info. At the moment I am only getting the first element to change regardless of what co-ordinates are entered. What is incorrect in my loop?
char inputRow;
char inputColumn;
char letterA = 'A';
void display(int known_location_info[][DIM], int size) {
printf(" A B C D\n");
for (int row = 0; row < DIM; row++) {
printf("%c", letterA);
letterA++;
for (int column = 0; column < DIM; column++) {
printf("%d ", known_location_info[row][column]);
}
printf("\n");
}
printf("Please select a row and column: ");
scanf("%c, %c", &inputRow, &inputColumn);
}
void update_known_info(int row, int col, int bomb_location_info[][DIM],
int known_location_info[][DIM]) {
for (inputRow = letterA; inputRow < DIM; inputRow++) {
for (inputColumn = letterA; inputColumn < DIM; inputColumn++) {
row++;
col++;
}
}
known_location_info[row][col] = bomb_location_info[row][col];
}
#include <stdio.h>
#include <assert.h>
#define DIM 4
void display(int known_location_info[][DIM]) {
printf(" A B C D\n");
for (int row = 0; row < DIM; ++row) {
printf("%c ", 'A' + row);
for (int column = 0; column < DIM; ++column)
printf("%2d ", known_location_info[row][column]);
putchar('\n');
}
printf("Please select a row and column: ");
char inputRow; char inputColumn;
if (scanf(" %c, %c", &inputRow, &inputColumn) != 2 ||
inputRow < 'A' || 'A' + DIM < inputRow ||
inputColumn < 'A' || 'A' + DIM < inputRow)
{
// handle input error
}
}
void update_known_info(char row, char col, int bomb_location_info[][DIM],
int known_location_info[][DIM])
{
row -= 'A';
col -= 'A';
assert(0 <= row && row < DIM && 0 <= col && col < DIM);
known_location_info[row][col] = bomb_location_info[row][col];
}
Access matrix using chars that scanned from the user is not a good idea. because every char is represented by an ASCII code. hence you will have an implicit offset of the ascii value of the letter (for example ASCII fo A = 64. in the other hand matrixes are like arrays. they are indexed starting from 0. you may retrieve the ascii offset before starting your loops..

For loop continues beyond limit (C language)

I'm trying to make a console application which displays the multiplication table multiplied by an integer. The integer is determined by the user.
It is written in C.
My problem is that if the user enters a value smaller than 10 or greater than 20, the app continues the nested 'for' loop beyond its determined limit (num + 10).
Otherwise it works fine.
#define _CRT_SECURE_NO_WARNINGS
#include `<stdio.h>`
void main()
{
int row, col, num; // Initialization of 10 x 10 array.
int arr[10][10];
printf("Enter a number: "); // User input of integer.
scanf("%d", &num);
for (row = num; row < num + 10; row++) /* Nested for loop. Loop starts at determined
number and stops ten steps further.*/
{
for (col = num; col < num + 10; col++)
{
arr[col][row] = row * col;
printf("%d\t", arr[col][row]);
}
printf("\n");
}
}
You are writing outside arr boundaries. Check your loop logic.
Since you want to multiply by numbers from 1 to 10, then you'll be better of with conditions like this:
for (row=0; row < 10; row++) {
for (col=0; col < 10; col++) {
arr[row][col] = (row+1)*(col+1);
printf("%d\t", arr[row][col]);
}
printf("\n");
}
Rearranging the condition inside the for loop will solve the problem.
the for loop condition will always satisfy for the input less than 10 and greater than 20
As has been stated you're overwriting the bounds of your array which will be overwriting part of the stack - this may be the portion that stores the num value.
Use different counters (i and j for indexing into array):
int main()
{
int row, col, num; // Initialization of 10 x 10 array.
int arr[10][10];
int i = 0;
int j;
printf("Enter a number: "); // User input of integer.
scanf("%d", &num);
for (row = num; row < num + 10; row++) /* Nested for loop. Loop starts at determined
number and stops ten steps further.*/
{
j = 0;
for (col = num; col < num + 10; col++)
{
arr[i][j] = row * col;
printf("%d\t", arr[i][j]);
j++;
}
i++;
printf("\n");
}
return 0;
}
Like Pablo said, you're writing out of your arr boundaries. arr[col][row] is out of bounds when either col or row is not in the range of 0 to 9. Maybe the easiest fix would be to replace this:
arr[col][row] = row * col;
printf("%d\t", arr[col][row]);
with just this line:
printf("%d\t", row * col);
You need to keep inside the limits of your array: arr
Suppose the user enters the value 50, your loop will iterate among 50 and 60, but your array has indexes from 0 to 9 (10 as the total). So, you can offset the indexes, subtracting the base: num
Example - the array offset:
int rowindex, colindex;
for (row = num; row < num + 10; row++) {
rowindex = row - num;
for (col = num; col < num + 10; col++) {
colindex = col - num;
arr[colindex][rowindex] = row * col;
printf("%d\t", arr[colindex][rowindex]);
}
printf("\n");
}
The array bounds for int arr[10][10]; require using index values from 0 to 9.
In addition to paying attention to array bounds in your nested for loops, (which you are currently violating) you should do something to verify user input before using it in the for loop:
printf("Enter a number from 0 to 9: "); // User input of integer.
scanf("%d", &num);
while((num < 0) || (num > 9))// legal array indices are 0 through 9
{
printf("%d is out of bounds, Enter another number: ", num);
scanf("%d", &num);
}
...

Filling two dimensional array C

#include <stdio.h>
int main()
{
//Variables
int x=0,y=0;
int my_data[7][7];
for (x=0;x<9;x++) {
printf("Enter rows:");
scanf("%i",&x);
// printf("%i\n",my_data[x][y]);
}
for(y=0;y<9;y++) {
printf("Enter columns: ");
scanf("%i", &y);
//printf("%i\n",my_data[x][y]);
}
for(y=0;y<9;y++) {
printf("%i\n",my_data[0][y]);
}
return 0; //Return process complete.
}
declares an 8X8 integer array my_data
prompts the user for data to fill the 8X8 array my_data
prints the sum of all the elements for each row
prints the sum of all the elements in the 8X8 array
prints the sum of all the elements in the diagonal of the 8x8 array.
What did I do wrong? When I enter 1,2,3,4,5,6,7,8; 1,2,3,4,5,6,7,8
I get back:
3612392
2686632
1966142592
3604480
0
1966142601
1825884643
4
3612396
Several issues right away:
The array is 7x7, you want it to be int my_data[8][8];
Instead of using the number for the size of the array over and over, define a constant #define FOO 8
The loops are not properly bounded, should be for (x=0;x<8;x++). (again, see my note on using a defined constant for the size)
You are not saving the value to the array, you are saving it to the iterator variable.
With two separate for loops you will not be able to fill the entire table, reconsider this structure because you will likely have to use nested loops.
You can use one loop nested in the other:
#define SIZE 8
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
printf("(%d,%d): ", i+1, j+1);
scanf("%d", &value);
array[i][j] = value;
}
}
for (x=0;x<9;x++) {
printf("Enter rows:");
scanf("%i",&x);
// printf("%i\n",my_data[x][y]);
}
What happens here is that you change the value of x. You do not save anything on the array.
Similarly for y
Also you should iterate from 0 to 6 (inclusive)
Try
int i;
for(i = 0 ; i < 7 ; i++)
{
scanf("%d" , &my_data[0][x]);
}
Or :
int row , col;
for (row=0; row<7; row++)
{
for (col=0; col<7; col++)
{
scanf("%d" , &ticTacToeBoard[row][col]);
}
}
What you see is the values that your array has when it was declared. The reason for that is when you declare a variable in C without initializing it, as in your case, your program just uses enough memory to store your data into the memory but does not set that memory to 0, hence seeing what the contents of the memory are from previous usage.
int my_data[7][7]; is a 7 x 7 array. Use int my_data[8][8]; for 8 x 8.
my_data is an array with space for 49 int, not 64!
In your for loops you are changing the loop control variable itself by using scanf with its address!
I think you want:
#include <stdio.h>
#define ROWS 8
#define COLUMNS 8
int main(void) {
int my_data[ROWS][COLUMNS];
int rows[ROWS];
int cols[COLUMNS];
size_t i, row, col;
/* input rows */
printf("Enter rows: ");
fflush(stdout);
for (i = 0; i < ROWS; i++) scanf("%d", &rows[i]);
/* input columns */
printf("Enter cols: ");
fflush(stdout);
for (i = 0; i < COLUMNS; i++) scanf("%d", &cols[i]);
/* calculate sums */
for (row = 0; row < ROWS; row++) {
for (col = 0; col < COLUMNS; col++) {
my_data[row][col] = rows[row] + cols[col];
}
}
/* print results */
for (row = 0; row < ROWS; row++) {
for (col = 0; col < COLUMNS; col++) {
printf("%d ", my_data[row][col]);
}
puts("");
}
return 0;
}

Resources