Matrix multiplication from files in C - arrays

Hello i have go a assignment where i have 3 files a,b and c which contains 2 matrix which i have to multiply. In all a and b the first line is the size of the array and the next line is the contetnt for that array. c is the output of multiplication of the matrix. When i run the program i get a segmentation fault, and i cant seem to find the problem
#include<stdio.h>
#include<stdlib.h>
int **arrayA; //unallocated array A
int **arrayB; //unallocated array B
int **arrayC; //unallocated array C
int rA, cA; //Size of A
int rB, cB; //Size of B
int rC, cC; //Size of C
/*int matrixmultiplication(int *arrayA, int *arrayB, int *arrayC)//Function that multiplice the matrix
{
for (int i = 0; i < rC; i = i + 1)
for (int j = 0; j < cC; j = j + 1)
{
arrayC[i][j] = 0;
for (int k = 0; k < cA; k = k + 1)
arrayC[i][j] = arrayC[i][j] + arrayA[i][k] * arrayB[k][j];
}
}*/
int main(void)// Main function
{
//File pointer to A, B and C
FILE *Aptr;
FILE *Bptr;
FILE *Cptr;
//Opening the files containing the information for the matrix
Aptr = fopen("/home/au/Desktop/Matrixmulti/a", "r");
if(Aptr == NULL)
{
printf("ERROR!! opening file A");
exit(1);
}
Bptr = fopen("/home/au/Desktop/Matrixmulti/b", "r");
if(Bptr == NULL)
{
printf("ERROR!! opening file B");
exit(1);
}
Cptr = fopen("/home/au/Desktop/Matrixmulti/c", "w");
if(Cptr == NULL)
{
printf("ERROR!! opening file C");
exit(1);
}
//Scan file a for size of matrix a and matrix b
fscanf(Aptr, "%d", &rA);
fscanf(Aptr, "%d", &cA);
fscanf(Bptr, "%d", &rB);
fscanf(Bptr, "%d", &cB);
rC = rA;
cC = cB;
//Allocating space for the arrays
arrayA = malloc(rA * sizeof(int*));
for (int i = 0; i < rA; i++)
{
arrayA[i] = malloc(cA * sizeof(int));
}
arrayB = malloc(rB * sizeof(int*));
for (int i = 0; i < rB; i++)
{
arrayB[i] = malloc(cB * sizeof(int));
}
arrayC = malloc(rC * sizeof(int*));
for (int i = 0; i < rC; i++)
{
arrayA[i] = malloc(cC * sizeof(int));
}
//Scan file a for data for matrix a
for (int i = 0; i < rA; i++)
{
for (int j = 0; j < cA; j++)
{
fscanf(Aptr, "%d", &arrayA[i][j]);
}
}
//Scan file b for data for matrix b
for (int i = 0; i < rB; i++)
{
for (int j = 0; j < cB; j++)
{
fscanf(Bptr, "%d", &arrayB[i][j]);
}
}
//Matrix multiplication
for (int i = 0; i < rC; i = i + 1)
for (int j = 0; j < cC; j = j + 1)
{
arrayC[i][j] = 0;
for (int k = 0; k < cA; k = k + 1)
arrayC[i][j] = arrayC[i][j] + arrayA[i][k] * arrayB[k][j];
}
//Print result matrix to file c
for (int i = 0; i < rC; i++)
{
for (int j = 0; j < cC; j++)
{
fprintf(Cptr, "%d \t", arrayC[i][j]);
}
}
//Closing the files
fclose(Aptr);
fclose(Bptr);
fclose(Cptr);
return 0;
}

Related

How to add a 2D array group which having reads from a file numbers in c?

I need to read a file which contain numbers, and make 4 rows and 5 columns matrices from those numbers. Then, I need to add these matrices and print the sum matrix (the numbers of matrices depends on the user input).
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[]) {
int a = 4;
int b = 5;
int m;
scanf("%d", &m);
FILE *file = fopen("matrix.txt", "r");
int arr[a][b][m], i, j, k;
for (i = 0; i < a; i++) {
for (j = 0; j < b; j++) {
for (m = 0; k < m; k++) {
fscanf(file, "%d", &arr[i][j][k]);
arr[i][j] += arr[i][j];
}
}
}
for (i = 0; i < a;i++) {
for (j = 0; j < b; j++) {
for (k = 0; k < m; k++) {
printf("%d", arr[i][j][k]);
printf("\t");
}
printf("\n");
}
}
}
You don't need to load the matrix data into separate matrices, you can just add the matrix contents on the fly as you read each matrix from the file:
#include <errno.h>
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[]) {
int m;
if (scanf("%d", &m) != 1)
return 1;
const char *filename = "matrix.txt";
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return 1;
]
int a = 4;
int b = 5;
int sum[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
sum[i][j] = 0;
}
}
for (int k = 0; k < m; k++) {
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
int value;
if (fscanf(file, "%d", &value) != 1) {
fprintf(stderr, "not enough data\n");
return 1;
}
sum[i][j] += value;
}
}
}
fclose(file);
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return 0;
}
If you are required to load all the data in memory, use an array of matrices: int arr[m][a][b]; and 2 separate loops to read and sum the data:
#include <errno.h>
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[]) {
int m;
if (scanf("%d", &m) != 1)
return 1;
const char *filename = "matrix.txt";
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return 1;
]
int a = 4;
int b = 5;
int arr[m][a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
sum[i][j] = 0;
}
}
for (int k = 0; k < m; k++) {
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
if (fscanf(file, "%d", &arr[k][i][j]) != 1) {
fprintf(stderr, "not enough data\n");
return 1;
}
}
}
}
fclose(file);
int sum[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
int s = 0;
for (int k = 0; k < m; k++) {
s += arr[k][i][j];
}
sum[i][j] = s;
}
}
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return 0;
}

Why does my C program that is supposed to output a matrix to the power of n output my matrix to the power of 2^n?

My code is supposed to take in a matrix M and raise it to the power of an integer A. However, somehow, my output is always M^(2^A). For example, if I want to find a matrix in its 3rd power, I will instead receive its 8th power.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void multiply(int ** p, int pwr, int dim, int ** prod) {
int m, i, j, k;
/*if (n<pwr){*/
int pos = 0;
for (m = 0; m < pwr; m++) {
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
for (k = 0; k < dim; k++) {
pos += p[i][k] * p[k][j];
}
prod[i][j] = pos;
pos = 0;
}
}
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
p[i][j] = prod[i][j];
prod[i][j] = 0;
}
}
}
/*n=n+1;
multiply(prod, q, pwr, dim, prod);
}*/
}
int main(int argc, char * argv[]) {
FILE * fp = fopen(argv[1], "r");
int dim, pwr, i, j;
fscanf(fp, "%d", & dim);
int ** matrix;
matrix = (int ** ) malloc(dim * sizeof(int * ));
for (i = 0; i < dim; i++) {
matrix[i] = (int * ) malloc(dim * sizeof(int));
}
int ** prod;
prod = (int ** ) malloc(dim * sizeof(int * ));
for (i = 0; i < dim; i++) {
prod[i] = (int * ) malloc(dim * sizeof(int));
}
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
fscanf(fp, "%d", & matrix[i][j]);
}
}
fscanf(fp, "%d", & pwr);
if (pwr == 1) {
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
} else if (pwr >= 2) {
multiply(matrix, pwr, dim, prod);
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
return 0;
}
You are multiplying your matrix by itself and then store the result in the original one. Then you do it again.
So perfectly normal that it gets powered 8 times. What you need is another temporary matrix on which you store the result and keep the original matrix to multiply your result with.

Multidimensional array - fscanf

int main(){
int word, r=3, i, j;
FILE *fp1 = fopen("key.txt","r");
int **arr = (int **)malloc(sizeof(int *) * r);
for(i = 0;i<r;i++)
arr[i] = (int *)malloc(sizeof(int)*r);
int a = 0, b = 0;
while (!feof(fp1)) {
fscanf(fp1,"%d",&word);
if (b == r){
a++;
b=0;
continue;
}
arr[a][b++] = word;
}
for (i = 0; i < r; i++)
for (j = 0; j < r; j++)
printf("%d \n", arr[i][j]);
fclose(fp1);
}
And this is my key.txt.
0 -1 0
-1 2 -1
0 -1 0
I want to store key.txt in a dynamic 2d array but it did not work. All the time a part of it is missing. Which part is wrong?
You should use fscanf in while, not feof
You should delete continue.
The follow code could work:
#include <stdio.h>
#include <stdlib.h>
int main(){
int word, r=3, i, j;
FILE *fp1 = fopen("key.txt","r");
int **arr = (int **)malloc(sizeof(int *) * r);
for(i = 0;i<r;i++)
arr[i] = (int *)malloc(sizeof(int)*r);
int a = 0, b = 0;
while (fscanf(fp1,"%d",&word) == 1) {
if (b == r) {
a++;
b=0;
}
arr[a][b++] = word;
}
for (i = 0; i < r; i++) {
for (j = 0; j < r; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
fclose(fp1);
return 0;
}

Can't compile matrix multiplication

Hey I got this error and I tried like 10 solutions and neither works. I want to load 2 matrix, each one from its own txt file then to multiply them. I can't compile cause of LNK1120 and LNK2019 errors.
Here is my code:
int main(int argc, char *argv[])
{
FILE *macierz1, *macierz2, *fw;
char *line = malloc(1000);
int count = 0;
macierz1 = fopen("macierz1.txt", "r");
if (macierz1 == NULL) {``
printf("nie można otworzyć", argv[1]);
exit(1);
}
macierz2 = fopen("macierz2.txt", "r");
if (macierz2 == NULL) {
printf("nie można otworzyć", argv[2]);
exit(1);
}
double *data = (double*)malloc(1000 * sizeof(double));
if (data == NULL)
{
printf("błąd lokowania pamięci");
return EXIT_FAILURE;
}
getline(&line, &count, macierz1);
int read = -1, cur = 0, columCount1 = 0;
while (sscanf(line + cur, "%lf%n", &data[columCount1], &read) == 1)
{
cur += read; columCount1++;
}
int rowCount1 = 1;
while (getline(&line, &count, macierz1) != -1) { rowCount1++; }
printf("%d\n", columCount1);
printf("%d\n", rowCount1);
getline(&line, &count, macierz2);
read = -1, cur = 0;
int columCount2 = 0;
while (sscanf(line + cur, "%lf%n", &data[columCount2], &read) == 1)
{
cur += read; columCount2++;
}
int rowCount2 = 1;
while (getline(&line, &count, macierz2) != -1) { rowCount2++; }
printf("%d\n", columCount2);
printf("%d\n", rowCount2);
int i = 0;
int j = 0;
int **mat1 = (int **)malloc(rowCount1 * sizeof(int*));
for (i = 0; i < rowCount1; i++)
mat1[i] = (int *)malloc(columCount1 * sizeof(int));
fseek(macierz1, 0, SEEK_SET);
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount1; j++)
fscanf(macierz1, "%d", &mat1[i][j]);
}
i = 0;
j = 0;
printf("\n\n");
//print matrix 1
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount1; j++)
printf("%d", mat1[i][j]);
printf("\n");
}
i = 0;
j = 0;
int **mat2 = (int **)malloc(rowCount2 * sizeof(int*));
for (i = 0; i < rowCount2; i++)
mat2[i] = (int *)malloc(columCount2 * sizeof(int));
fseek(macierz2, 0, SEEK_SET);
for (i = 0; i < rowCount2; i++)
{
for (j = 0; j < columCount2; j++)
fscanf(macierz2, "%d", &mat2[i][j]);
}
i = 0;
j = 0;
printf("\n\n");
//print matrix 2
for (i = 0; i < rowCount2; i++)
{
for (j = 0; j < columCount2; j++)
printf("%d", mat2[i][j]);
printf("\n");
}
i = 0;
int **mat3 = (int **)malloc(rowCount1 * sizeof(int*));
for (i = 0; i < rowCount1; i++)
mat3[i] = (int *)malloc(columCount2 * sizeof(int));
i = 0;
j = 0;
int k = 0;
int sum = 0;
if (columCount1 != rowCount2)
{
puts("The number of columns in Matrix 1 is not same as the number of rows in Matrix 2");
exit(1);
}
//multiplication of two matrices
for (i = 0; i<rowCount1; i++)
{
for (j = 0; j<columCount2; j++)
{
mat3[i][j] = 0;
for (k = 0; k<columCount1; k++)
{
mat3[i][j] = mat3[i][j] + mat1[i][k] * mat2[k][j];
}
}
}
//print multiplication result
printf("\n\nResult = \n\n");
for (i = 0; i < rowCount1; i++)
{
for (j = 0; j < columCount2; j++)
printf("%d", mat3[i][j]);
printf("\n");
}
for (i = 0; i< rowCount1; i++)
free(mat1[i]);
free(mat1);
for (i = 0; i< rowCount2; i++)
free(mat2[i]);
free(mat2);
for (i = 0; i< rowCount1; i++)
free(mat3[i]);
free(mat3);
free(data);
return 0;
}
Since you're using Visual C++, there is no such C function as getline. The C compiler that comes with Visual C++ adheres to the C89 specification.
Use fgets to retrieve the data from the file.
If you really want to use getline in your Visual C++ (really C) program, you could try this code from GNU that implements the function.
There is a stray '`' in program posted at the end of the line:
if (macierz1 == NULL) {``
and
getline
function is not defined.
add needed includes:
#include <stdio.h>
#include <stdlib.h>

C program store file to jagged array and sort it

I am trying to create C program to read a text file and sort it by ascending order. The example of text file is
2
3; 2, 5, 7
6; 4, 7, 8, 9, 5, 2
with the first line indicated the number of rows, the number after the ";" indicated elements each rows and elements separated by ",".
So my idea is to create a dynamic jagged array with rows as the first number, then point each row to the different array with element. Sort the pointer arrays first then sort elements of each arrays. This is what I have tried so far
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int SortLists();
int main ()
{
int i,j = 0;
char filename[10]; //name of the file
char line[100];
int rows = 3; //I have to initialized this to test my code first
int cols;
int **jaggedArr; //jagged array
jaggerArr = malloc (rows*sizeof(int*)) ;
printf("Enter the file name with .txt : ");
scanf("%s", filename);
FILE *filePtr = fopen(filename, "r");
int num;
if (filePtr != NULL)
{
while (fgets(line, sizeof(line), filePtr) != NULL) //read each line of the text
{
cols = atoi(strtok(line, ";")); //use strtk to break elements
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
jaggedArr[i][j] = atoi(strtok(line, ",")); //parse into the jagged array
}
}
}
fclose(filePtr);
}
}
int SortLists(int list[], int size) //sort method
{
int i,j,temp;
for (i = 0; i < size; ++i)
{
for (j = i + 1; j < size; ++j)
{
if (list[i] > list[j])
{
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
As a beginner in C, I am not familiar with the idea of pointer, which a lot different with C#.
Sorry for my bad English as its not my first language. Thank you so much for helping me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S_(x) #x
#define S(x) S_(x)
void SortLists(int list[], int size);
int main(void){
char filename[FILENAME_MAX+1];
char line[100];
int rows, cols;
printf("Enter the file name with .txt : ");
scanf("%" S(FILENAME_MAX) "[^\n]%*c", filename);
FILE *filePtr = fopen(filename, "r");
if(!filePtr)
return EXIT_FAILURE;
fscanf(filePtr, "%d ", &rows);
int **jaggedArr;
jaggedArr = malloc (rows * sizeof(int*));
int *sizeArr = malloc(rows * sizeof(int));
int r = 0, c;
while (fgets(line, sizeof(line), filePtr) != NULL){
sizeArr[r] = cols = atoi(strtok(line, ";"));
jaggedArr[r] = malloc(cols * sizeof(int));
for (c = 0; c < cols; ++c){
jaggedArr[r][c] = atoi(strtok(NULL, ","));
}
SortLists(jaggedArr[r++], cols);
}
fclose(filePtr);
//check print and deallocation
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
free(jaggedArr[r]);
}
free(jaggedArr);
free(sizeArr);
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
for extra question.
#include <stdio.h>
void SortLists(int list[], int size);
void SortRows(int *jaggedArr[], int size, int *rowSize);
int main(void){
int row1[] = {4,7,8,9,5,2};
int row2[] = {2,5,7};
int *jaggedArr[] = { row1, row2};
int rows = 2;
int sizeArr[] = {6,3};
int i, r, c;
for(i=0;i<rows;++i)
SortLists(jaggedArr[i], sizeArr[i]);
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
printf("\n");
SortRows(jaggedArr, rows, sizeArr);
for(r = 0;r < rows; ++r){
for(c = 0; c < sizeArr[r]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
void SortRows(int *jaggedArr[], int size, int *rowSize){
int i,j,temp,*tempp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (rowSize[i] > rowSize[j]){
//swap in pairs
temp = rowSize[i];
rowSize[i] = rowSize[j];
rowSize[j] = temp;
tempp = jaggedArr[i];
jaggedArr[i] = jaggedArr[j];
jaggedArr[j] = tempp;
}
}
}
}
#include <stdio.h>
void SortLists(int list[], int size);
void SortRows(int *jaggedArr[], int size);
int main(void){
int row1[] = {6, 4,7,8,9,5,2};//The first element represents the number of elements.
int row2[] = {3, 2,5,7};
int *jaggedArr[] = { row1, row2};
int rows = 2;
//int sizeArr[] = {6,3};//Not required
int i, r, c;
for(i=0;i<rows;++i)
SortLists(jaggedArr[i]+1, jaggedArr[i][0]);
SortRows(jaggedArr, rows);
for(r = 0;r < rows; ++r){
for(c = 1; c <= jaggedArr[r][0]; ++c)
printf("%d ", jaggedArr[r][c]);
printf("\n");
}
return 0;
}
void SortLists(int list[], int size){
int i,j,temp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (list[i] > list[j]){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
}
void SortRows(int *jaggedArr[], int size){
int i,j,*tempp;
for (i = 0; i < size-1; ++i){
for (j = i + 1; j < size; ++j){
if (jaggedArr[i][0] > jaggedArr[j][0]){
tempp = jaggedArr[i];
jaggedArr[i] = jaggedArr[j];
jaggedArr[j] = tempp;
}
}
}
}

Resources