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, botów: 0