Using scanf() with a pointer to a double pointer - c

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}

There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}

Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

i have problem with acessing 2d array via function

i am learning pointers and i write these code to add two martix via function, it compile well and give correct answer for 2x2 matrix but for more than two row and col it fails when i try it with 3x3 matrix [0][0] element for the first matrix it automaticaly become 6 and [1][0] it became 9 every time, i can't figure out why this happen
#include <stdio.h>
//-----------------Function------------------
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c);
void get(int (*p1)[10], int r, int c);
void print(int (*p1)[10], int r, int c);
//---------------Main Program----------------
int main()
{
//declartion
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(m1, r, c);
print(m1, r, c);
printf("\n\tenter the element of second matrix\n\t");
get(m2, r, c);
print(m2, r, c);
add(m1, m2, m3, r, c);
printf("\n");
print(m3, r, c);
return(0);
}
//-------------Define Function---------------
//get()
void get(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n\t");
for(j = 0; j < c; j++)
{
scanf("%d", (*(p1+i)+j));
}
}
}
//--------------------X----------------------
//add()
void add(int (*p1)[10], int (*p2)[10], int (*p3)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
//printf("\n%d %d = %d & %d", i, j, *(*(p1+i)+j), *(*(p2+i)+j));
*(*(p3+i)+j) = *(*(p1+i)+j) + *(*(p2+i)+j);
}
}
}
//--------------------X----------------------
//print()
void print(int (*p1)[10], int r, int c)
{
int i, j;
for(i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
{
printf("\t%d", *(*(p1+i)+j));
}
}
}
//--------------------X----------------------
Drop the array pointer notation and the fixed size. Use variable-length arrays based on the parameters.
Remove useless comments like // get ... void get...
Don't use unreadable de-referncing with *(arr+i) when you could be writing readable arr[i].
Print new line after each row, not before each row.
Here's a cleaned up program which compiles. I haven't tested it.
#include <stdio.h>
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c]);
void get (int r, int c, int p1[r][c]);
void print (int r, int c, int p1[r][c]);
int main (void)
{
int i, j, r, c;
printf("\n\tenter the row and column of matrix\n\t");
scanf("%d %d", &r, &c);
int m1[r][c], m2[r][c], m3[r][c];
printf("\n\tenter the element of first matrix\n\t");
get(r, c, m1);
print(r, c, m1);
printf("\n\tenter the element of second matrix\n\t");
get(r, c, m2);
print(r, c, m2);
add(r, c, m1, m2, m3);
printf("\n");
print(r, c, m3);
return(0);
}
void get (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
scanf("%d", &p1[i][j]);
}
}
}
void add (int r, int c, int p1[r][c], int p2[r][c], int p3[r][c])
{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
p3[i][j] = p1[i][j] + p2[i][j];
}
}
}
void print (int r, int c, int p1[r][c])
{
for(int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
printf("\t%d", p1[i][j]);
}
printf("\n");
}
}

Why can't I print out this matrix/2D array?

I am trying to type in a matrix and then print it, using functions.
The program crashes when it gets to the read_mat function. What am I getting wrong?
#include <stdio.h>
#include <stdlib.h>
int** insert_mat(int **mat, int r, int c);
int** read_mat(int** mat, int r, int c)
{
mat = (int**)calloc(r,sizeof(int*));
for (int i=0; i<r; i++)
{
mat[i]=(int*)calloc(c,sizeof(int));
}
insert_mat(mat, r, c);
return mat;
}
int** insert_mat(int **mat, int r, int c)
{
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
printf("\nmat[%d][%d] = ",i , j);
scanf("%d", &mat[i][j]);
}
}
return mat;
}
void print_mat(int **mat, int r, int c)
{
printf("\n");
for (int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
printf("%d ",mat[i][j]);
}
printf("\n");
}
}
int main()
{
int **mat;
int r1 =2;
int c1 = 2;
read_mat(mat, r1, c1);
print_mat(mat, r1, c1);
return 0;
}
I also tried printing elements of mat in main (ex: printf("%d", mat[0][0]);) and it is also not working. So maybe the error is when I insert the elements? But I am not sure what I do wrong.

how to store multiple arrays and make array of pointers to them

I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())

Passing a matrix in a function (C)

I have an issue passing a matrix to a function in C. There is the function I want to create:
void ins (int *matrix, int row, int column);
but I noticed that in contrast to the vectors, matrix give me an error. How can I pass my matrix to a function so?
EDIT --> there is the code:
// Matrix
#include <stdio.h>
#define SIZE 100
void ins (int *matrix, int row, int column);
void print (int *matrix, int row, int column);
int main ()
{
int mat[SIZE][SIZE];
int row, col;
printf("Input rows: ");
scanf ("%d", &row);
printf("Input columns: ");
scanf ("%d", &col);
printf ("Input data: \n");
ins(mat, row, col);
printf ("You entered: ");
print(mat, row, col);
return 0;
}
void ins (int *matrix, int row, int column);
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
printf ("Row %d column %d: ", i+1, j+1);
scanf ("%d", &matrix[i][j]);
}
}
}
void print (int *matrix, int row, int column)
{
int i;
int j;
for(i=0; i<row; i++)
{
for(j=0; j<column; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
You need to pass a pointer with as much levels of indirection (*) as the number of dimensions of your matrix.
For example, if your matrix is 2D (e.g. 10 by 100), then:
void ins (int **matrix, int row, int column);
If you have a fixed dimension (e.g. 100), you can also do:
void ins (int (*matrix)[100], int row, int column);
or in your case:
void ins (int (*matrix)[SIZE], int row, int column);
If both your dimensions are fixed:
void ins (int matrix[10][100], int row, int column);
or in your case:
void ins (int matrix[SIZE][SIZE], int row, int column);
If you have a modern C compiler you can do the following for 2D matrices of any sizes
void ins (size_t rows, size_t columns, int matrix[rows][columns]);
Important is that the sizes come before the matrix, such that they are known, there.
Inside your function you then can access the elements easily as matrix[i][j] and the compiler is doing all the index calculations for you.
it would also possible to leave the first dimension empty, the same as (*matrix):
void ins (int matrix[][100], int row, int column);
Much better way to use malloc function and create dynamically allocated array and do whatever you want to do using 2d array:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
void fun(int **arr,int m,int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arr[i][j]);
}
}
}
int main()
{
int i,j,m,n;
printf("enter order of matrix(m*n)");
scanf("%d*%d",&m,&n);
int **a=(int **)malloc(m*sizeof(int));
for(i=0;i<n;i++)
a[i]=(int *)malloc(n*sizeof(int));
fun(a,m,n);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
output:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
void fun(int **arr,int m,int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arr[i][j]);
}
}
}
int main()
{
int i,j,m,n;
printf("enter order of matrix(m*n)");
scanf("%d*%d",&m,&n);
int **a=(int **)malloc(m*sizeof(int));
for(i=0;i<n;i++)
a[i]=(int *)malloc(n*sizeof(int));
fun(a,m,n);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
You can try this as well:
void inputmat(int r,int c,int arr[r * sizeof(int)][c * sizeof(int)])

Resources