#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct
{
	int **mat;
	int mat_row;
	int mat_column;
}Matrix;

void readfile(FILE *fp, Matrix *mat, int mat_num);
void writefile(FILE *fp, Matrix mat);
int get_row_column(FILE *fp, Matrix *mat);
Matrix Product1(Matrix mat1, Matrix mat2);
Matrix Product2(Matrix *mat, int mat_num);
void delete_mat(Matrix *mat, int mat_num);

int main(void)
{
	FILE *fp;
	Matrix mat[10];
	char *filename = "c5.txt";
	fopen_s(&fp, filename, "r");
	if (fp == NULL)
	{
		return -1;
	}
	int mat_num = get_row_column(fp, mat);
	readfile(fp, mat, mat_num);
	Matrix product = Product2(mat, mat_num);
	writefile(fp, product);
	fopen_s(&fp, filename, "w");
	delete_mat(mat, mat_num);
	delete_mat(&product, 1);
	fclose(fp);
	getchar();
}
int get_row_column(FILE *fp, Matrix *mat)
{
	int state_row = 0;
	int state_column = 0;
	int mat_num = 0;
	int ch;
	while ((ch = fgetc(fp)) != EOF)
	{
		if (ch != '\n'&&ch != ' '&&state_column == 0)
		{
			++mat[mat_num].mat_column;
		}
		else if (ch != '\n'&&ch != ' '&&state_column == 1)
		{
			state_row = 0;
		}
		else if (ch == '\n'&&state_row == 0)
		{
			state_column = 1;
			state_row = 1;
			++mat[mat_num].mat_row;
		}
		else if (ch == '\n'&&state_row == 1)
		{
			state_row = 0;
			state_column = 0;
			++mat_num;
		}
	}
	return mat_num;
}

void readfile(FILE *fp, Matrix *mat, int mat_num)
{
	rewind(fp);
	for (int i = 0; i < mat_num; ++i)
	{
		mat[i].mat = (int**)malloc(sizeof(int*)*mat[i].mat_row);
		for (int j = 0; j < mat[i].mat_row; ++j)
		{
			mat[i].mat[j] = (int*)malloc(sizeof(int)*mat[i].mat_column);
			for (int k = 0; k < mat[i].mat_column; ++k)
			{
				fscanf_s(fp, "%d", &(mat[i].mat[j][k]));
			}
		}
	}
}

Matrix Product1(Matrix mat1, Matrix mat2)
{
	Matrix Product;
	Product.mat_row = mat1.mat_row;
	Product.mat_column = mat2.mat_column;
	Product.mat = (int**)malloc(sizeof(int*)*Product.mat_row);
	for (int i = 0; i < Product.mat_row; ++i)
	{
		Product.mat[i] = (int*)malloc(sizeof(int)*Product.mat_column);
	}
	for (int i = 0; i < Product.mat_row; ++i)
	{
		for (int j = 0; j < Product.mat_column; ++j)
		{
			for (int k = 0; k < mat1.mat_column; ++k)
			{
				Product.mat[i][j] = mat1.mat[i][k] * mat2.mat[k][j];
			}
		}
	}
	return Product;
}

Matrix Product2(Matrix *mat, int mat_num)
{
	Matrix Product = mat[0];
	for (int i = 1; i < mat_num; ++i)
	{
		Product = Product1(Product, mat[i]);
	}
	return Product;
}

void delete_mat(Matrix *mat, int mat_num)
{
	for (int i = 0; i < mat_num; ++i)
	{
		for (int j = 0; j < mat[i].mat_row; ++j)
		{
			free(mat[i].mat[j]);
			mat[i].mat[j] = NULL;
		}
		free(mat[i].mat);
		mat[i].mat = NULL;
	}
}

void writefile(FILE *fp, Matrix mat)
{
	char ch;
	for (int i = 0; i < mat.mat_row; ++i)
	{
		for (int j = 0; j < mat.mat_column; ++j)
		{
			ch = mat.mat[i][j];
			fputc(ch, fp);
		}
	}
}