Dva soubory, seřazené podle stejného kritéria, se otevřou, z obou se přečte jedna komponenta. Ta z přečtených komponent, která má nižší hodnotu řadícího klíče, se zapisuje do pomocného výstupního souboru a ze souboru, ze kterého se četla, se přečte další komponenta. Pokud je jeden ze vstupních souborů prázdný, provede se kopírování zbytku druhého na výstupní, nakonec se provede přejmenování a zrušení.
Pro vytváření souboru se používají tyto standardní procedury a funkce:
assign, reset, rewrite, read, write, close, erase, rename.
Myšlenka zatřiďování je velmi jednoduchá. Předpokládejme, že máme dva vstupní vzestupně seřazené soubory, z nichž máme vytvořit jeden vzestupně seřazený soubor.
Evidentně chceme opakovaně provádět příkaz (zjednodušeně):
while not EOF(infile1) and not eof (infile2) do begin
if element1.Key <= element2.Key then begin {pošli element1 na výstup }
write(OutFile,element1);
read (InFile1,element1)
end
else begin {pošli element2 na výstup }
write(OutFile,element2);
read (InFile2,element2)
end;
end;
a to tak dlouho, dokud jeden vstupní soubor není vyčerpán. Pak kopírujeme druhý vstupní soubor na výstup až narazíme na jeho konec.
Vstupní soubory odpovídající animaci mají následující obsah:
03trojka *
04čtyřka *
08osmička *
a
05pětka *
09devítka *
První dva znaky představují řadící klíč.
Výsledný soubor má tvar:
03trojka *
04čtyřka *
05pětka *
08osmička *
09devítka *
Jako ukázka je uveden program, který provede sloučení obou souborů:
program merge;
{/**
*
* Projekt: PPVS Autor: Kopeček Datum: 20.4.2005
*
* Funkce: Slučování dvou souborů
*
* ***************
* infile1.dat -->* * --> outfile.dat
* * merge.exe *
* infile2.dat -->* *
* ***************
*
**/}
const
KEY_LEN = 2; // délka klíče
USER_LEN = 8; // délka uživatelské informace
INFILE1 = 'INFILE1.DAT'; // 1. vstupní soubor
INFILE2 = 'INFILE2.DAT'; // 2. vstupní soubor
OUTFILE = 'OUTFILE.DAT'; // výstupní soubor
DEBUG = 1; // pro ladění a sledování běhu
type
typ_stav = (NECTENO,PRECTENO,KONEC);
typ_porov = (MENSI,ROVNO,VETSI);
typ_klic = array[1..KEY_LEN] of char;
typ_uziv = array[1..USER_LEN] of char;
typ_soub = record
klic : typ_klic;
uziv : typ_uziv;
znacik0: char;
znacik1: char;
znacik2: char;
end;
var
ind1,ind2: typ_stav;
rec1,rec2,
strec1,strec2: typ_soub;
isoub1,isoub2,osoub: file of typ_soub;
// pomocné funkce a procedury
function porov(r,s:typ_klic): 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 tisksoub(s:typ_soub;var t:text);
var i:integer;
begin
for i := 1 to KEY_LEN do write(t,s.klic[i]);
for i := 1 to USER_LEN do write(t,s.uziv[i]);
writeln(t);
end;
// Uvodni sekce - otevreni souboru
begin
assign(isoub1,INFILE1);
{$i-}
reset(isoub1);
{$i+}
if ioresult <> 0 then begin
writeln('Nelze otevrit soubor ',INFILE1);
exit;
end;
reset(isoub2,INFILE2);
{$i-}
reset(isoub2);
{$i+}
if ioresult <> 0 then begin
writeln('Nelze otevrit soubor ',INFILE2);
exit;
end;
assign(osoub,OUTFILE);
{$i-}
rewrite(osoub);
{$i+}
if ioresult <> 0 then begin
writeln('Nelze otevrit soubor ',OUTFILE);
exit;
end;
writeln;
writeln;
writeln('SLUCOVANI SOUBORU');
writeln;
ind1 := NECTENO;
ind2 := NECTENO;
strec1.klic := ' ';
strec2.klic := ' ';
// Hlavni cyklus - pokud nejsou oba vstupní soubory zpracovány
while (ind1 <> KONEC) or (ind2 <> KONEC) do begin
if (DEBUG=1) then writeln('indikator ind1 = ', ukazstav(ind1),
' indikator ind2 = ', ukazstav(ind2));
if (ind1 = NECTENO) then begin // načítání 1. souboru
if eof(isoub1) then ind1 := KONEC
else begin
read(isoub1,rec1);
ind1 := PRECTENO;
end;
if (ind1 = PRECTENO) and (DEBUG = 1) then begin
writeln('Precten 1. soubor: ');
tisksoub(rec1,output);
end;
if (ind1 = KONEC) and (DEBUG = 1) then
writeln('Konec 1. souboru');
if (ind1 = PRECTENO) and
(porov(strec1.klic,rec1.klic) <> MENSI) then begin
writeln('Porusena posloupnost zaznamu v 1. souboru:');
if (DEBUG = 1) then begin
tisksoub(strec1,output);
end;
ind1 := KONEC;
end;
strec1 := rec1;
end;
if (ind2 = NECTENO) then begin // načítání 2. souboru
if eof(isoub2) then ind2 := KONEC
else begin
read(isoub2,rec2);
ind2 := PRECTENO;
end;
if (ind2 = PRECTENO) and (DEBUG = 1) then begin
writeln('Precten 2. soubor: ');
tisksoub(rec2,output);
end;
if (ind2 = KONEC) and (DEBUG = 1) then
writeln('Konec 2. souboru');
if (ind2 = PRECTENO) and
(porov(strec2.klic,rec2.klic) <> MENSI) then begin
writeln('Porusena posloupnost zaznamu v 2. souboru:');
if (DEBUG = 1) then begin
tisksoub(strec2,output);
end;
ind2 := KONEC;
end;
strec2 := rec2;
end;
// Ukončen 1. soubor - dokončí se zpracovaní 2. souboru - prosté kopírování
if (ind1 = KONEC) and (ind2 <> KONEC) then begin
if (DEBUG = 1) then
writeln('Dokonceni zpracovani 2. souboru - klic: ',rec2.klic);
write(osoub,rec2);
ind2 := NECTENO;
end;
// Ukončen 2. soubor - dokončí se zpracovaní 1. souboru - prosté kopírování
if (ind2 = KONEC) and (ind1 <> KONEC) then begin
if (DEBUG = 1) then
writeln('Dokonceni zpracovani 1. souboru - klic: ',rec1.klic);
write(osoub,rec1);
ind1 := NECTENO;
end;
// Zpracovávají se oba soubory
if (ind1 <> KONEC) and (ind2 <> KONEC) then begin
if (DEBUG = 1) then begin
writeln('Zpracovani obou souboru');
writeln('Porovnava se 1. klic:', rec1.klic);
writeln('Porovnava se 2. klic:', rec2.klic);
end;
case porov(rec1.klic,rec2.klic) of
MENSI:begin
if (DEBUG = 1) then
writeln('Vlozeni z 1. souboru');
write(osoub,rec1);
ind1 := NECTENO;
end;
ROVNO:begin
ind1 := NECTENO;
ind2 := NECTENO;
write(osoub,rec1);
write(osoub,rec2);
writeln('Zaznam se stejnym klicem');
tisksoub(rec1,output);
end;
VETSI:begin
if (DEBUG = 1) then
writeln('Vlozeni z 2. souboru');
write(osoub,rec2);
ind2 := NECTENO;
end;
end;
end; // Konec zpracování obou vstupních souborů
end; // Konec hlavní smyčky
// Závěrečná sekce - uzavření všech souborů
close(isoub1);
close(isoub2);
close(osoub);
writeln;
writeln('KONEC SLUCOVANI SOUBORU');
end.
Průběh činnosti programu (ladící výstup) je následující:
SLUCOVANI SOUBORU
indikator ind1 = NECTENO indikator ind2 = NECTENO
Precten 1. soubor:
03trojka
Precten 2. soubor:
05pětka
Zpracovani obou souboru
Porovnava se 1. klic:03
Porovnava se 2. klic:05
Vlozeni z 1. souboru
indikator ind1 = NECTENO indikator ind2 = PRECTENO
Precten 1. soubor:
04čtyřka
Zpracovani obou souboru
Porovnava se 1. klic:04
Porovnava se 2. klic:05
Vlozeni z 1. souboru
indikator ind1 = NECTENO indikator ind2 = PRECTENO
Precten 1. soubor:
08osmička
Zpracovani obou souboru
Porovnava se 1. klic:08
Porovnava se 2. klic:05
Vlozeni z 2. souboru
indikator ind1 = PRECTENO indikator ind2 = NECTENO
Precten 2. soubor:
09devítka
Zpracovani obou souboru
Porovnava se 1. klic:08
Porovnava se 2. klic:09
Vlozeni z 1. souboru
indikator ind1 = NECTENO indikator ind2 = PRECTENO
Konec 1. souboru
Dokonceni zpracovani 2. souboru - klic: 09
indikator ind1 = KONEC indikator ind2 = NECTENO
Konec 2. souboru
KONEC SLUCOVANI SOUBORU