Witajcie.
Mam pewien problem. Zrobiłem program, który odczytuje z pliku rozmiar macierzy kwadratowej oraz jej elementy i liczy wyznacznik wczytanej macierzy. Program działa, ale potrzebuje jeszcze zrobić zabezpieczenia przed głupotą ludzką.
- Aby wczytywany rozmiar nie był literą .
- Aby element macierzy nie był literą.
- Aby nie było za mało elementów macierzy.
- Aby nie było za dużo elementów macierzy.
Prowadzący zajęcia wspomniał coś o funkcji fscanf przy wczytywaniu ale nie za bardzo wiem co ona zwraca i jak to do zabezpieczeń wykorzystać. Poniżej wklejam wczytywany plik i kod w języku C. Ochrona ta ma być zawarta w funkcji double **Wczytywanie(int *rozmiar){}
Z góry dziękuje za pomoc.
wczytywany plik o nazwie "macierz.txt"
5
4 6 8 10 12
1 2 4 8 5
2 9 6 8 6
3 5 7 9 7
2 4 6 8 10
Plik C
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double **Alokacja(int rozmiar);
double **Wczytywanie(int *rozmiar);
double Wyznacznik(int rozmiar, double **buffor);
double Sarusa(int rozmiar, double **buffor);
double Tworz_Minor(int rozmiar, double **buffor, int ktory_minor); // tworzy minor i liczy jego wyznacznik
void Zwalnianie(int rozmiar, double **buffor);
int main()
{
int rozmiar = 0;
double **buffor = Wczytywanie(&rozmiar);
printf("Wyznacznik tej macierzy to: %lf\n", Wyznacznik(rozmiar, buffor));
Zwalnianie(rozmiar, buffor);
getchar();
return 0;
}
void Zwalnianie(int rozmiar, double **buffor)
{
for (int i = 0; i < rozmiar; i++)
{
free(buffor[i]);
}
free(buffor);
}
double **Alokacja(int rozmiar)
{
double **tab2 = NULL;
tab2 = (double**)malloc(rozmiar * sizeof(double*));
int i;
for (i = 0; i < rozmiar; i++)
{
tab2[i] = (double*)malloc(rozmiar * sizeof(double));
}
return tab2;
}
double **Wczytywanie(int *rozmiar)
{
FILE *plik;
if ((plik = fopen("macierz.txt", "r")) == NULL)
{
printf("Nie mozna otworzyc pliku\n");
fclose(plik);
getchar();
exit(1);
}
fscanf(plik, "%d\n", rozmiar);
double **tab = Alokacja(*rozmiar);
int i, j = 0;
for (i = 0; i < *rozmiar; i++)
{
for (j = 0; j < *rozmiar; j++)
{
fscanf(plik, "%lf", &tab[i][j]);
printf("%lf ", tab[i][j]);
}
printf("\n");
}
fclose(plik);
return tab;
}
double Sarusa(int rozmiar, double **buffor)
{
double wyznacznik = 0;
wyznacznik += buffor[0][0] * buffor[1][1] * buffor[2][2];
wyznacznik += buffor[1][0] * buffor[2][1] * buffor[0][2];
wyznacznik += buffor[2][0] * buffor[0][1] * buffor[1][2];
wyznacznik -= buffor[2][0] * buffor[1][1] * buffor[0][2];
wyznacznik -= buffor[2][1] * buffor[1][2] * buffor[0][0];
wyznacznik -= buffor[2][2] * buffor[1][0] * buffor[0][1];
return wyznacznik;
}
double Tworz_Minor(int rozmiar, double **buffor, int ktory_minor)
{
double wyznacznik_minora = 0;
double **minor = Alokacja(rozmiar);
for (int q = 0; q < rozmiar; q++) //wypelnienie minora
{
int flaga = 0;
for (int w = 0; w < rozmiar; w++)
{
if (w == ktory_minor) flaga++;
minor[q][w] = buffor[q + 1][flaga]; //q+1 bo pierwszy wiersz usuwamy
flaga++;
}
}
int potega = 1 + ktory_minor + 1; // 1 i k_m + 1 bo macierze numeruje sie od 1
wyznacznik_minora += (int)pow(-1.0, potega) * buffor[0][ktory_minor] * Wyznacznik(rozmiar, minor);
Zwalnianie(rozmiar, minor);
return wyznacznik_minora;
}
double Wyznacznik(int rozmiar, double **buffor)
{
if (rozmiar == 1) return 1;
else if (rozmiar == 2)
{
return (buffor[0][0] * buffor[1][1]) - (buffor[0][1] * buffor[1][0]);
}
else if (rozmiar == 3)
{
return Sarusa(rozmiar, buffor);
}
else if (rozmiar >= 4)
{
double suma_wyznacznikow = 0;
double wyznacznik_minora;
for (int i = 0; i < rozmiar; i++)
{
wyznacznik_minora = 0;
wyznacznik_minora = Tworz_Minor(rozmiar - 1, buffor, i);
suma_wyznacznikow += wyznacznik_minora;
}
return suma_wyznacznikow;
}
}