Oczywiście jak to zwykle w tym dziale przed analizą zamieszczonego kodu trzeba go koniecznie sformatować...:
Kopiuj
type
TTab = array of array of array of double;
TStr = string;
TWczytaj = class(TObject)
public
Date: TStr;
Name: TStr;
TabSkatBRDF: array of array of array of double;
function Sprawdz(Naglowek: string; Open: TOpenDialog): Integer;
end;
procedure TFrmMain.Otworz1Click(Sender: TObject);
var
Wczytaj: TWczytaj;
S : String;
TF: TextFile;
begin
S := '#Data Generated By Imaging Sphere Version: 1.4.34.0';
if Wczytaj.Sprawdz(s, OpnBRDF1) = 1 then
begin
Memo1.Lines.Add('dobrze!!!');
AssignFile(TF, OpnBRDF1.FileName);
Reset(TF);
Readln(TF, s);
Readln(TF, s);
Wczytaj.Date := s;
Readln(TF, s);
Wczytaj.Name := s;
end
else
MessageBox(Handle, 'Nieodpowieni format pliku!', 'WRONG!', MB_OK or MB_ICONERROR);
end;
Teraz cokolwiek przynajmniej widać...
Po pierwsze - zadeklarowany masz typ TTab
, z którego w ogóle nie korzystasz, a pole klasy TabSkatBRDF
jest dokładnie tego typu - pewnie zapomniałeś podmienić nazwę typu;
Po drugie - deklarujesz alias TStr = String
- jest to niepotrzebne; Oczywiście można to wykorzystywać, ale aliasy służą jedynie do zwiększenia czytelności kodu (choć TStr
jest mniej intuicyjne niż wszystkim znany i szanowany String
);
Po trzecie - zapewne nie przeczytałeś żadnego kursu na temat programowania obiektowego dlatego nie wiesz, że obiekt trzeba utworzyć w pamięci żeby można było z niego korzystać, analogicznie po zakończeniu pracy z danym obiektem trzeba go z pamięci usunąć - służą do tego konstruktor i destruktor; Ty nie masz w ogóle zadeklarowanego ani konstruktora, ani dekstruktora (oczywiście można wykorzystać odziedziczony konstruktor / destruktor i nie deklarować własnych, ale za ich pomocą obiekt i tak trzeba utworzyć i zwolnić z pamięci);
Po czwarte - w deklaracji klasy podana jest deklaracja metody Sprawdz
, jednak nie podałeś jej definicji - skąd mamy wiedzieć, że to właśnie w ciele tej metody nie jest powodowany wyjątek...? Zamieść jego definicję jeśli dalej nie możesz znaleźć błędu;
Po piąte - wykorzystujesz wcześniej wspomniany obiekt bez jego utworzenia w pamięci, więc w tym momencie na pewno otrzymasz Access Violation
; Zasadę korzystania z obiektów musisz poznać - przeczytaj podstawy programowania obiektowego (OOP) z linku, który Ci wcześniej podałem a będziesz wiedział w czym tkwi błąd;
Po szóste - wykorzystujesz przekazywany przez argument metody Sprawdz
obiekt klasy TOpenDialog
- dziwna jest taka konstrukcja; Ja osobiście wolę nie kłaść tego komponentu na formularz - zadeklarować sobie lokalną zmienną i ręcznie ją utworzyć, ustawić wartości interesującym mnie polom i wywołać metodę Execute
, sprawdzić jej rezultat i pobrać ścieżkę z obiektu; Jeśli musisz wykorzystać ten dialog w kilku miejscach w programie to polecam napisać sobie prostą funkcję, w której będziesz wykorzystywał taki obiekt i zwracał ścieżkę, a w argumentach podasz informacje dla pól obiektu; Ale to wykonasz dopiero jak nauczysz się podstaw obiektówki;
Po siódme - wykorzystujesz zmienną plikową jednak konstrukcja jest nienajlepsza - jeżeli wykorzystujesz pliki to pakuj je do bloku try .. finally .. end
- jest bezpieczniej; To samo tyczy się tworzenia obiektów w danej procedurze / funkcji / metodzie jeśli są one lokalne - warto stosować ten blok oraz w niektórych przypadkach try .. except .. end
dla przechwytywania wyjątków; Dzięki temu zauważyłbyś, że wykorzystujesz tą zmienną, otwierasz plik do odczytu, czytasz dwie linie i nie zamykasz pliku (procedura CloseFile), stąd powodujesz wycieki pamięci; Prawidłowy blok operacji na pliku powinien wyglądać tak:
Kopiuj
AssignFile(TF, OpnBRDF1.FileName);
try
Reset(TF);
Readln(TF, s);
Readln(TF, s);
Wczytaj.Date := s;
Readln(TF, s);
Wczytaj.Name := s;
finally
CloseFile(TF)
end;
Po ósme - w ww. bloku wykonujesz pod rząd dwa razy wczytanie bieżącej linii z pliku, stąd pierwszej linii nigdy nie będziesz mógł wykorzystać, bo do pola Wczytaj.Date
zawsze trafi druga linia, a do pola Wczytaj.Name
zawsze trzecia;
Tak więc podsumowując najpierw przejrzyj temat programowania obiektowego (głównie o konstruktorach i destruktorach), poczytaj o dynamicznym tworzeniu obiektów (przyda się do tworzenia procedury / funkcji wywołującej okno dialogowe - ale to jako ciekawostkę), o bloku try .. finally .. end
i try .. except .. end
i o procedurze CloseFile
; Potem zabierz się za kodzenie, a jeśli dalej nie będziesz mógł odnaleźć błędów to poczytaj także o debugowaniu aplikacji w Delphi - to musisz się nauczyć żeby usamodzielnić się trochę;