How to set values of matrices with the help of methods in c? - Stack Overflow

Ive been trying to set the values of matrices with the help of methods that take pointers, But I am una

Ive been trying to set the values of matrices with the help of methods that take pointers, But I am unable to do this. The setMatrixValue method stops working when the loop reaches the second row. The inputs which I am using to test:

2 2

1 2 3 4

The output I am getting:

Input the size: 2 2

Size of matrix 1: 2

First matrix size: 2

Input elements of matrix 1: 1 2 3 4

I: 0, J: 0

Token: 1

Value: 1

I: 0, J: 1

Token: 2

Value: 2

I: 1, J: 0

Token: 3

This is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 4

// This method clears buffer
void clearBuffer (void) {
    char input;
    while ( (input = getchar()) != '\n' && input != EOF );
}

void setMatrixValues(int *firstMatrixSize, int **firstMatrix) {
    char temp2[200];
    int i;
    int j;
    int *pI = &i;
    int *pJ = &j;

    printf("First matrix size: %d\n", *firstMatrixSize);

    printf("Input elements of matrix 1: ");
    fgets(temp2, sizeof(temp2), stdin);
    char *token = strtok(temp2, " ");

    for(*pI = 0; *pI < *firstMatrixSize; ++*pI) {
        for(*pJ = 0; *pJ < *firstMatrixSize; ++*pJ) {
            printf("I: %d, J: %d\n", *pI, *pJ);
            printf("Token: %d\n", atoi(token));
            firstMatrix[*pI][*pJ] = atoi(token);
            printf("Value: %d\n", firstMatrix[*pI][*pJ]);
            token = strtok(NULL, " ");
        }
    }

}

void setMatrixSize(int *firstMatrixSize, int *secondMatrixSize) {
    char temp[200];
    printf("Input the size: ");
    fgets(temp, sizeof(temp), stdin);

    char *token = strtok(temp, " ");

    for(int i = 0; i < 2; i++) {
        if(i == 0) {
            *firstMatrixSize = atoi(token);
        } else {
            *secondMatrixSize = atoi(token);
        }
        token = strtok(NULL, " ");
    }
}

int main(int argc, char *argv[]) {
    int size_matrix_1;
    int size_matrix_2;
    int *pSize_matrix_1 = &size_matrix_1;
    int *pSize_matrix_2 = &size_matrix_2;

    char stringMatrix1[200];
    char stringMatrix2[200];

    setMatrixSize(pSize_matrix_1, pSize_matrix_2);

    int matrix_1[*pSize_matrix_1][*pSize_matrix_1];
    int matrix_2[*pSize_matrix_2][*pSize_matrix_2];

    printf("Size of matrix 1: %d\n", *pSize_matrix_1);
    setMatrixValues(pSize_matrix_1, matrix_1);

}

Ive been trying to set the values of matrices with the help of methods that take pointers, But I am unable to do this. The setMatrixValue method stops working when the loop reaches the second row. The inputs which I am using to test:

2 2

1 2 3 4

The output I am getting:

Input the size: 2 2

Size of matrix 1: 2

First matrix size: 2

Input elements of matrix 1: 1 2 3 4

I: 0, J: 0

Token: 1

Value: 1

I: 0, J: 1

Token: 2

Value: 2

I: 1, J: 0

Token: 3

This is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 4

// This method clears buffer
void clearBuffer (void) {
    char input;
    while ( (input = getchar()) != '\n' && input != EOF );
}

void setMatrixValues(int *firstMatrixSize, int **firstMatrix) {
    char temp2[200];
    int i;
    int j;
    int *pI = &i;
    int *pJ = &j;

    printf("First matrix size: %d\n", *firstMatrixSize);

    printf("Input elements of matrix 1: ");
    fgets(temp2, sizeof(temp2), stdin);
    char *token = strtok(temp2, " ");

    for(*pI = 0; *pI < *firstMatrixSize; ++*pI) {
        for(*pJ = 0; *pJ < *firstMatrixSize; ++*pJ) {
            printf("I: %d, J: %d\n", *pI, *pJ);
            printf("Token: %d\n", atoi(token));
            firstMatrix[*pI][*pJ] = atoi(token);
            printf("Value: %d\n", firstMatrix[*pI][*pJ]);
            token = strtok(NULL, " ");
        }
    }

}

void setMatrixSize(int *firstMatrixSize, int *secondMatrixSize) {
    char temp[200];
    printf("Input the size: ");
    fgets(temp, sizeof(temp), stdin);

    char *token = strtok(temp, " ");

    for(int i = 0; i < 2; i++) {
        if(i == 0) {
            *firstMatrixSize = atoi(token);
        } else {
            *secondMatrixSize = atoi(token);
        }
        token = strtok(NULL, " ");
    }
}

int main(int argc, char *argv[]) {
    int size_matrix_1;
    int size_matrix_2;
    int *pSize_matrix_1 = &size_matrix_1;
    int *pSize_matrix_2 = &size_matrix_2;

    char stringMatrix1[200];
    char stringMatrix2[200];

    setMatrixSize(pSize_matrix_1, pSize_matrix_2);

    int matrix_1[*pSize_matrix_1][*pSize_matrix_1];
    int matrix_2[*pSize_matrix_2][*pSize_matrix_2];

    printf("Size of matrix 1: %d\n", *pSize_matrix_1);
    setMatrixValues(pSize_matrix_1, matrix_1);

}
Share Improve this question asked Feb 4 at 19:41 carbonatedWaterrcarbonatedWaterr 112 bronze badges 3
  • 1 int **firstMatrix requires an array of pointers. But you have a 2-dimensional array, not an array of pointers. – Barmar Commented Feb 4 at 19:50
  • Sidenote: char input; - That should be int input; – Ted Lyngmo Commented Feb 4 at 20:06
  • Please, define first a method in C.... as it is normally something related to object oriented programming. – Luis Colorado Commented Feb 6 at 15:19
Add a comment  | 

2 Answers 2

Reset to default 1

In this call

setMatrixValues(pSize_matrix_1, matrix_1);

the second argument expression having the variable array type

int [*pSize_matrix_1][*pSize_matrix_1]

is implicitly converted to a pointer of the type int ( * )[*pSize_matrix_1] to the first element of the two-dimensional array that has one-dimensional array type

int [*pSize_matrix_1]

However the corresponding parameter has type int **firstMatrix.

There is no implicit conversion between the two pointer types. So the function invokes undefined behavior.

You could declare the function at least like

void setMatrixValues(int *firstMatrixSize, int ( *firstMatrix )[*firstMatrixSize] ); 

Though there is no great sense to declare the first parameter as having a pointer type because the original argument is not changed within the function.

So the function declaration could look like

void setMatrixValues(int firstMatrixSize, int ( *firstMatrix )[firstMatrixSize] ); 

or like

void setMatrixValues(int firstMatrixSize, int firstMatrix[][firstMatrixSize] ); 

Pay attention to that the variable input should be declared as having type int. Otherwise when the type char behaves as type unsigned char the comparison the variable input with the macro EOF will results always in logical false.

Normally, when I have generic code to initialize some kind of matrix implementation I normally provide a provider function pointer that is called by the initialization routine with some information passed from the caller code. Something like:

void matrix_init(
        MATRIX_T *matrix, 
        CELL_T (*provider)(int row, int col, void *private_data),
        void *private_data);

and the matrix_init will call the provider function, for each element (indicated by the row and col indexes, and the private data reference that will be passed to the provider to hold state data to be used by the provider. This allows you to pass a FILE * for example to the provider to get the data from the state holder structure. To maintain it simple, I have used VLAs to allow for simple matrix definition.

void matrix_init(
        int rows, int cols, 
        double matrix[rows][cols],
        double (*provider)(int r, int c, void *cd),
        void *call_data)
{
    for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++)
            matrix[r][c] = provider(r, c, call_data);
}

double provider_delta_kroneker(int r, int c, void *unused)
{
    return r == c ? 1.0 : 0.0;
}

double provider_from_FILE(int r, int c, void *the_file)
{
    FILE *in = the_file;
    double val = 0.0;
    if (fscanf(in, "%lg", &val) == 1)
        return val;
    return FLOAT_NAN; /* couldn't read, so this is a possible alternative */
}

And then, you could initialize differently, by passing either of two functions.

    double matrix[10][10];
    matrix_init(10, 10, matrix, provider_delta_kroneker, NULL);
    /* you got the identity matrix */

or

    double matrix[20][5];
    matrix_init(20, 5, matrix, provider_from_FILE, stdin);
    /* you got the matrix read from stdin */

This way, you can initialize your matrix with full flexibility and genericly.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745236405a4617918.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信