Я пытаюсь умножить две матрицы, хранящиеся в файле, отформатированном таким образом:
1 2
2 3
*
-4 1
1 0
Я изначально не знаю, каково измерение каждой матрицы.Но я позволю пользователю определить его, иначе будет принято значение по умолчанию 100
.
int maxc = argc > 2 ? atoi(argv[2]) * atoi(argv[2]) : 100;
Я уже могу правильно выполнить расчет, но я заметил, что если я введу измерение argv[2] = "2"
так что maxc = 8
, (этого должно быть достаточно для этого примера), возникают ошибки при чтении или печати файла.Но если я введу argv[2] = "3"
, все отлично работает для этого примера.Поскольку maxc
используется для выделения памяти здесь: matrix = malloc(maxc * sizeof *matrix)
, я подозреваю, что проблема может быть в этой строке.Должен ли я выделять память также для size_t row; size_t col;
?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define MAXNOP 50 /*Max number of operations allowed */
#define MAXNMATR 20 /*Max number of matrices */
struct m {
size_t row;
size_t col;
double *data;
};
struct m multiply(struct m *A, struct m *B);
void f(double x);
void print_matrix(struct m *A);
void read_file(int maxc, FILE *fp);
void scalar_product(double scalar, struct m *B);
void calculate(struct m *matrix, int nop, int id, char *op);
int main(int argc, char *argv[]) {
FILE *file = argc > 1 ? fopen(argv[1], "rb") : stdin;
/* define max dimension of a matrix */
int maxc = argc > 2 ? atoi(argv[2]) * atoi(argv[2]) : 100;
read_file(maxc, file);
return 0;
}
void read_file(int maxc, FILE *fp) {
struct m *matrix;
int id = 0; /* id of a matrix */
size_t ncol, nrow; /* No of columns of a matrix*/
ncol = nrow = 0;
int nop = 0; /*No of operators*/
int off = 0;
int i;
int n;
double *d;
char buf[2 * maxc]; /*to store each lines of file */
char *p = buf;
char op[MAXNOP];
for (i = 0; i < MAXNOP; i++)
op[i] = '?';
if (!(matrix = malloc(maxc * sizeof *matrix))) {
perror("malloc-matrix");
exit(1);
}
/* Read file line by line */
while (fgets(buf, maxc, fp)) {
if (nrow == 0) {
/* allocate/validate max no. of matrix */
d = matrix[id].data = malloc(sizeof(double) * MAXNMATR);
}
/* check if line contains operator */
if ((!isdigit(*buf) && buf[1] =='\n')) {
op[nop++] = *buf;
matrix[id].col = ncol;
matrix[id].row = nrow;
nrow = ncol = 0;
id++;
continue;
} else {
/* read integers in a line into d */
while (sscanf(p + off, "%lf%n", d, &n) == 1) {
d++;
if (nrow == 0)
ncol++;
off += n;
}
nrow++;
off = 0;
}
} /*end of while fgets cycle */
/* Assign last matrix No of columns and rows */
matrix[id].col = ncol;
matrix[id].row = nrow;
/* Printing the matrices and operations */
for (i = 0; i <= id; i++) {
if (op[i] == '*' || op[i] == '-' || op[i] =='+') {
print_matrix(&matrix[i]);
if (op[i-1] != 'i')
printf("%c\n", op[i]);
else
continue;
} else
if (op[i] == '?') {
print_matrix(&matrix[i]);
}
}
calculate(matrix, nop, id, op);
}
void calculate(struct m *matrix, int nop, int id, char *op) {
int i;
for (i = 0; i <= nop; i += 2) {
if (op[i] == '*' && op[i+1] == '?') {
if (matrix[i].row == 1 && matrix[i].col == 1)
scalar_product(matrix[i].data[0], &matrix[i + 1]); //Multiplication of Scalar per matrix
else {
matrix[i + 1] = multiply(&matrix[i], &matrix[i + 1]);
matrix[i + 2] = multiply(&matrix[i + 1], &matrix[i + 2]);
}
break;
}
}
printf("=\n");
print_matrix(&matrix[id]); /* Print the result */
free(matrix);
}
struct m multiply(struct m *A, struct m *B) {
size_t i, j, k;
struct m C;
C.data = malloc(sizeof(double) * A->row * B->col);
C.row = A->row;
C.col = B->col;
for (i = 0; i < C.row; i++)
for (j= 0 ; j < C.col; j++)
C.data[i * C.col + j] = 0;
// Multiplying matrix A and B and storing in C.
for (i = 0; i < A->row; ++i)
for (j = 0; j < B->col; ++j)
for (k = 0; k < A->col; ++k)
C.data[i * C.col + j] += A->data[i * A->col + k] * B->data[k * B->col + j];
return C;
}
void f(double x) {
double i, f = modf(x, &i);
if (f < .00001)
printf("%.f ", i);
else
printf("%f ", x);
}
/* printing a Matrix */
void print_matrix(struct m *A) {
size_t i, j;
double *tmp = A->data;
for (i = 0; i < A->row; i++) {
for (j = 0; j < A->col; j++) {
f(*(tmp++));
}
putchar('\n');
}
}
void scalar_product(double scalar, struct m *B) {
size_t i, j;
for (i = 0; i < B->row; i++)
for (j = 0; j < B->col; j++)
B->data[i * B->col + j] = scalar * B->data[i * B->col + j];
}
Ожидаемый результат таков: https://ideone.com/Z7UtiR
здесь argv[2]
не читается, поэтому достаточно памяти для хранения всех данных.