Mivel más nem jutott az eszembe, kivételesen nézzünk valami értlemeset.
Mondjuk könyvtárstruktúra végigjárása. (Remélem még nem volt) Hogy
lehet egy ilyet (un. fa gráfot) végigjárni? Minden egyes alkönyvtárba be
kell nyitni, de csak pontosan egyszer. A problámát igencsak megnehezti,
hogy minden egyes alkönyvtárnak további tettszôleges számú alkönyvtára
lehet, és ezeknek az alkönyvtáraknak is, és így tovább és így tovább. Az
ilyen féle problémákat elég jól lehet kezelni rekurzióval. A rekurzióra
(mint a múltkori programozás vizsga UTÁN megtudtam), nagyon szép defininíciók
vannak, de nem hiszem hogy ebbôl bárki is egy büdös szót meg tudna érteni
(engem is beleérteve). Szóval egyszerűen, a rekurzió egy olyan dolog,
amikor a függvény állandóan saját magát hívja meg. Ha rekurzívan gondolkodunk,
akkor valami hasonlót kell csinálnunk egy fa struktúra körbejárásánál(mi
vagyunk a függvény):
függvény:
megkeresem a következô alkönyvtárat
ha van még alkönyvtár, benyitok, és meghívom magam, ha
nincs kilépek az aktuális könyvtárból
függvény vége (és magamból is kilépek)
Remélem érthetô.
Egy pár dologra szükségünk lesz. Ugye ismerôs a findnext, findfirst, chdir meg ijesmi! Ezek a dolgok C-ben is léteznek.A prototípusuk a dir.h ban van.
findfirst,findnext:
A findfirst-el kell kezdeni a keresést,a findnexttel kell folytatni:
findfirst(filenev,* ffblk,attributum);
az ffblk a file found block , ami így néz ki:
struct ffblk {
char ff_reserved[21]; /* reserved by DOS */
char ff_attrib; /* attribute
found */
int ff_ftime;
/* file time */
int ff_fdate;
/* file date */
long ff_fsize;
/* file size */
char ff_name[13]; /* found file
name */
};
Ezt persze nem nekünk kell megadni, a header file-ban már létezik. A megtalált file adatait tartalmazza. A findnext-et mindig csak akkor szabad meghívni, ha elôtte a findfirst-et már meghívtuk. (hiszen a findfirst tölti fel a filefound blockot)
findnext(* ffblk);
Mivel minden lényeges adat benne van már a file found blockban, csak ezt kell megadni paraméterként. A megtalált file adatai termászetesen szintén itt lesznek.
Ami még kelleni fog, az a chdir.
chdir(directory);
Asszem ezen nem kell túl sokat magyarázni.
Lássuk a mdevét:
int depth=0; //melyseg
void dirlist(char near *dir)
{
struct ffblk ffblk;
int done=0;
depth++;
//egyel beljebb vagyunk
chdir(dir);
//cd dir
gotoxy((depth-1)*5,wherey());
cprintf("%s\n",dir);
//konyvtar kiirasa
findfirst("*",&ffblk,FA_DIREC);
if (*ffblk.ff_name=='.') done = findnext(&ffblk); //.
if (*ffblk.ff_name=='.') done = findnext(&ffblk); //..
atlepese
while (!done)
{
if (ffblk.ff_attrib==FA_DIREC) dirlist(ffblk.ff_name); //belepes
a ovetkezobe
done = findnext(&ffblk); //kovetkezo keresese
}
chdir(".."); //nincs mas hatra, mint hatra
depth--;
}
Ilyen egyszerű lenne. A függvény meghívása elôtt természetesen nem
árt elmenteni az aktuális könyvtárat, mert ki tudja, hol leszünk, a függvény
lefutása után. Elvileg ugyanaz, mint amit már feljebb megpróbáltam emberi
nyelven leírni, csak itt az a különbség, hogy van két könyvtár, ami tulajdonképpen
nem is könyvtár, ez a . és a .. , ezeket át kell lépni. Aztán még annyi,
hogy van egy globális változónk, amivel a könyvtár mélységét jelöljük,
ez tulajdonképpen csak a kiiratáshoz fog kelleni. Így minden egy szinten
levô könyvtár egymás alá kerül. Ugyanúgy, mint a dos tree parancsában,
csak itt nem rajzolgatunk vonalakat. Akinek van hozzá idege, megcsinálhatja.
Persze azt sem lenne rossz megoldani, hogy minden képernyônyi kiírás után
álljon meg egy kicsit.
Tehát a program nem kész, van még rajta mit csinálni. Persze egy program
soha nincs kész, és egyáltalán soha semmi sincs teljesen kész. Kivéve ezt
az elég rövidre sikerült cikket.