Baza danych - edycja wpisów

0

Witam. Do napisania mam program pod tytułem : "Książka kucharska". Aktualnie udało mi się napisać część odpowiedzialną za dodawanie elementów, wyszukiwanie (według podanych przez użytkownika składników). Mam mianowicie problem z usuwaniem wybranego sładnika i usuwaniem całych potraw. Typy są takie :

   
program ksiazka_new;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
    {rekord nagłówkowy}
    TPotrawa = record
                     ID    : word;         {identyfikator potrawy}
                     Nazwa : string[255];  {nazwa potrawy}
                     Opis  : string[255];  {opis potrawy}
               end;

    TSkladnik = record
                     ID    : word;         {identyfikator skladnika}
                     Nazwa : string[255];  {nazwa skladnika}
                     Ilosc : single;       {ilosc skladnika np. 2 jajka}
                end;

    {Lista potraw}
    PListaPotraw = ^TListaPotraw;
    TListaPotraw = record
                         Potrawa : TPotrawa;       {zmienna typu rekordowego}
                         nast    : PListaPotraw;   {wskaźnik na następny}
                         pop     : PListaPotraw;   {wskaźnik na poprzedni}
                   end;

    {Lista skladników}
    PListaSkladnikow = ^TListaSkladnikow;
    TListaSkladnikow = record
                             Skladnik : TSkladnik;   {zmienna typu rekordowego}
                             nast     : PListaSkladnikow; {wskaźnik na następny}
                             pop      : PListaSkladnikow; {wskaźnik na poprzedni}
                       end;

Dodawanie potraw i składników wygląda tak :

procedure dodaj_potrawe(pamiec : TPotrawa);
begin
     if ListaPotraw = nil then
        begin
             new(ListaPotraw);
             ListaPotraw^.nast    := nil;
             ListaPotraw^.pop     := nil;
             ListaPotraw^.Potrawa := pamiec;
        end
     else
        begin
             ustaw_potrawy(true);
             new(ListaPotraw^.nast);
             ListaPotraw^.nast^.pop  := ListaPotraw;
             ListaPotraw             := ListaPotraw^.nast;
             ListaPotraw^.nast       := nil;
             ListaPotraw^.Potrawa    := pamiec;
        end;
end;


procedure dodaj_skladniki(pamiec : TSkladnik);
begin
     if ListaSkladnikow = nil then
        begin
             new(ListaSkladnikow);
             ListaSkladnikow^.nast     := nil;
             ListaSkladnikow^.pop      := nil;
             ListaSkladnikow^.Skladnik := pamiec;
        end
     else
        begin
             ustaw_skladniki(true);
             new(ListaSkladnikow^.nast);
             ListaSkladnikow^.nast^.pop := ListaSkladnikow;
             ListaSkladnikow            := ListaSkladnikow^.nast;
             ListaSkladnikow^.nast      := nil;
             ListaSkladnikow^.Skladnik  := pamiec;
        end;
end;

skladniki dodawane sa do tablicy :

if AnsiSameText(polecenie, 'DODAJ') then
      begin
        Potrawa.ID := tworz_identyfikator;
        writeln('Wpisz nazwe potrawy. Wpisz #exit aby anulowac.');
        write('Nazwa : ');
        readln(znak);
        if znak = '#exit' then
          exit;
        Potrawa.Nazwa := znak;

        Skladnik.ID := Potrawa.ID;
        writeln('Wpisz kolejno skladniki i ilosc. Aby zakonczyc wpisz #end. ');
        while znak <> '#end' do
            begin
                write('Nazwa skladnika : ');
                readln(znak);
                if znak <> '#end' then
                    begin
                        Skladnik.Nazwa := znak;
                        write('Ilosc skladnika : ');
                        readln(i_znak);
                        Skladnik.Ilosc := i_znak;
                        dodaj_skladniki_do_pliku(Skladnik);
                    end;
            end;
        dodaj_potrawe_do_pliku(Potrawa);
        zwolnij_pam;
        laduj_potrawy;
        laduj_skladniki;
        writeln('Zaladowano '+IntToStr(Skladniki)+' skladnikow w '+IntToStr(Potrawy)+' potrawach.');
        exit;
      end;

Bardzo prosił bym o pomoc w rozwiązaniu tego problemu. Jeżeli nie na forum to podaj mój e-mail :

Z góry dziękuje za wszelką pomoc.
Pozdrowienia

0

ja to bym przede wszyskim zastosowal tablice dynamiczne zamiast wskaznikow.
jest to baaaardzo proste.

rozumiem ze TPotrawa jest jednym elemntem bazy(rekoredm) a a PListaPotraw jest ta wlasnie baza?
jesli tak to zmien z:

PListaPotraw = ^TListaPotraw;

na

PLista = array of TSkladnik;

taka tablica jest indeksowana od 0.
a w kodzie zamiast kilku(nastu) linijek zeby dodac nowy element piszesz tylko:

SetLength(Nazwa_Tablicy,length(Nazwa_Tablicy)+1); //ustawiasz dlugosc tablicy na o 1 dluzsza
NazwaTablicy[High(Nazwa_Tablicy)] := Nowy_Element; //high() zwraca nr ostatniej komorki tablicy

No a usuniecie jakiegos elementu tez nie sprawi problemow gdzy:

repeat
 i := i+1;
 if Nazwa_Tablicy[i] = Element_Do_Usuniecia then nr := i; //jesli znajdziemy usowany to zapamietujemy jego pozycje
 if nr > i then Nazwa_Tablicy[i-1] := NazwaTablicy[i] //wszystkie elementy powyzej kasowanego przesuwamy o jeden do poczatku.
untli i = length(Nazwa_Tablicy); //dopuki nie przejdziemy calej tablicy
Setlength(Nazwa_Tablicy,Lemgth(Nazwa_Tablicy)-1); //skracamy tablice po wyrzuceniu jednego elementu

jest to moze pewna nowosc i moze odstraszac ale na prawde WARTO sie tym poslugiwac.

P.S.
A z Twojego programu usunac element tez jest nie trudno:

  1. idziesz po koleii az znajdziesz element ktory chcesz usunac;
  2. pamietasz wskaznika na element ktory wskazuje na ten ktory chcesz usunac
  3. patrzysz na jaki element wskazuje ten ktorego chcesz usunac
  4. wartosc wskaznika z punktu 3 wstawiasz do wskaznika z punktu 2
  5. zwalniasz pamiec ze wskaznika z pubktu 3
    i juz:)

pozdrawiam

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