2

I am trying to read matrix from two text files, storing it into 2 arrays and then trying to multiply the two matrices and store the result in an array. The multiplication result is coming as 000.

Below is my code

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

int main(int argc,char *argv[])
{
    FILE *fr1, *fr2, *fw;
    char *line = malloc(1000);
    int count = 0;
    //To read a file use the fopen() function to open it 
    fr1 = fopen(argv[1], "r");
    //If the file fails to open the fopen() returns a NULL 
    if (fr1 == NULL) {
        printf("Cannot open %s. Program terminated...",argv[1]);
        exit(1);
    }

    // Similar to the above method read the second file
    fr2 = fopen(argv[2], "r");
    if (fr2 == NULL) {
        printf("Cannot open %s. Program terminated...",argv[2]);
        exit(1);
    }

    double *data = (double*) malloc(1000*sizeof(double));
    if(data == NULL)
    {
        printf("Error in allocating memory");
        return EXIT_FAILURE;
    }
    // Read number of columns and number of rows of first matrix
    getline(&line, &count, fr1);
    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, fr1) != -1) {rowCount1++;}
    printf("%d\n",columCount1);
    printf("%d\n",rowCount1);

    // Read number of columns and number of rows of second matrix
    getline(&line, &count, fr2);
    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, fr2) != -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( fr1, 0, SEEK_SET );

    for(i=0; i<rowCount1; i++)
    {
        for(j=0; j<columCount1; j++)
            fscanf(fr1,"%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( fr2, 0, SEEK_SET );

    for(i=0; i<rowCount2; i++)
    {
        for(j=0; j<columCount2; j++)
            fscanf(fr2,"%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;
    //multiplication of two matrices
    for(i=0; i<rowCount1; i++)
    {
        for(j=0; j<columCount2; j++)
        {
            sum=0;
            for(k=0; k<rowCount2; k++)
                sum+=mat1[i][k]*mat2[k][j];
        }
        mat3[i][j] = sum;
    }

    i = 0;
    j = 0;


    //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");
    }

    return 0;   
}
ani627
  • 5,578
  • 8
  • 39
  • 45
user3648814
  • 45
  • 1
  • 8
  • You're likely to have reached the end-of-file by the time you've read enough to know the number of rows, so the `while(!feof(fr1))` won't do much... Try `fseek` back to the start of file. – SleuthEye Sep 05 '14 at 22:58
  • Thanks. Using fseek solved the problem, but now i am getting the result of multiplying two matrices as 000. – user3648814 Sep 05 '14 at 23:24
  • 2
    I see that it looks awful again, now that you've taken out NetVipeC's nice edit. That said, using a debugger should allow you to find what's wrong with the matrix multiplication (hint: what's the value of `j` when you assign `sum` to `mat3`?) – SleuthEye Sep 05 '14 at 23:41
  • 2
    `mat3[i][j]=sum;` move to inside of for-loop. also `getline`'s 2nd arg type is `size_t*`, not `int*`. – BLUEPIXY Sep 06 '14 at 00:07
  • @user3648814: BLUEPIXY correctly pointed out the problem in your code. Also don't forget to check if `columCount1==rowCount2` before you proceed with matrix multiplication. – ani627 Sep 06 '14 at 19:46
  • @user3648814: Also don't forget to free the memory. – ani627 Sep 06 '14 at 20:20
  • Do NOT cast the return of `malloc`. It is totally unnecessary and can hide errors. See: [**Do I cast the result of malloc?**](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – David C. Rankin Sep 07 '14 at 00:40
  • Additionally, you can continue to use `malloc` for both allocating pointers to rows and allocating space for your data (columns), but it is common to use `calloc` to allocate space for your data (columns) as it automatically zeros the memory locations. I.e.: `mat1[i] = calloc(columCount1, sizeof(int));` and prevents a second call to `memset`. – David C. Rankin Sep 07 '14 at 00:47

1 Answers1

2

1) Before matrix multiplication check if the number of columns in Matrix 1 is same as the number of rows in Matrix 2

//Check if number of col in mat1 is same as number of rows in mat2
if(columCount1 != rowCount2)
{
    puts("The number of columns in Matrix 1 is not same as the number of rows in Matrix 2");
    exit(1);
}

2) Code for 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];
        }
    }
}

3) Free the allocated memory before returning from main()

/* After printing the results free the memory */
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);
ani627
  • 5,578
  • 8
  • 39
  • 45