Zabezpieczenie przed wczytywaniem znaków i nie tylko.

0

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ą.

  1. Aby wczytywany rozmiar nie był literą .
  2. Aby element macierzy nie był literą.
  3. Aby nie było za mało elementów macierzy.
  4. 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;
	}
} 
0

Pewnie sam to znalazłeś, ale co tam.
http://www.cplusplus.com/reference/cstdio/fscanf/
int fscanf ( FILE * stream, const char * format, ... );
do funkcji podajesz dwa parametry, wskaźnik na plik i.... format o którym jest cała tabelka , który to może występować w kilku parametrach. To on pozwala sprawdzić, czy znak jest liczbą, literą, liczba typu float... itp na dole jest krótki przykład na pewno się zorientujesz.

0

nie wiem czy widziałeś mój program ale tam użyłem fscanf wczytując %lf . I nawet jak wstawie znak to wyświetli mi dużą liczbe na minusie , która będzie sie mieściła w double więc to raczek nie zadziała.

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