Mnożenie macierzy wczytanych z plików – błędne wyniki

0

Witam,
program ma za zadanie wczytywac dwie macierze z dwóch różnych plików tekstowych (gdzie dwie pierwsze liczby w pierwszej linii są całkowite i określają rozmiary macierzy, a w kolejnych liniach są liczby tworzące macierz z zakresu 0-100 z jednym miejscem po przecinku), wyświetlic je, przemnożyc, wyświetlic otrzymaną macierz i zapisac ją do trzeciego, wynikowego pliku tekstowego.

Napisałem poniższy kod, jednak gdy dochodzi do momentu mnożenia macierzy program podaje jedną dużą liczbę zamiast wynikowej macierzy, dlatego uznałem, że coś jest źle w pętli odpowiadającej za mnożenie i próbowałem ją zmienic, ale mimo to mnożenie dalej jest źle wykonywane. Bardzo proszę o pomoc.

  • w1 - liczba wierszy w macierzy A/1
  • k2 - liczba kolumn w macierzy A/1
  • w2 - liczba wierszy w macierzy B/2
  • k2 - liczba kolumn w macierzy B/2
  • x1,x23,x4 - określają położenie w macierzy mnożonych liczb

W komentarzu jest generator plików tekstowych w postaci takiej, jakiej wymaga zadanie( 2 liczby całkowite i macierz).

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

int main()
{
  /*float liczba;
    int w, k, stop;
    FILE *plik;

    srand(time(0));

    w = (1 + rand() % 9);
    k = (1 + rand() % 9);

    plik = fopen("matrix1.txt", "wt");

    fprintf(plik, "%d  %d\n\n", w, k);
    printf("%d  %d\n\n", w, k);

    for (int i = 0; i < w; i++)
    {
        for (int j = 0; j < k; j++)
        {
            liczba = rand() % 1001;
            liczba = liczba / 10;
            fprintf(plik,"%.1f   ", liczba);
            printf("%.1f   ", liczba);
        }
        fprintf(plik,"\n\n");
        printf("\n\n");
    }

    printf("Powyzsza macierz zostala zapisana do pliku matrix1.txt");

    fclose(plik);

    scanf("%d", &stop);
    return 0;*/

    float c = 0;
    float **macierz1;
    float **macierz2;
    float liczba;
    int w1, w2, k1, k2;
    int stop;

    FILE *plik1;
    FILE *plik2;
    FILE *plik3;

    plik1 = fopen("matrix1.txt", "r");
    plik2 = fopen("matrix2.txt", "r");
    plik3 = fopen("matrixW.txt", "w");

    fscanf(plik1, "%d %d", &w1, &k1);
    fscanf(plik2, "%d %d", &w2, &k2);
    printf("Ilosc wierszy pierwszej macierzy: %d\nIlosc kolumn pierwszej macierzy: %d\n\nIlosc wierszy drugiej macierzy: %d\nIlosc kolumn drugiej macierzy: %d\n\n", w1, k1, w2, k2);


    if (k1 == w2)
    {
         macierz1 = (float **) malloc (w1 * sizeof(float *));
         for (int i = 0; i < w1; i++)
         {
            macierz1[i] = (float *) malloc(k1 * sizeof(float));
         }

         macierz2 = (float **) malloc (w2 * sizeof(float *));
         for (int i = 0; i < w2; i++)
         {
             macierz2[i] = (float *) malloc (k2 * sizeof(float));
         }

         for (int i = 0; i < w1; i++)
         {
             for (int j = 0; j < k1; j++)
             {
                 fscanf(plik1, "%f", &liczba);
                 macierz1[i][j] = liczba;
             }
         }

         for (int k = 0; k < w2; k++)
         {
             for (int l = 0; l < k2; l++)
             {
                 fscanf(plik2, "%f", &liczba);
                 macierz2[k][l] = liczba;
             }
         }

         printf("Wczytana macierz A: \n\n");

         for (int i = 0; i < w1; i++)
         {
             for (int j = 0; j < k1; j++)
             {
                 printf("%.1f   ", macierz1[i][j]);
             }
             printf("\n\n");
         }
         printf("\n");

         printf("Wczytana macierz B: \n\n");

         for (int k = 0; k < w2; k++)
         {
             for (int l = 0; l < k2; l++)
             {
                 printf("%.1f   ", macierz2[k][l]);
             }
             printf("\n\n");
         }
         printf("\n");

         printf("Macierz C bedaca iloczynem A i B wynosi:\n\n");
         for (int x1 = 0; x1 < w1; x1++)
         {
             for (int x4 = 0; x4 < w1; x4++)
             {
                 float c = 0;
                 for (int x23 = 0; x23 < k1; x23++)
                 {
                     c = c + macierz1[x1][x23] * macierz2[x23][x4];
                 }
                 printf("%.1f   ", c);
                 fprintf(plik3, "%.1f   ", c);
             }
             printf("\n\n");
             fprintf(plik3,"\n\n");
         }
         printf("\n");
         printf("Macierz C zostala zapisana do pliku matrixW.txt \n\n");


         for (int i = 0; i < w1; i++)
         {
             free(macierz1[i]);
         }
         free(macierz1);

         for (int i = 0; i < w2; i++)
         {
             free(macierz2[i]);
         }
         free(macierz2);
    }
    else
    {
        printf("Wymnozenie tych macierzy nie jest mozliwe");
    }

    fclose(plik1);
    fclose(plik2);
    fclose(plik3);

    scanf("%d", &stop);
    return 0;
}
1

c = c + macierz1[x1][x23] * macierz2[x23][x4];
Gdzie tu jest przypisywanie elementów macierzy wynikowej? c powinno być macierzą i w pętli maja lecieć jego odpowiednie indeksy.

1

Znalazłem błąd przy określaniu liczby kolumn wynikowej macierzy. Wynikowa macierz ma tyle kolumn, co drugi czynnik.
Zmień

for (int x4 = 0; x4 < w1; x4++) 

na

for (int x4 = 0; x4 < k2; x4++)
0

Bardzo proszę o jeszcze jedną pomoc. Chciałbym zamienić ten fragment na funkcję, ale nie wiem do końca jak to prawidłowo zapisać, przez co nie mogę poprawić wyskakujących błędów, które tyczą się argumentów funkcji, które są wskaźnikami(**macierz i *plik):

macierz1 = (float **) malloc (w1 * sizeof(float *));
         for (int i = 0; i < w1; i++)
         {
            macierz1[i] = (float *) malloc(k1 * sizeof(float));
         }

         macierz2 = (float **) malloc (w2 * sizeof(float *));
         for (int i = 0; i < w2; i++)
         {
             macierz2[i] = (float *) malloc (k2 * sizeof(float));
         }

Próbuję w ten sposób:

void Alokacja(float **macierz, int w, int k)
{
   macierz = (float **) malloc (w * sizeof(float *));
         for (int i = 0; i < w; i++)
         {
            macierz[i] = (float *) malloc(k * sizeof(float));
         }
}

Wywołując potem w main() tak:

Alokacja(**macierz1, w1, k1);
Alokacja(**macierz2, w2, k2);

Oraz ten fragment na drugą funkcję:

for (int i = 0; i < w1; i++)
         {
             for (int j = 0; j < k1; j++)
             {
                 fscanf(plik1, "%f", &liczba);
                 macierz1[i][j] = liczba;
             }
         }

         for (int k = 0; k < w2; k++)
         {
             for (int l = 0; l < k2; l++)
             {
                 fscanf(plik2, "%f", &liczba);
                 macierz2[k][l] = liczba;
             }
         }

Próbując w ten sposób:

float Wczytanie(FILE *plik, int w, int k, float **macierz)
{
   float liczba;
   for (int i = 0; i < w; i++)
         {
             for (int j = 0; j < k; j++)
             {
                 fscanf(plik, "%f", &liczba);
                 macierz[i][j] = liczba;
             }
         }
return (macierz[w][k]);
}

Wywołując potem w main() tak:

Wczytanie(*plik1, w1, k1, **macierz1);
Wczytanie(*plik2, w2, k2, **macierz2);
1

Na początek, funkcja alokacja musi wyglądać odrobinę inaczej

void Alokacja(float ***macierz, int w, int k)
{
		*macierz = malloc (w * sizeof(float *));
		 for (int i = 0; i < w; i++)
		 {
			(*macierz)[i] = malloc(k * sizeof(float));
		 }
}

Mając samo float **macierz, jest się w stanie przekazać kopię lokalną wskaźnika, lecz nie dałoby się go zmodyfikować globalnie, co uniemożliwiałoby wykorzystanie zaalokowanej pamięci w dalszej części programu.

Jej wywołanie powinno być odpowiednio

		Alokacja(&macierz1, w1, k1);
		Alokacja(&macierz2, w2, k2);

Wywołanie funkcji Wczytanie

		Wczytanie(plik1, w1, k1, macierz1);

1 użytkowników online, w tym zalogowanych: 0, gości: 1