Cannot modify a matrix element's value with a function - c

i'm trying to create a function that sets to 0 the value of every matrix element a[i][j] which is divisible by both i and j. I tried to do it this way but the program just "exits" without giving any error or warning after the matrix=editMat(matrix, nrows, ncols); line.
#include <stdio.h>
#include <stdlib.h>
FILE *openFileR(const char *);
int rows(FILE *);
int cols(FILE *);
int **readMat(FILE *, int **);
int **allocMat(int, int);
void printMat(int **, int, int);
int **editMat(int, int, int**);
int main()
{
FILE *fp, *fpout;
fp=openFileR("matrixmag.txt");
int nrows=rows(fp); int ncols=cols(fp);
int **matrix=allocMat(nrows, ncols);
readMat(fp, matrix);
printMat(matrix, nrows, ncols);
matrix=editMat(nrows, ncols, matrix);
printMat(matrix, nrows, ncols);
return 0;
}
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
int **readMat(FILE *fp, int **matrix)
{
int value, row, col;
while(fscanf(fp, "%d %d %d", &value, &row, &col)!=EOF)
{
matrix[row][col]=value;
}
return matrix;
}
int **allocMat(int nrows, int ncols)
{
int **matrix=malloc(nrows*(sizeof(int *)));
for(int i=0; i<nrows; i++)
{
matrix[i]=malloc(ncols*sizeof(int));
}
return matrix;
}
void printMat(int **matrix, int nrows, int ncols)
{
for(int i=0; i<nrows; i++)
{
for(int j=0; j<ncols; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int cols(FILE *fp)
{
int columns;
fscanf(fp, "%d", &columns);
printf("Columns:%d\n", columns);
return columns;
}
int rows(FILE *fp)
{
int lines;
fscanf(fp,"%d", &lines);
printf("Rows:%d\n", lines);
return lines;
}
FILE *openFileR(const char *nome_file)
{
FILE *fp;
printf("File name: %s\n", nome_file);
fp=fopen(nome_file, "r");
if(fp==NULL)
{
printf("Couldn't open file\n");
exit(-1);
}
else
printf("File correctly opened\n");
return fp;
}
Input file is
3 3
2 0 0
7 0 1
6 0 2
9 1 0
5 1 1
1 1 2
4 2 0
3 2 1
8 2 2
sorry about the errors, i didn't check what i wrote before

Just figured out i was trying to divide a number by 0, since i and j were both initialized to 0
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
This way it works fine
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=1; i<nrows; i++)
{
for(j=1; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
Thanks everybody for the help anyway :)

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.

VSCode doesn't show all warnings/errors

I have this code:
#include <stdio.h>
#include <stdlib.h>
FILE *openFile(char const * , char const *);
int readDim(FILE *);
double **allocMatrix(int , int );
void printMatrix(int , int , double **);
void readMatrix(FILE *, int , int , double **);
void mediana(int , int , double **);
void printVect(int , double *);
FILE* openFile(char const* file_name, char const* mode)
{
FILE* fp = fopen(file_name, mode);
printf("File name: %s\n", file_name);
if (fp == NULL)
{
perror(file_name);
exit(EXIT_FAILURE);
}
else
printf("File read correctly\n");
return fp;
}
int main()
{
FILE *fp=openFile("matrice.txt", "r");
int nrows=readDim(fp), ncols=readDim(fp);
printf("Rows: %d\tColumns: %d\n", nrows, ncols);
double **matrix=allocMatrix(nrows, ncols);
readMatrix(fp,nrows, ncols, matrix);
printMatrix(nrows, ncols, matrix);
mediana(nrows, ncols, matrix);
return 0;
}
void mediana(int nrows, int ncols, double **matrix)
{
int i, col=0;
double temp;
double *row=calloc(ncols, sizeof(double));
for(i=0; i<ncols; i++)
{
row[i]=matrix[i][col];
}
printVect(ncols, row);
/* for(i=0; i<ncols; i++)
{
if(row[i]>row[i+1])
{
row[i]=temp;
row[i]=row[i+1];
row[i+1]=temp;
}
}
printVect(ncols, row);*/
}
void printVect(int ncols, double *row)
{
int i;
printf("Vector:\n");
for(i=0; i<ncols; i++)
{
printf("%lf", row[i]);
}
}
void readMatrix(FILE *fp, int nrows, int ncols, double **matrix)
{
int i, j;
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
fscanf(fp, "%lf", &matrix[i][j]);
}
}
}
void printMatrix(int nrows, int ncols, double **matrix)
{
int i, j;
printf("Matrix:\n");
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
printf("%.4lf\t", matrix[i][j]);
}
printf("\n");
}
}
double **allocMatrix(int nrows, int ncols)
{
int i;
double **matrix;
matrix=calloc(nrows, sizeof(double));
for(i=0; i<nrows; i++)
{
matrix[i]=calloc(ncols, sizeof(double));
}
if(matrix==NULL)
{
perror("matrix");
}
else
printf("Memory allocated correctly\n");
return matrix;
}
int readDim(FILE *fp)
{
int num;
fscanf(fp, "%d", &num);
return num;
}
I am sure there is some sort of error because the output i get from VSCode is:
File name: matrice.txt
File read correctly
Rows: 6 Columns: 8
Memory allocated correctly
Matrix:
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 0.6948 0.7655
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 0.3171 0.7952
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 0.9502 0.1869
0.9134 0.9649 0.1419 0.0357 0.3922 0.0462 0.0344 0.4898
0.6324 0.1576 0.4218 0.8491 0.6555 0.0971 0.4387 0.4456
0.0975 0.9706 0.9157 0.9340 0.1712 0.8235 0.3816 0.6463
TL;DR
Everything is fine until the program has to execute the "mediana" function, I think the error is row[i]=matrix[i][col]; but the compiler doensn't show any error or warning, what should I do?
Input file:
6 8
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 0.6948 0.7655
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 0.3171 0.7952
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 0.9502 0.1869
0.9134 0.9649 0.1419 0.0357 0.3922 0.0462 0.0344 0.4898
0.6324 0.1576 0.4218 0.8491 0.6555 0.0971 0.4387 0.4456
0.0975 0.9706 0.9157 0.9340 0.1712 0.8235 0.3816 0.6463
The problem is here:
row[i] = matrix[i][col];
which should rather be:
row[i] = matrix[col][i];
You mixed up something.
You also should free the memory at the end of mediana with:
free(row);
BTW if you run your code with your debugger (don't ask me how to do this on your platform), your program would most likely have crashed into the debugger showing you the exact line where the crash happended.

pass matrix by reference and scan values

I'm trying to scan values into a matrix that is passed by reference to a function and that's not compiled.
What's wrong?
I think the problem is in line of scanf but I don't know how to fix it.
#include <stdio.h>
#include <stdlib.h>
int** initMatrix(int lines, int columns) {
int i;
int** matrix;
matrix = (int**) calloc(lines, sizeof(int*));
for (i = 0; i < lines; i++) {
matrix[i] = (int*) calloc(columns, sizeof(int));
}
return matrix;
}
void fillMatrixValues(int*** matrixA, int lines, int columns) {
int i, j;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
scanf("%d", matrixA[i][j]);
}
}
}
void printMatrix(int** matrix, int lines, int columns) {
int i, j;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
void main() {
int** matrixA;
int lines = 2, columns = 2;
matrixA = initMatrix(lines, columns);
fillMatrixValues(&matrixA, lines, columns);
printMatrix(matrixA, lines, columns);
}
void main -> undefined behaviour
Use
int main(void)
or
int main(int argc, char ** argv)
You should check return value of scanf
if (scanf("%d", matrixA[i][j]) != 1)
{
// failed
}
Next problem
void fillMatrixValues(int ***matrixA, int lines, int columns)
fillMatrixValues(&matrixA, lines, columns)
to
void fillMatrixValues(int **matrixA, int lines, int columns)
fillMatrixValues(matrixA, lines, columns)

Function to find average for array

Did I implement float overallavg(float* matrix, int rows, int cols)correctly? I think I didn't. I'm trying to return the average value of the elements of the array pointed to by matrix. Should I call the other two functions into the overall one and then divide by the total number elements in the array?
#include <stdio.h>
#include <stdlib.h>
float *readMatrix(int rows, int cols);
float *rowavg(float *matrix, int rows, int cols);
float *colavg(float *matrix, int rows, int cols);
float overallavg(float* matrix, int rows, int cols);
void printavg(float *matrix, float *rowAve, float *colAve, float overallAve, int rows, int cols);
#define MAX_DIM 10
int main(void)
{
int done = 0;
int rows, cols;
float *dataMatrix;
float *rowAveVector;
float *colAveVector;
float overallAve;
while (!done)
{
// Prompt user to enter row and column dimensions of matrix (must be > 0)
do
{
printf("Enter row dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &rows);
} while(rows <= 0 || rows > MAX_DIM);
do
{
printf("Enter column dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &cols);
} while(cols <= 0 || cols > MAX_DIM);
dataMatrix = readMatrix(rows, cols);
if (dataMatrix == NULL)
{
printf ("Program terminated due to dynamic memory allocation failure\n");
return (0);
}
rowAveVector = rowAverage(dataMatrix, rows, cols);
colAveVector = colAverage(dataMatrix, rows, cols);
if(rowAveVector == NULL || colAveVector == NULL)
{
printf("malloc failed. Terminating program\n");
return (0);
}
overallAve = overallAverage(dataMatrix, rows, cols);
//Print Averages
printAverages(dataMatrix, rowAveVector, colAveVector, overallAve, rows, cols);
free(dataMatrix);
free(rowAveVector);
free(colAveVector);
//Check if user wants to enter a new matrix
printf("Enter 0 to continue with a new matrix\n");
printf("Enter any other number to terminate the program: ");
scanf("%d", &done);
}
//That's it, we are done
return (0);
}
float *readMatrix(int rows, int cols)
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *readMatrix(int rows, int cols)
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(rows*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
mean+=matrix[i*cols+j];
}
Average_array[i]=(float)(mean/cols);
}
return Average_array;
}
float *colavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(cols*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<cols;i++)
{
for (j=0;j<rows;j++)
{
mean+=matrix[j*cols+i];
}
Average_array[i]=(float)(mean/rows);
}
return Average_array;
}
float overallavg(float* matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean_1=0;
float mean_2=0;
float avg=0;
float elements=0;
float sum=0;
elements=rows*cols;
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
mean_1+=matrix[i*rows+j];
}
}
for (i=0;i<cols;i++)
{
for (j=0;j<rows;j++)
{
mean_2+=matrix[j*cols+i];
}
}
sum=mean_1+mean_2;
avg=sum/elements-1;
}
the following code:
cleanly compiles
contains the needed #include statements
Note: this line:
avg=sum/elements-1;
will not calculate the average of all the elements but rather a somewhat larger value because the total number of elements is being decremented by 1
Suggestion, in the function: overallavg() do not calculate separate 'mean' values, rather simply step through the whole array summing each element, then divide by the total number of elements
Suggestion, use an indent width of 4 spaces, as that is easily visible, even with a variable width font. 2 spaces with a variable width font just looks like the indented row is indented about 1/2 the width of a char. I.E. barely visible and very messy looking. (code is read many many times so should be written to be very easy to read.
#include <stdio.h> // printf() scanf()
#include <stdlib.h> // malloc, free()
float *readMatrix( size_t rows, size_t cols)
{
//int i=0;
//int j=0;
size_t elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (size_t i=0; i<rows; i++)
{
for ( size_t j=0; j<cols; j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, size_t rows, size_t cols)
{
if (matrix==NULL)
{
return NULL;
}
//int i=0;
//int j=0;
float mean=0;
float *Average_array=malloc(rows*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for ( size_t i=0; i<rows; i++)
{
for ( size_t j=0; j<cols; j++)
{
mean+=matrix[i*cols+j];
}
Average_array[i] = (mean/(float)cols);
}
return Average_array;
}
float *colavg(float *matrix, size_t rows, size_t cols)
{
if (matrix==NULL)
{
return NULL;
}
//int i=0;
//int j=0;
float mean=0;
float *Average_array = malloc( cols*sizeof(float) );
if (Average_array==NULL)
{
return NULL;
}
for ( size_t i=0; i<cols; i++)
{
for (size_t j=0; j<rows; j++)
{
mean+=matrix[j*cols+i];
}
Average_array[i] = (mean/(float)rows);
}
return Average_array;
}
float overallavg(float* matrix, size_t rows, size_t cols)
{
#if 0
if (matrix==NULL)
{
return NULL;
}
#endif
//int i=0;
//int j=0;
float mean_1=0;
float mean_2=0;
float avg=0;
float elements=0;
float sum=0;
elements= (float)rows* (float)cols;
for ( size_t i=0;i<rows;i++)
{
for ( size_t j=0;j<cols;j++)
{
mean_1+=matrix[i*rows+j];
}
}
for ( size_t i=0; i<cols; i++)
{
for ( size_t j=0; j<rows ;j++)
{
mean_2+=matrix[j*cols+i];
}
}
sum=mean_1+mean_2;
avg=sum/elements-1;
return avg;
}

I want that vector_total dont have any repeated number

I need that vector_total dont have any repeated number.
Function for entry vector1 and vector2 that are declared in main().
void entrada_vectors(int vector1[], int vector2[], int vector_total[], int *n, int *m)
{
int i=0, j=0;
/*Entrarem els nombres del vector 1 primer */
for (i=0; i<*n; i++)
{
vector_total[i]=vector1[i];
}
/*Entrarem els nombres del vector 2 després */
for (i=*n; i<*n+*m; i++)
{
if (j<*m)
{
vector_total[i]=vector2[j];
j++;
}
}
}
Function 2. This is for order numbers in vector_total.
void ordena(int vector_total[], int *n, int *m)
{
int i=0, j=0;
int aux=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]>vector_total[j+1])
{
aux=vector_total[j];
vector_total[j]=vector_total[j+1];
vector_total[j+1]=aux;
aux=0;
}
}
}
}
Function 3. Print vector_total
void mostra(int vector_total[], int *n, int *m )
{ int i;
for (i=0; i<*n+*m; i++)
{
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
Function 4. Here are the problem!! This function is for clean my vector_total and drop the repeated numbers.
void limpiar_repetidos(int vector_total[], int *n, int *m)
{
int x=0, i=0, j=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]==vector_total[j+1])
{
x=j+1;
for (i=*n+*m; i>x; i--)
{
vector_total[i-1]=vector_total[i];
}
}
}
}
}
And here is my main. And my declaration variables:
int vector1[]={7,1,5,3,4,2};
int vector2[]={3,7,3,0,9,10};
int n=sizeof(vector1)/sizeof(vector1[0]);
int m=sizeof(vector2)/sizeof(vector2[0]);
int vector_total[n+m];
main()
{
entrada_vectors(vector1, vector2, vector_total, &n, &m);
ordena(vector_total, &n, &m);
mostra(vector_total, &n, &m);
limpiar_repetidos(vector_total, &n, &m);
printf ("==================\n");
mostra(vector_total, &n, &m);
return 0;
}
Thanks everybody! :)
1) If function deal with only a vector_total , Length of the vector_total is better to pass by one argument. Also you do not need to pointer pass if it will not change.
void mostra(int vector_total[], int len){
int i;
for (i=0; i<len; i++) {
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
2) function need a new length after the element has been removed. Also, deletion of adjacent same elements that can be like this.
int limpiar_repetidos(int vector_total[], int len){//int *n, int *m --> int len
int i, size, new_size;
size = len;
for(i = new_size = 1; i < size; ++i){
if(vector_total[new_size-1] != vector_total[i])
vector_total[new_size++] = vector_total[i];
}
return new_size;
}
Example of use
mostra(vector_total, m + n);
int l = limpiar_repetidos(vector_total, n + m);
mostra(vector_total, l);

Resources