Klasické dávkové zpracování souborů
Algoritmus aktualizace
 Tisk

Algoritmus aktualizace


Klasickým zpracováním je program TELEF. Zde jsou definovány proměnné, které indikují stav obou vstupních souborů INDOLD a INDUPD s možnými stavy:



Obecná pravidla:


  1. Výchozím stavem souborů je NECTENO.
  2. Zpracování probíhá tak dlouho, dokud nejsou oba soubory ve stavu KONEC.
  3. Soubor ve stavu NECTENO je čten, výsledkem je PRECTENO nebo KONEC.
  4. Pokud je potom pouze kmenový soubor ve stavu PRECTENO, kopíruje se jeho přečtený záznam na výstup a stav se mění na NECTENO.
  5. Pokud je potom pouze změnový soubor ve stavu PRECTENO, kopíruje se jeho přečtený záznam na výstup a stav se mění na NECTENO, jen pokud se jedná o vložení nového záznamu. Změna a rušení se vypisuje jako chyba a stav se také mění na NECTENO.
  6. Pokud jsou oba soubory ve stavu přečteno, potom záleží na typu změny a vzájemném vztahu kmenového a změnového záznamu:


Pokud jsou přečteny záznamy z obou souborů pak:


  1. Pokud je kmenový záznam menší než změnový, výstup se zapisuje z kmenového souboru, jehož indikace se nastaví na NECTENO.
  2. Pokud jsou oba záznamy se stejnými klíči, vypisuje se chyba, že vkládaný záznam již existuje a indikace změnového souboru se nastaví na NECTENO.
  3. Pokud je kmenový záznam větší než změnový, výstup se zapisuje ze změnového souboru, jehož indikace se nastaví na NECTENO.


  1. Pokud je kmenový záznam menší než změnový, výstup se zapisuje z kmenového souboru, jehož indikace se nastaví na NECTENO.
  2. Pokud jsou oba záznamy se stejnými klíči, zapisuje se ze změnového souboru a oba soubory se nastaví na NECTENO.
  3. Pokud je kmenový záznam větší než změnový, vypíše se chyba, že měněný záznam neexistuje, indikace změnového souboru se nastaví na NECTENO.


  1. Pokud je kmenový záznam menší než změnový, výstup se zapisuje z kmenového souboru, jehož indikace se nastaví na NECTENO.
  2. Pokud jsou oba záznamy se stejnými klíči, na výstup se nezapíše nic a indikace obou souborů se nastaví na NECTENO.
  3. Pokud je kmenový záznam větší než změnový, vypíše se, že rušený záznam neexistuje a indikace změnového souboru se nastaví na NECTENO.


Podrobné struktogramy jsou na obrázku a .



program telef;

{/**

*

* Projekt: PPVS     Autor: Kopeček     Datum: 20.4.2005

*

* Funkce: Změnové řízení telefonního seznamu

*

*                     ***************

*        telef.old -->*             * --> telef.new

*                     * telef.exe *

*        telef.new -->*             * --> telef.err

*                     ***************

* Spuštěním s přesměrováním výstupu lze vytvořit soubor ladících výstupů

*     telef.exe >telef.prn

*

**/}

const

     NAME_LEN = 25;               // délka jména abonenta

     ADRE_LEN = 45;               // délka adresy

     NUM_LEN = 8;                // délka čísla


     TELEF_OLD = 'TELEF.OLD';     // starý kmenový soubor

     TELEF_UPD = 'TELEF.UPD';     // soubor změn

     TELEF_NEW = 'TELEF.NEW';     // nový kmenový soubor

     TELEF_ERR = 'TELEF.ERR';     // soubor chyb


     VLOZIT = 'V';               // indikace typu změnového záznamu

     ZMENIT = 'Z';

     RUSIT   = 'R';


     DEBUG   = 1;                 // pro ladění a sledování běhu


type

     typ_stav = (NECTENO,PRECTENO,KONEC);

     typ_porov = (MENSI,ROVNO,VETSI);

     typ_jmeno = array[1..NAME_LEN] of char;

     typ_adresa= array[1..ADRE_LEN] of char;

     typ_cislo = array[1..NUM_LEN] of char;


     typ_kmen = record

             jmeno : typ_jmeno;

             adresa : typ_adresa;

             cislo : typ_cislo;

             znacik0: char;

             znacik1: char;

             znacik2: char;

     end;

     typ_zmen = record

           typ    : char;

           dvoutecka: char;

           jmeno : typ_jmeno;

           adresa : typ_adresa;

           cislo : typ_cislo;

           znacik0: char;

           znacik1: char;

           znacik2: char;

     end;

var

   indold,indupd:     typ_stav;

   kmen,stkmen,pkmen: typ_kmen;

   zmen,stzmen:       typ_zmen;


   old, new: file of typ_kmen;

   upd:      file of typ_zmen;

   err:      text;


// pomocné funkce a procedury


function porov(r,s:typ_jmeno): typ_porov;

begin

if r<s then porov := MENSI else

if r>s then porov := VETSI else

             porov := ROVNO;

end;


function ukazstav(s:typ_stav): string;

begin

case s of

    NECTENO: ukazstav:= 'NECTENO';

    PRECTENO: ukazstav:= 'PRECTENO';

    KONEC:    ukazstav:= 'KONEC';

end;

end;


procedure prirad(var s:typ_kmen;r:typ_zmen);

begin

     s.jmeno := r.jmeno;

     s.adresa := r.adresa;

     s.cislo := r.cislo;

     s.znacik0:= '*';       // ochrana proti zkrácení editorem

     s.znacik1:= chr(13);   // CR

     s.znacik2:= chr(10);   // LF

end;


procedure tiskkmen(s:typ_kmen;var t:text);

var i:integer;

begin

     for i := 1 to NAME_LEN do write(t,s.jmeno[i]);

     for i := 1 to ADRE_LEN do write(t,s.adresa[i]);

     for i := 1 to NUM_LEN do write(t,s.cislo[i]);

     writeln(t);

end;


procedure tiskzmen(s:typ_zmen;var t:text);

var i:integer;

begin

     write(s.typ);

     write(s.dvoutecka);

     for i := 1 to NAME_LEN do write(t,s.jmeno[i]);

     for i := 1 to ADRE_LEN do write(t,s.adresa[i]);

     for i := 1 to NUM_LEN do write(t,s.cislo[i]);

     writeln(t);

end;


// Uvodni sekce - otevreni souboru


begin

assign(old,TELEF_OLD);

{$i-}

reset(old);

{$i+}

if ioresult <> 0 then begin

    writeln('Nelze otevrit soubor ',TELEF_OLD);

    exit;

end;


assign(upd,TELEF_UPD);

{$i-}

reset(upd);

{$i+}

if ioresult <> 0 then begin

    writeln('Nelze otevrit soubor ',TELEF_UPD);

    exit;

end;


assign(new,TELEF_NEW);

{$i-}

rewrite(new);

{$i+}

if ioresult <> 0 then begin

    writeln('Nelze otevrit soubor ',TELEF_OLD);

    exit;

end;


assign(err,TELEF_ERR);

{$i-}

rewrite(err);

{$i+}

if ioresult <> 0 then begin

    writeln('Nelze otevrit soubor ',TELEF_ERR);

    exit;

end;


writeln;

writeln;

writeln('ZPRACOVANI TELEFONNIHO SEZNAMU');

writeln;


indold := NECTENO;

indupd := NECTENO;


// Hlavni cyklus - pokud nejsou oba vstupní soubory zpracovány


while (indold <> KONEC) or (indupd <> KONEC) do begin


    if (DEBUG=1) then writeln('indikator indold = ', ukazstav(indold),

                              ' indikator indupd = ', ukazstav(indupd));


    if (indold = NECTENO) then begin       // načítání kmenového souboru

        if eof(old) then indold := KONEC

        else begin

             read(old,kmen);

             indold := PRECTENO;

        end;

        if (indold = PRECTENO) and (DEBUG = 1) then begin

                writeln('Precten kmenovy zaznam: ');

                tiskkmen(kmen,output);

        end;

        if (indold = KONEC) and (DEBUG = 1) then

                writeln('Konec kmenoveho souboru');


        if (indold = PRECTENO) and

              (porov(stkmen.jmeno,kmen.jmeno) <> MENSI) then begin

                  writeln('Porusena posloupnost kmenovych zaznamu:');

                  writeln(err,'Porusena posloupnost kmenovych zaznamu:');

               if (DEBUG = 1) then begin

                   tiskkmen(stkmen,output);

                   tiskkmen(kmen,output);

               end;

               indold := KONEC;

        end;

        stkmen := kmen;

    end;


    if (indupd = NECTENO) then begin       // načítání změnového souboru

        if eof(upd) then indupd := KONEC

        else begin

             read(upd,zmen);

             indupd := PRECTENO;

        end;

        if (indupd = PRECTENO) and (DEBUG = 1) then begin

                writeln('Precten zmenovy zaznam');

                tiskzmen(zmen,output);

        end;


        if (indupd = KONEC) and (DEBUG = 1) then

                  writeln('Konec zmenoveho souboru');


        if (indupd = PRECTENO) and

           (porov(stzmen.jmeno,zmen.jmeno) <> MENSI) then begin

                 writeln('Porusena posloupnost zmenovych zaznamu');

                 writeln(err,'Porusena posloupnost zmenovych zaznamu');

                 if (DEBUG = 1) then begin

                     tiskzmen(stzmen,output);

                     tiskzmen(zmen,output);

                 end;

                 indupd := KONEC;

         end;

         stzmen := zmen;

    end;


// Ukončen změnový soubor - dokončí se zpracovaní kmenového souboru

//                          prosté kopírování


    if (indupd = KONEC) and (indold <> KONEC) then begin

         if (DEBUG = 1) then writeln('Dokonceni zpracovani kmenoveho souboru');

             write(new,kmen);

         indold := NECTENO;

    end;


// Ukončen kmenový soubor - dokončí se zpracování změnového souboru


    if (indupd <> KONEC) and (indold = KONEC) then begin

         if (DEBUG = 1) then writeln('Dokonceni zpracovani zmenoveho souboru');


         case(zmen.typ) of

         VLOZIT:

                begin

                     prirad(pkmen,zmen);

                     if (DEBUG = 1) then writeln('Vlozeni zmenoveho zaznamu');

                           write(new,pkmen);

                end;

         ZMENIT:

                begin

                     writeln('Meneny zaznam neexistuje');

                     writeln(err,'Meneny zaznam neexistuje');

                     tiskzmen(zmen,output);

                     tiskzmen(zmen,err);

                end;

         RUSIT:

                begin

                     writeln('Ruseny zaznam neexistuje');

                     writeln(err,'Ruseny zaznam neexistuje');

                     tiskzmen(zmen,output);

                     tiskzmen(zmen,err);

                end;

         else

                begin

                    writeln('Neznamy kod zmenoveho zaznamu');

                    writeln(err,'Neznamy kod zmenoveho zaznamu');

                    tiskzmen(zmen,output);

                    tiskzmen(zmen,err);

                end;

                end;

         indupd := NECTENO;

    end;


// Zpracovávají se kmenový i změnový soubor


    if (indupd <> KONEC) and (indold <> KONEC) then begin

         if (DEBUG = 1) then writeln('Zpracovani obou souboru');


         case(zmen.typ) of

         VLOZIT:

                case(porov(kmen.jmeno,zmen.jmeno)) of

                MENSI:

                       begin

                          if (DEBUG = 1) then

                            writeln('Vlozeni kmenoveho zaznamu');

                          write(new,kmen);

                          indold := NECTENO;

                       end;

                ROVNO:

                       begin

                          indupd := NECTENO;

                          writeln('Vkladany zaznam existuje');

                          tiskzmen(zmen,output);

                          writeln(err,'Vkladany zaznam existuje');

                          tiskzmen(zmen,err);

                       end;

                VETSI:

                       begin

                          if (DEBUG = 1) then

                          writeln('Vlozeni zmenoveho zaznamu');

                          prirad(pkmen,zmen);

                          write(new,pkmen);

                          indupd := NECTENO;

                      end;

                end;


         ZMENIT:

                case(porov(kmen.jmeno,zmen.jmeno)) of

                MENSI:

                       begin

                          if (DEBUG = 1) then

                            writeln('Vlozeni kmenoveho zaznamu');

                          write(new,kmen);

                          indold := NECTENO;

                       end;

                ROVNO:

                       begin

                          if (DEBUG = 1) then

                             writeln('Zamena kmenoveho zaznamu zmenovym');

                          prirad(pkmen,zmen);

                          write(new,pkmen);

                          indupd := NECTENO;

                          indold := NECTENO;

                      end;

                VETSI:

                      begin

                          writeln('Meneny zaznam neexistuje');

                          tiskzmen(zmen,output);

                          writeln(err,'Meneny zaznam neexistuje');

                          tiskzmen(zmen,err);

                          indupd := NECTENO;

                      end;

                end;


         RUSIT:

                case(porov(kmen.jmeno,zmen.jmeno)) of

                MENSI:

                       begin

                         if (DEBUG = 1) then

                          writeln('Vlozeni kmenoveho zaznamu');

                          write(new,kmen);

                          indold := NECTENO;

                       end;

                ROVNO:

                       begin

                         if (DEBUG = 1) then

                          writeln('Nic se nevklada');

                         indupd := NECTENO;

                         indold := NECTENO;

                       end;

                VETSI:

                       begin

                         writeln('Ruseny zaznam neexistuje');

                         tiskzmen(zmen,output);

                         writeln(err,'Ruseny zaznam neexistuje');

                         tiskzmen(zmen,err);

                         indupd := NECTENO;

                        end;

                end;


         else

                    begin

                        writeln('Neznamy kod zmenoveho zaznamu');

                        tiskzmen(zmen,output);

                        writeln(err,'Neznamy kod zmenoveho zaznamu');

                        tiskzmen(zmen,err);

                        indupd := NECTENO;

                   end;

         end;

    end;      // Konec zpracování obou vstupních souborů

end;         // Konec hlavní smyčky


// Zaverecna sekce - uzavreni vsech souboru


close(old);

close(new);

close(upd);

close(err);

writeln;

writeln('KONEC ZPRACOVANI TELEFONNIHO SEZNAMU');

end.