Problem zapisem/odczytem listy.

0

Witam, nie mogę sobie poradzić z zapisem i odczytem w moim programie, może ktoś z Was znajdzie błąd:

Program Dziennik;

Uses
crt, sysutils;

type
pOsoba=^Osoba; //przechowuje osoby
Osoba=record
imie: string;
nazwisko: string;
uwagi: array[0..19] of string;
oceny: array[0..2,0..19] of integer;
nastepny: pOsoba;
end;

procedure Odczyt(var poczatek:pOsoba); //odczyt danych z pliku, zapis dziala tak samo
var suwak: pOsoba;
//nowaos: pOsoba;
plik: file of pOsoba;
//i: integer;
nowy: pOsoba;
begin
assign(plik, 'osoby.dat');
reset(plik);
while EOF(plik)=false do
begin
if poczatek = NIL then begin
new(poczatek);
read(plik,poczatek);
poczatek^.nastepny:=NIL;
end
else begin
suwak:=poczatek;
while suwak^.nastepny<>NIL do
suwak:=suwak^.nastepny;
new(nowy);
read(plik,nowy);
nowy^.nastepny:=NIL;
suwak^.nastepny:=nowy;
end;
end;
close(plik);
end;

procedure Zapis(poczatek:pOsoba);
var suwak: pOsoba;
plik: file of pOsoba;
begin
assign(plik, 'osoby.dat');
rewrite(plik);
suwak:=poczatek;
while suwak^.nastepny<>NIL do begin
write(plik,suwak);
suwak:=suwak^.nastepny;
end;
write(plik,suwak);
close(plik);
end;

1

Problem w zapisie:
while suwak^.nastepny<>NIL do begin
Jak chcesz zapisać do notatnika listę osób stojących w kolejce to czy wymagasz aby osoba miała kogoś za sobą?

0

Przepraszam za tamten kod, ale przez masę kombinowania i edycji nie był on właściwy. Poniżej wklejam właściwy kod. Problem polega na tym, że w momencie zapisu nowodopisane elementy w liście mają konkretne wartości, a po odczycie już wszystko jest puste. Liczba elementów zgadza się, ale są one puste. Zapis następujena końcu programu, a odczyt na początku.

type
pOsoba=^Osoba; //przechowuje osoby
Osoba=record
imie: string;
nazwisko: string;
uwagi: array[0..19] of string;
oceny: array[0..2,0..19] of integer;
nastepny: pOsoba;
end;

procedure Odczyt(var poczatek:pOsoba); //odczyt danych z pliku, zapis dziala tak samo
var suwak: pOsoba;
//nowaos: pOsoba;
plik: file of pOsoba;
//i: integer;
nowy: pOsoba;
begin
assign(plik, 'osoby.dat');
reset(plik);
while EOF(plik)=false do
begin
if poczatek = NIL then begin
new(poczatek);
read(plik,poczatek);
poczatek^.nastepny:=NIL;
end
else begin
suwak:=poczatek;
while suwak^.nastepny<>NIL do
suwak:=suwak^.nastepny;
new(nowy);
read(plik,nowy);
nowy^.nastepny:=NIL;
suwak^.nastepny:=nowy;
end;
end;
close(plik);
end;

procedure Zapis(poczatek:pOsoba);
var suwak: pOsoba;
plik: file of pOsoba;
begin
assign(plik, 'osoby.dat');
rewrite(plik);
suwak:=poczatek;
while suwak^.nastepny<>NIL do begin
write(plik,suwak);
suwak:=suwak^.nastepny;
end;
write(plik,suwak);
close(plik);
end;

0

Przy zapisie sprawdź czy argument Poczatek nie jest nil i jeśli nie jest - ustaw pętlę repeat zapisującą osobę until suwak = nil - coś w tym stylu:

procedure Zapis(Poczatek: POsoba);
var
  Suwak: POsoba;
  Plik: file of Osoba;
begin
  Assign(Plik, 'osoby.dat');
  ReWrite(Plik);
  Suwak := Poczatek;

  while Suwak <> nil then
  begin
    Write(Plik, Suwak^);
    Suwak := Suwak^.Nastepny;
  end;

  Close(Plik);
end;

Nie wiem także czy nie powinnaś określić RecSize w procedurze ReWrite, jednak teraz nie mam jak sprawdzić poprawności;

Poza tym popraw formatowanie, a kod wklej w znaczniki <code class="deplhi"></code>;


EDIT: poza tym jeśli chcesz zapisać struktury w ten sposób to określ długość dla wszystkich łańcuchów;
EDIT 2: poprawiłem kod żeby plik był czyszczony jak lista jest pusta;

0

@Magda_2608: jako dziewczynie, napiszę delikatnie. Twoje "formatownie" jest w tak zwanym stylu "z pupeczki" ;) Formatuj kod po ludzku. Jeżeli nie umiesz tego robić sama, to skorzystaj z JEDI Code Formatter lub innych tego typu narzędzi do znalezienia w google. Poza tym kod wstawiaj w tagi delphi. Forumowicze byli i tak, na tyle uprzejmi, że Tobie odpowiedzieli. Ale czytając taki kod - po prostu człowiek się meczy i utrudnia się zadanie potencjalnym zainteresowanm sprawną pomocą przez odpowiedź Tobie i respektowania ogólnych zasad wstawiania kodu na fora programistyczne. To Twój pierwszy wątek tutaj, dlatego chciałem uczulić Ciebie na przyszłość abyś stosowała dobre nawyki, ułatwiając w przyszlosci zycie nam jak i sobie.

2

@furious programming porównaj te dwa kody:

  if Poczatek <> nil then
  begin
    Suwak := Poczatek;
 
    repeat
      Write(Plik, Suwak^);
      Suwak := Suwak^.Nastepny;
    until Suwak = nil;
  end;
  Suwak:=Poczatek;
  while Suwak<>nil do
  begin
    Write(Plik,Suwak^);
    Suwak:=Suwak^.Nastepny;
  end;

może coś zauważysz. W pierwszym złamana zasada DRY, dwa razy porównujesz Suwak z nil, o tym że jest dłuższy już nie wspominam.

1

Po mojemu to pierwszy błąd jaki widzę to stosowanie string w rekordzie musi być to string ograniczony do pewnej ilości znaków np.:

type
  pOsoba=^Osoba;  //przechowuje osoby
  Osoba=record
    imie: string[40]; //nie moze by string
    nazwisko: string[40];
    uwagi: array[0..19] of string[255];
    oceny: array[0..2,0..19] of integer;
    nastepny: pOsoba;
  end;

a co poza tym to jeszcze nie wiem...

plik: file of pOsoba;
chyba
plik: file of Osoba;
i tak samo masz odczytywać i zapisywąć Osoba nie pOsoba

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