Witam wszystkich,
Mam problem ze swoim programem.
Założenia są takie, że program ma wczytać z pliku listę osób z przypisanym numerem lotu, numerem miejsca i danymi pasażera, a następnie utworzyć strukturę dynamiczną i ją wyświetlić. Ma to być drzewo list, w którym węzłem jest numer lotu, a w liście mają być przyporządkowani pasażerowie danego lotu, posortowani względem numeru miejsca.
Z wczytaniem danych, ze strukturą drzewa oraz z procedurą wyświetlenia węzłów i listy już sobie poradziłem. Na razie jest to rekurencja, ale zmienię to niedługo na coś lepszego ;) Problem mam jednak w czymś innym - w dodawaniu autosortującym do listy.
Program kompiluje się poprawnie, jednak wywala błąd External: SIGSEGV i Lazarus podświetla jedną z linijek (zaznaczyłem to w kodzie). Męczę się z tym już 3 dzień, ale nie umiem tego naprawić. Co jest nie tak w tej procedurze WstawDoListy?
Kod:
program loty;
uses
Sysutils, interfejs, crt;
type
Lot = record
nrlotu, imie, nazwisko : String;
nrrezerwacji, nrmiejsca, key: Integer;
end;
PList = ^TList;
TList = record
dane: lot;
key: integer;
next: PList;
end;
PNode = ^TNode;
TNode = record
key: string;
wsklista: PList;
left, right: PNode;
end;
procedure WstawDoListy(var glowa: PList; rekord: lot);
var
nowa, tmp, prev:PList;
begin
new(nowa);
nowa^.dane:=rekord;
nowa^.next:=NIL;
while ((tmp<>NIL) or (tmp^.dane.nrmiejsca<rekord.nrmiejsca)) do
begin
prev:=tmp;
tmp:=tmp^.next; // <-- ta linijka jest podswietlana po wyswietleniu bledu External: SIGSEGV
end;
if (glowa = NIL ) then
glowa:=nowa
else if (tmp=NIL) then
prev^.next:=nowa
else if (tmp^.dane.nrmiejsca=rekord.nrmiejsca) then
writeln('Blad w pliku: Pasazer o takim samym numerze miejsca juz istnieje')
else
begin
glowa:=nowa;
nowa^.next:=tmp;
end;
end;
procedure WstawdoStruktury(var root: PNode; var rekord:lot);
var
element,elementnext,tmp: PList;
begin
if root = NIL then
begin
new(root);
root^.key := rekord.nrlotu;
WstawDoListy(element, rekord);
root^.wsklista := element;
root^.right:=NIL;
root^.left:=NIL;
end
else
if root^.key = rekord.nrlotu then WstawdoListy(element, rekord);
if root^.key < rekord.nrlotu then WstawdoStruktury(root^.left, rekord);
if root^.key > rekord.nrlotu then WstawdoStruktury(root^.right, rekord);
end;
procedure WyswietlListe (glowa: PList);
var
tmp: PList;
begin
tmp := glowa;
while (tmp<>NIL) do
begin
writeln(tmp^.dane.nrmiejsca, ' ', tmp^.dane.nrrezerwacji, ' ', tmp^.dane.imie, ' ', tmp^.dane.nazwisko);
tmp:= tmp^.next;
end;
end;
procedure WyswietlDrzewo(p: PNode);
begin
if p<>NIL then
begin
WyswietlDrzewo(p^.left);
Writeln('Wezel: ',p^.key);
WyswietlListe(p^.wsklista);
WyswietlDrzewo(p^.right);
end;
end;
{jest to glowna procedura uruchamiajaca podrzedne tak, aby zrealizowac funkcje programu}
{procedura wczytuje dane z pliku i zapisuje je do rekordow}
procedure WczytaniezPliku(plik:string; niecmd:boolean);
var
Rekord: lot;
p : Text; {p - od plik}
Linia : String;
root: PNode;
begin
root := NIL;
if FileExists(plik) then
begin
AssignFile(p,plik);
Reset(p);
while not eof(p) do
begin
ReadLn(p,Linia);
SScanf(Linia,'%s %d %d %s %s',[@Rekord.nrlotu,@Rekord.nrrezerwacji,@Rekord.nrmiejsca,@Rekord.imie,@Rekord.nazwisko]);
WstawDoStruktury(root, rekord);
// wpisanie do drzewa list (jezeli lot istnieje to wstaw pasazera do danego lotu)
end;
Close(p);
WyswietlDrzewo(root);
end
else Writeln('Blad: Plik "',plik,'" nie istnieje.');
if niecmd then readln;
end;
begin
WczytaniezPliku('plik.txt',true);
end.
Zawartość pliku (dajmy na to plik.txt) wygląda tak:
FL345X 323 5 Jan Kowalski
GL2225 233 3 Adam Nowak
GPS325 263 2 Janusz Korwin-Mikke
FL345X 221 1 Michal Kowalski
GL2225 123 4 Wojciech Niski
GL2225 135 2 Elvis Presley
Byłbym ogromnie wdzięczny gdyby ktoś mi pomógł. Z góry dziękuję!
Pozdrawiam
EDIT: Poprawiłem trochę czytelność kodu