Popracuj nad estetyką kodu
Funkcja wczytaj jest mocno przekombinowana i trudno stwierdzić czy będzie działała prawidłowo. Dobrze też żeby zwracała czy wczytywanie się powiodło.
Kod:
bool wczytaj(const char* nazwa_pliku, double** &dane, int &wiersze, int &kolumny)
{
ifstream plik(nazwa_pliku);
if(!plik)
{
cerr << "Nie udało się otworzyć pliku " << nazwa_pliku << endl;
return false; //jeśli nie udało się otworzyć pliku to zwraczasz niepowodzenie
}
plik >> wiersze >> kolumny; //pobranie rozmiarów macierzy
dane = new double*[wiersze];
for(int i = 0; i < wiersze; ++i)
dane[i] = new double[kolumny]; //alokacja pamięci
for(int i = 0; i < wiersze; ++i)
for(int j = 0; j < kolumny; ++j)
plik >> dane[i][j]; //pobieranie danych
return true; //operacja zakończona sukcesem
}
Poza tym zamiast szatkować pamięć, możesz zapisywać wszystkie wiersze w jednym kawałku pamięci, wtedy nie potrzebujesz dodatkowej funkcji do zwalniania, tylko możesz użyć po prostu delete[]
Kod:
bool wczytaj(const char* nazwa_pliku, double* &dane, int &wiersze, int &kolumny)
{
/*...*/
dane = new double[wiersze*kolumny]; //alokacja pamięci
for(int i = 0; i < wiersze; ++i)
for(int j = 0; j < kolumny; ++j)
plik >> dane[i * kolumny + j]; //pobieranie danych
return true; //operacja zakończona sukcesem
}
Kod pobierający dane można wtedy trochę uprościć
Kod:
for(int i = 0; i < wiersze*kolumny; ++i)
plik >> dane[i];
Zamiast ręcznego zarządzania pamiecią możesz użyć vectora, wtedy nie musisz niczego zwalniać, bo vector zrobi to za ciebie gdy wyjdziesz poza zakres jego istnienia
Kod:
bool wczytaj(const char* nazwa_pliku, vector<double> &dane, int &wiersze, int &kolumny)
{
/*...*/
dane.resize(wiersze*kolumny); //zmiana rozmiaru wektora
for(int i = 0; i < wiersze*kolumny; ++i)
plik >> dane[i]; //pobieranie danych
return true; //operacja zakończona sukcesem
}
Przydałoby się też oprócz sprawdzania czy udało sie otworzyć plik, także sprawdzać czy udało się odczytać dane z pliku (plik może być uszkodzony albo coś)
Kod:
bool wczytaj(const char* nazwa_pliku, vector<double> &dane, int &wiersze, int &kolumny)
{
ifstream plik(nazwa_pliku);
if(!plik)
{
cerr << "Nie udało się otworzyć pliku " << nazwa_pliku << endl;
return false;
}
plik >> wiersze >> kolumny;
if(!plik)
{
cerr << "Nie udało się pobrać rozmiarów macierzy" << endl;
return false;
}
dane.resize(wiersze*kolumny);
for(int i = 0; i < wiersze*kolumny; ++i)
plik >> dane[i];
if(!plik)
{
cerr << "Nie udało się pobrać wszystkich danych" << endl;
dane.clear(); //Przy ręcznym zarządzaniu pamięcią musisz zwolnić zaalokowaną pamięć. W przypadku vectora nie jest to konieczne ale nie zaszkodzi.
return false;
}
return true;
}
istream (a więc także ifstream, który dziedziczy po istream) staje się fałszywy gdy ostatni odczyt nie powiódł się.
Napisał
Gosik
Bede wdzieczna za wszlkie slowa krytyki.
Mam nadzieję, że nie piszesz słabego kodu tylko po to by Cię krytykowano