Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




UNIT-UL DOS

Informatica


UNIT-UL DOS

Unit-ul standard DOS implementeaza un numar de subprograme axate pe sistemul de operare si de tratare a fisierelor. Subprogramele nu sint definite in limbajul Pascal standard, motiv pentru care ele au fost comasate in acelasi unit. Programele care folosesc aceste subprograme trebuie sa contina directiva uses Dos.



Subprogramele unit-ului DOS pot fi clasificate astfel:

. subprograme referitoare la data si timp;

. subprograme referitoare la gestiunea fisierelor;

. tratarea intreruperilor;
. gestiunea proceselor;

. tratarea .numelor fisierelor;

. starea discului;

. subprograme de interes general;

. tratarea variabilelor de mediu DOS

Programe care folosesc unitul DOS

4.1. Descrierea programelor

Unitul DOS ofera posibilitatea utilizarii principalelor servicii oferite de sistemul de operare, altele decat operatiile de intrare/iesire la nivel de fisier, care sunt implementate in unitul SYSTEM. Programele din acest capitol pun in evidenta o parte din posibilele utilizari ale rutine lor unitului DOS.

4.1.1. Programul FILEDIR

Sa se scrie un program care sa afiseze pe ecran numele fisierelor si subdirectoarelor aflate in directorul curent.

Programul foloseste procedurile FINDFIRST si FINDNEXT ale unitului DOS. Pentru aceasta este nevoie de o variabila S de tip SEARCHREC. Programul numara intr-o variabila intreaga I fisierele si directoarele gasite, afisandu-i valoarea inainte de incheierea executiei.

Se face un singur apel al lui FINDFIRST furnizandu-i-se ca prim parametru '*.*' pentru a lua in consideratie toate numele posibile de fisiere. Al doilea parametru este ANYFILE - VOLUMEID, avandu-se in vedere atat fisierele care nu au nici un atribut sau au numai atributul ARCHIVE, cat si cele care au unul sau o parte din atributele DIRECTORY (directoare), HIDDEN (fisiere ascunse), READONLY (fisiere asupra carora sunt interzise operatiile de scriere) sau SYSFILE (fisiere sistem). Ultimul parametru este variabila S, care va fi transmisa lui FINDNEXT si din care se vor extrage datele necesare programului. Numele fisierelor vor fi preluate din campul NAME al variabilei S (S.NAME). Atributele fisierelor se vor gasi in S.ATTR, determinandu-se daca este vorba de un director sau de un fisier, dupa cum bitul DIRECTORY este pozitionat sau sters.

Procedura FINDNEXT este apelata atat timp cat continutul variabilei DOSERROR a unitului DOS este 0. In momentul in care DOSERROR devine diferit de 0 inseamna ca s-a epuizat lista fisierelor din directorul curent.

i: = 0;

findfirst anyfile - volumeid, s);

while doserror = 0 do

begin

inc (i);

write (s.name, '' : 13-length (s.name));

if s.attr and directory directory then write(' <DIR> ');

writeln,

findnext (s);

end.

4.1.2. Programul FILEDISC

Sa se scrie un program care sa verifice daca un fisier are suficient loc sa fie copiat pe un anumit disc.

Programul citeste mai intai, de la tastatura, numele fisierului intr-o variabila de tip string numita NAME si litera asociata discului pentru care se face verificarea, intr-o variabila DISC de tip char, fiind convertita apoi catre majuscula corespunzatoare ei cu functia UPCASE a unitului SYSTEM.

Spatiul liber de pe discul respectiv se afla cu ajutorul functiei DISKFREE a unitului DOS, valoarea returnata de aceasta fiind memorata intr-o variabila longint numita SPAC. Lui DISKFREE i se furnizeaza ca parametru codul ascii al caracterului retinut in variabila DISC din care se scade 64, obtinandu-se 1 pt. 'A', 2 pt. 'B', s.a.m.d.

Apoi se determina dimensiunea fisierului si este memorata in variabila SIZE, tot de tip longint, folosindu-se functia FILESIZE a unitului SYSTEM. Pentru aceasta este necesara o variabila F de tip file. Inainte de apelul lui FILESIZE, lui F i se asigneaza fisierul a carui denumire e memorata in NAME si se deschide acest fisier cu RESET. Dupa determinarea dimensiunii sale, el este inchis cu CLOSE.

Instructiunile care determina SPAC si SIZE sunt urmatoarele :

disc := upcase (disc);

spac := diskfree (ord (disc) - 64);

assign (f, name);

reset (f, 1);

size : = filesize(f);

close (f);

In final (daca SIZE > SPAC se afiseaza pe monitor 'Nu e Ioc'. Altfel este scris pe ecran mesajul 'OK'

Sugestie

Modificati progratttul astfel incat dimensiunea fisierului sa se afle cu procedura FINDFIRST a unit-ului DOS.

4.1.3. Programul INPATH

Sa se scrie un program care sa caute fisierul al carui nume a fost specificat in linia de comanda, in lista de directoare continuta in variabila de mediu PATH. Daca e gasit fisierul, se afiseaza calea completa a acestuia.

In partea de inceput a programului este declarata o variabila P de tip pathstr, folosita de instructiunile:

p : = fsearch (paramstr(1), getenv ('PATH'));

if p = '' then

writeln ('Nu a fost gasit') else

writeln (fexpand (p));

Prin apelul lui PARAMSTR se determina numele fisierului din linia de comanda. Functia GETENV a unitului DOS e folosita pentru a obtine lista cailor de cautare memorata in variabila de mediu PATH. Aceste cai sunt folosite de catre sistemul de operare, pentru a cauta program ele executabile apelate de la prompterul sistem si care nu au fost gasite in directorul curent. Programul nostru face exact acelasi lucru pentru fisierul al carui nume se da in linia de comanda, folosindu-se in acest scop de functia FSEARCH a unitului DOS.

Daca rezultatul returnat de FSEARCH este diferit de sirul vid, acesta este expandat cu functia FEXPAND si afisat pe ecran. Daca fisierul este gasit in directorul curent FSEARCH returneaza chiar numele acestuia, FEXPAND adaugandu-i calea curenta de pe discul curent. Altfel, daca fisierul e gasit intr-unul din directoarele listei PATH, FSEARCH returneaza aceasta cale urmata de numele fisierului. Functia FEXPAND va face anumite prelucrari, daca e cazul, asupra rezultatului returnat de FSEARCH, cum ar fi in locuirea lui '.' sau a lui '..' cu directoarele corespunzatoare.

Sugestie

Incercati o implementare proprie a functiei FSEARCH, folosindu-va de procedura FINDFIRST.

4.1.4. Programul CMDCOM

Sa se scrie un program care sa afiseze calea completa unde se gaseste interpretorul de comenzi COMMAND.COM.

Rezolvarea consta in a afisa continutul variabilei de mediu COMSPEC. Programul face in plus si o verificare a faptului ca aceasta variabila are o valoare corecta, apeland FINDFIRST pentru a determina daca fisierul indicat de COMSPEC exista intr-adevar pe disc. Daca in urma acestui apel DOSERROR are valoarea 0, este afisat continutul lui COMSPEC dupa ce i s-a aplicat functia FEXPAND a unit-ului DOS.

4.1.5. Programul CRONO

Sa se scrie un program, care sa permita crnometrarea altor programe, adica sa afiseze timpul de executie al acestora.

Programul citeste de la tastatura numele programului si linia de comanda cu care se va executa programul, memorand aceste date in doua variabile P si C de tip pathstr, respectiv comstr.

Apoi timpul sistemului este setat la 0 folosind procedura SETTIME a unitului DOS in continuare este apelata procedura EXEC incadrata intre doua apeluri SWAPVECTORS. Apelurile procedurii SWAPVECTORS sunt necesare intrucat orice program compilat cu TP schimba anumite date ale sistemului numite adrese de intreruperi care trebuie refacute inaintea apelului unui alt program cu EXEC (primul apel al iui SWAPVECTORS), respectiv trebuie facuta o revenire la schimbarile facute dupa terminarea lui EXEC (al doilea apel al lui SWAPVECTORS).

Daca a aparut o eroare la incercarea de executie a programului, spre exemplu s-a specificat un nume de fisier inexistent, atunci DOSERROR indica acest lucru si programul este intrerupt prin apelul procedurii HALT a unitului SYSTEM.

Atentie!

Eroarea la incercarea de executie a programului ai carui nume a fost introdus de la tastatura nu are nici o legatura cu eventualele erori de executie ale respectivului program,

De asemenea apare eroare la incercarea de executie a programului daca nu exista suficienta memorie disponibila pentru programul a carui executie se doreste a fi cronometrata. Aceasta situatie apare in mod sigur daca nu se foloseste directiva de compilare care stabileste dimensiunile stivei si ale heapului. In cazul absentei acestei directive intreaga memoriee ramasa libera dupa incarcarea lui CRONO va fi ocupata de heapul acestuia si nu va mai fi loc pentru incarcarea altui program.

In final se citeste cu GETTIME timpul inregistrat de ceasul sistemului, care coincide cu timpul scurs de la lansarea in executie a programului respectiv, intrucat in acel moment timpul sistemului a fost setat la 0. Se folosesc patru variabile de tip word numite H, M, S, S100 si o variabila reala R in care se retin secundele cumulate cu sutimile de secunda. Sunt afisate cu WRITELN variabilele H, M si R.

Urmeaza codul sursa al instructiunilor ale caror actiuni au fost descrise in cele de mai inainte:

settime(0, 0, 0, 0); swapvectors;

exec (p, c);

swapvectors;

if doserror <> 0 then

begin

writeln ('Eroare

halt; end;

gettime (h, m, s, s100);

r: = s + s100 / 100;

writeln (h, ' ore', m, ' minute ', r : 0 : 2, ' secunde '

Atentie!

Trebuie mentionat faptul ca inevitabil este cronometrat si timpul de incarcare in memorie al programului. Daca se doreste cronometrarea efectiva a executiei respectivului program sau numai a anumitor parti din acesta, atunci mecanismul de cronometrare trebuie implementat in interiorul acelui program.

Sugestie

Modificati programul astfel incat numele programului si parametrul cu care va fi executat acesta sa fie dati in linia de comanda a lui CRONO

Atentie!

Un lucru suparator este faptul ca programul altereaza timpul sistemului, acesta trebuind refacut manual dupa executia lui CRONO pentru a arata ora corecta.

Sugestie

Remediati acest defect.

Atentie!

Un alt neajuns al programului este acela ca nu permite o cronometrare mai lunga de 24 de ore.

Sugestie

Reginditi programul astfel incat sa fie permisa si o cronometrare de lunga durata. Veti folosi probabil procedura GETDATE a unitului DOS, care comunica data calendaristica inregistrata de sistem.

4.1.6. Programul FILENFO

Sa se scrie un program care sa afiseze atributele, data si om ultimei scrieri in fisierul al carui nume apare in linia de comanda.

Numele fisierului se obtine cu functia PARAMSTR si este asignat unei variabile de tip file.

Atributele fisierului se afla cu procedura GETFATTR a unitului DOS.

Pentru fiecare posibil atribut se face operatia AND pe biti intre atributele fisierului si constanta care reprezinta acel atribut. Daca se obtine ca rezultat aceeasi valoare cu cea a atributului, inseamna ca fisierul are acel atribut. Altfel se obtine 0 si fisierul nu are respectivul atribut.

Data si ora la care s-a facut ultima scriere in fisier se obtin cu GETFTIME. Rezultatul este de tip longint si trebuie despachetat cu UNPACKTIME, fiind transformat intr-un record care contine datele ce vor fi afisate pe monitor.

4.1.7. Programul DISCNFO

Sa se scrie un program care sa afiseze spatiul liber, spatiul ocupat si capacitatea totala a discului curent.

Se folosesc functiile DISKFREE si DISKSIZE ale unitului DOS care returneaza spatiul liber, respectiv spatiul total in care pot fi inscrise date pe un anumit disc. Spatiul ocupat se afla facand diferenta intre spatiul total si spatiul liber. Aceste valori sunt impartite la 1024 pentru a le transforma in KB. Afisarea se face cu doua zecimale.

4.1.8. Programul DOSNFO

Sa se scrie un program care sa afiseze versiunea sistemului de operare, data curenta, ora curenta, starea comutatorului BREAK, starea comutatorului VERIFY si variabilele de mediu.

Programul contine mai multe functii, primele doua avand un rol auxiliar, celelalte fiind apelate de programul principal.

Functia CBOOL primeste ca parametru o valoare booleana si returneaza sirul de caractere On daca acea valoare este TRUE, si Off daca este FALSE.

Functia CNUM converteste un numar intr-nn sir de caractere adaugandu-i un 0 la inceput daca numarul este format dintr-o singura cifra.

Procedurile P_DATE si P_TIME determina data si ora sistemului folosind procedurile GETDATE si GETTIME ale unitului DOS.

Procedurile P_BREAK si P_VERIFY afiseaza starea indicatorilor BREAK si VERIFY ai sistemului de operare si folosesc procedurile GETCBREAK si GETVERIFY.

Rutina P_VER afiseaza versiunea sistemului de operare pe care o afla apeland la functia DOSVERSION. Numarul major al versiunii se afla in octetul inferior al cuvantului returnat de DOSVERSION, putand fi obtinut cu functia LO a unitului SYSTEM. Numarul minor al versiunii se afla in octetul superior si se obtine cu functia HI aplicata rezultatului returnat de DOSVERSION.

In sfirsit, pentru variabilele de mediu se afla mai intai numarul lor cu functia ENVCOUNT si apoi valoarea fiecareia cu ENVSTR Aceste doua functii apartin tot unitului DOS.

4.1.9. Programul DOSSHL

Sa se scrie un program care sa ofere posibilitatea apelam programului DOSNFO sau a interpretorului de comenzi COMMAND.COM.

O parte din explicatiile facute pentru programul CRONO sunt utile si in cazul lui DOSSHL, intrucat ambele programe folosesc directiva de compilare $M si apeleaza procedurile EXEC si SWAPVECTORS.

Atentie!

Executabilul programului anterior (DOSNFO.EXE) trebuie sa fie prezent in directorul curent in momentul rularii lui DOSSHL, deoarece este apelat cu EXEC de catre acesta,

Programul contine o bucla REPEAT la inceputul careia se citeste un intreg in variabila B. In cazul in care B = l se executa DOSNFO.EXE. Daca B = 2 se afla calea unde se gaseste interpretorul de comenzi COMMAND.COM, apeland GETENV pentru determinarea valorii variabilei de mediu COMSPEC si se executa COMMAND.COM-ul. Revenirea din COMMAND.COM in program se face prin comanda EXIT

Se iese din REPEAT cand B = 3.

lata codul sursa al buclei REPEAT :

repeat

writeln ('1 - Info'

writeln ('2 - DosShell');

writeln ('3 - Exit');

readln (b);

swapvectors;

case b of



: exec ('dosnfo.exe', ');

: exec (getenv ('COMSPEC'), ');
end;

swapvectors;

until b = 3

4.2. Sursele programelor

4.2.1. Sursa programului FILEDIR

program filedir;

uses dos; var begin i: = 0;

findfirst ('*.*', anyfile - volumeid,s);

while doserror = 0 do begin

inc (t);

write (s.name, ' ; 13 - length (s.name));

if s.attr and directory = directory then

write (' <DIR> '); writeln;

findnext (s); end;

writeln;

writeln (i, ' fisiere si directoare ');

writeln; end.

4.2.2. Sursa programului FILEDISC

program filedisc; uses dos;

var

disc : char;

name : string;

f : file;

spac : longint;

size : longint;

begin

write ('File : ');

readln (name);

write ('Disc : ');

readln (diac);

disc : = upcase (disc);

spac : = diskfree (ord (disc) 64);

assign (f, name);

reset (f,

size ; = filesize (f);

close (f);

if size > spac

then writeln ('Nu e loc') else writeln ('OK'); end.

4.2.3. Sursa programului INPATH

program inpath;

uses dos;

var

p : pathstr;

begin

if p = '' then

wrileln ('Nu a fost gasit') else

writeln (fexpand (p));

writeln; end.

4.2.4. Sursa programului CMDCOM

program emdcotn; uses dos; var

s : searchrec;

begin

findfirst (getenv ('COMSPEC'), anyfile - volumeid - directory, s);

if doserror <> 0 then

writeln ('Nu a fost gasit')

else

writeln (fexpand (getenv ('COMSPEC')));

writelni; end.

4.2.5. Sursa programului CRONO

($M 1024, 0,0}

program crono;

uses dos;

var

h, m, s, s100 : word;

r : real;

p : pathstr;

c : comstr;

begin

write (Nume program ;'); readln (p);

write ('Linie de comanda : '); readln ( c );

settime(0, 0, 0,0);

swapvectors;

exec (p, c);

swapvectors;

if doserror <> 0 then

begin

writeln ('Eroare halt;

end;

gettime (h, m, s, s100);

r := s + s100 / 100;

writeln (h, ' ore' , m, ' minute', r:0:2, ' secunde');

end.

4.2.6. Sursa programului FILENFO

program filenfo;

uses dos;

var

f: file;

a : word;

t: longmt;

d : datetime;

begin

assign (f, pararastr (1)); getfattr (f, a);

if doserror = 0 then begin

writeln ('Attr : ');

if a and readonly = readonly then writeln ('readonly');

if a atid hidden = hidden then w r ite in ('hidden');

if a and sysfile = sysfile then writeln ('sysfile');

if a and archive = archive then writeln ('archive');

writeln; end;

filemode : = 0; reset (f); getftime (f, t);

if doserror = 0 then begin

writeln ('Time : ');

unpacktime (t, d);

writeln ('year', d.year);

writeln ('month ', d.month);

writeln ('day ', d.day);

writeln ('hour', d.hour),

writeln ('min ', d.min);

writeln ('sec ', d.sec);

writeln; end:

close (f);

end.

4.2.7. Sursa programului DISCNFO

program discnfo;

uses dos;

var

df, ds : longint;

d : byte;

ch  : char;

begin

readln (ch);

ch := upcase (ch);

d := ord(ch)-ord('A') + 1;

df : = diskfree(d);

ds: = disksize (d);

writeln ('Liber : ', df/l024 : 10 : 2);

writeln 'Ocupat : ', (ds - df)/1024 : 10 : 2);

writeln ('----- ----- ----------

writeln (Total : ', ds/1024 : 10 : 2);

end.

4.2.8. Sursa programului DOSNFO

funuction cbool (b : boolean) : string;

begin

case b of

true : cbool: = 'On'

false : cbool : = 'Off';

end;

end;

function cnum (n : word) : string;

var

s : string;

begin

str (n : 2, s);

if s[1] = '' then

cnum : = s;

end;

procedure p_date;

var

y, m, d, w : word;

begin

getdate(y, m,d, w);

writeln

procedure p_time;

var

h, m, s, z : word; begin

gettime (h, m, s, z);

writeln ('Time : ', cnum (h), '-', cnum (m), '-', cnum (s));

end;

procedure p_break;

var

b : boolean;

begin

getcbreak (b);

writeln ('Break : ', cbool (b));

end;

procedure p_verify;

var

v : boolean;

begin

getverify (v);

writeln ('Verify : ', cbool (v));

end;

procedure p_ver;

begin

writeln ('Dos ver : ', lo (dosversion), '.', hi (dosversion));

end;

procedure p_env;

var

i: word;

begin

writeln;

writeln ('Parametrii de mediu : ');

writeln;

for t : = 1 to envcount do

writeln (envstr (i));

writeln;

end;

begin

p_ver;

p_date;

p_time;

p_break;

p _ verif y;

p_ env;

end.

4.2.9. Sursa programului DOSSHL

($M 1024,0,0}

program dosshl;

uses dos;

begin

repeat

writeln ('l - Info');

writeln - DosShell');



writeln - Exil');

readln (b);

swapvectors;

case b of

: exec ('dosnfo.exe',''

: exec (getenv ('COMSPEC'),'');


end;

swapvectors;

untilb = 3;

writeln;

end.

Programe care folosesc uniturile CRT si DOS

4.3. Descrierea programelor

In acest capitol este prezentat un prim set de programe utilitare simple. Sunt folosite uniturile SYSTEM (in mod automat), CRT si DOS.

4.3.1. Programul ECRANSAV

Sa se scrie un program care sa permita salvarea continutului ecranului intr-un fisier text al carui nume se da in linia de comanda,

Vom determina continutul ecranului citindu-1 din memoria video. Aceasta este o zona de memorie care contine codurile ascii si atributele de culoare ale caracterelor ce se gasesc afisate pe ecranul calculatorului. Mai mult decat atat, scrierea in memoria video este echivalenta cu afisarea de informatii pe monitor.

Adresa de inceput a memoriei video este B800:0000 pentru monitoarele color si 6000:0000 pentru cele monocrome. Memoria video este organizata in perechi de octeti asociate caracterelor de pe ecran. Primul octet al unei astfel de perechi reprezinta un cod ascii, iar cei de-al doilea contine atribute de culoare. Primii doi octeti ai memoriei video contin codul ascii si atributele primului caracter de pe ecran (cel din coltul stanga-sus). Urmeaza codul ascii si atributele caracterului afisat tot pe prima linie, dar pe coloana a doua. Se continua astfel cu caracterele primei linii, apoi cu cele de pe a doua linie, s.a.m.d.

Atentie!

Tot ceea ce s-a spus pana acum despre memoria video este valabil numai atunci cind modul video curent este unul din modurile text. Mai exista, in afara de acestea, moduri grafice de afisaj care au, de asemenea, asociata memorie video, dar cu un alt mod de organizare si mapata la alte adrese. Diferentele se datoreaza faptului ca in modurile text se opereaza la alt nivel de caracter, iar in modurile grafice se pot accesa numai puncte (numite pixeli). Aceasta face ca utilizarea modurilor grafice sa fie mult mai flexibila, dar si mult mai lenta, operatiile de afisare direct in memoria video (fara a se face apel la subrutine ale sistemului) fiind o necesitate.

Programul nostru foloseste memoria video pentru a afla codurile de ascii ale caracterelor afisate pe ecran, pe care apoi le salveaza intr-un fisier. Este conceputa o functie numita GETCHAR careia i se furnizeaza doi parametrii X si Y reprezentand coloana si lina unei pozitii de pe ecran si care returneaza caracterul afisat pe ecran in acea pozitie. Codul sursa al acestei functii este urmatorul:

Function getchar (x,y : byte ) : char; begin

getchar := chr (mem [vseg : (y-1) * 160 + (x-1) * 2]); end;

Adresa de segment a locatiei din memoria video unde este retinut codul ascii a caracterului coincide cu adresa de segment a memoriei video, care este calculata de program si retinuta in variabila VSEG. Deplasamentul se afla inmultind Y - l cu 160 si adunand la valoarea obtinuta X - 1 inmultit cu 2 (caracterele de pe fiecare linie a ecranului ocupa 80 de perechi de octeti in memoria video, adica 160 octeti, fiecare astfel de pereche ocupand evident 2 octeti). Pentru a afla continutul locatiei de memorie respective se foloseste tabloul MEM.

Calculul valorii ce trebuie retinuta in VSEG se face examinand octetul inferior al variabilei LASTMODE a unitului CRT. Din acest octet se poate obtine modul video anterior in cazul in care a fost aplicata procedura TEXTMODE a unitului CRT, iar in lipsa unui astfel de apel (cazul nostru) se obtine modul video curent. Daca octetul inferior al lui LASTMODE are valoarea 7, inseamna ca monitorul este monocrom si VSEG primeste valoarea hexazecimala $B000. Altfel, monitorul este color sau foloseste nuante de gri si valoarea corecta pentru VSEG este $B800.

if lo ( lastmode) = 7 then vseg := $b000

else

vseg := $b800

Este folosita o varianta de tip text numita T, careia i se asigneaza numele de fisier dat in linia de comanda, acest fisier fiind creat de catre program cu REWRITE. Apoi intr-o bucla for sunt parcurse liniile ecranului, caracterele citite din memoria video fiind salvate in fisier :

for i :=1 to 25 do begin

for j := 1 to 80 do

s[j] := getchar (j, i);

for j := l to 80 do

if s[ j ] < ' ' then s[ j ] := ' '

j := 80;

while (j >0 ) and (s[j] <> ' ') do dec (j) ;

s [ 0 ] := char (j);

Pentru fiecare din cele doua linii ale ecranului se construieste un sir S continand cele 80 de caractere care se gasesc pe linia respectiva. Apoi sunt inlocuite cu spatii caracterele din S ale caror coduri ascii sunt mai mici decat codul caracterului spatiu pentru a nu cauza probleme la eventualele prelucrari ale fisierului cu anumite editoare de texte sau la tiparirea acestuia la imprimanta. Urmeaza elimiinarea spatiilor inutile de la sfirsitui lui S si scrierea acestuia in fisier.

In final se inchide fisierul, este sters ecranul si este afisata calea completa a fisierului in care s-a facut salvarea continutului ecranului.

4.3.2. Programul INLOCSTR

Sa se scrie un program care sa permita inlocuirea unui sir de caractere printr-un alt sir, intr-un grup de fisiere al carui nume se da de la tastatura.

Programul principal contine doua apeluri de procedura: INIT si SCAN. Procedura INIT citeste datele de la tastatura, si anume : numele fisierelor (putand fi folosite caracterele '*' si '?') in variabila NAME, extensia fisierelor care vor fi create, adaugandu-i caracterul '.' la inceput daca nu-l are si convertind literele mici in litere mari. In variabilele de tip string SOURCE si DEST se citesc sirul care se cauta in fisiere, respectiv sirul cu care e in locuit cel cautat in cazul in care e gasit. Daca sirul sursa este subsir al celui destinatie, atunci programul se intrerupe. Astfel la prima intilnire a primului sir s-ar putea intra intr-o bucla infinita si programul s-ar bloca. Cealalta procedura, SCAN, apeleaza procedurile FINDFIRST si FINDNEXT ale unitului DOS pentru a determina fisierele sursa, pentru fiecare astfel de fisier apeland o a treia procedura a programului numita INLOC. Sursa procedurii SCAN este urmatoarea:

procedara scan;

var

d : dirstr ;

n : namestr:

e : existr;

s : searchrec;

begin

name :=fexpand (name);

fsplit (name, d, n, e );

findfirst (name, archive, s);

while doserror = 0 do

begin

fsplit (d + s, name, d, n, e );

if e = ext then

begin

writeln ( 'Eroare ' );

halt ;

end ;

inloc ( d + s, name, d + n + ext);

findnext ( s );

end ;

end;

Numele de cale citit in NAME este expandat, dupa care i se afla directorul fiind apelata procedura FSPLIT. In bucla WHILE se face un al doilea apel al lui FSPLIT in scopul obtinerii extensiei fisierului sursa. Daca aceasta este egala cu extensia fisierelor destinatie, este semnalata eroarea si programul se opreste. Aceasta deoarece numele si cel al destinatiei trebuie diferentiate dupa extensie, cele doua fisiere ncputand fi unul si acelasi. Procedurii INLOC i se furnizeaza numele fisierelor sursa si destinatie. Pentru a mari viteza de executie a programului, variabilelor text TS si TD li se asociaza bufferele A si B, de cate 10000 de octeti, folosindu-se procedura SETTEXTBUF a unitului SYSTEM. Fisierul sursa este deschis cu RESET, iar cel destinatie este creat cu REWRITE.

Secventa de instructiuni care face efectiv inlocuirea sirurilor de caractere este urmatoarea:

i : = 0 ;

while not eof (ts) do

begin

readln (ts, s );

p : = pos ( source , s ) ;

while p > 0 do

begin

inc (i);

delete ( s, p, length (source ));

insert ( dest, s, p );

p := pos ( source , s );

end ;

writeln (td, s );

end ;

In variabila I sunt contorizate inlocuirile. Fisierul TS este parcurs linie cu linie. Dupa citirea fiecarei linii in variabila de tip string S, sunt inlocuite toate aparitiile lui SOURCE cu DEST. O inlocuire se face stergand SOURCE din S cu procedura DELETE a unitului SYSTEM si apoi inserand DEST in locul in care s-a facut stergerea folosind procedura INSERT a aceluiasi unit.

In finalul procedurii INLOC fisierele sunt inchise cu CLOSE si se afiseaza numarul de inlocuiri facute.

Atentie!

Fisiereie trebuie neaparat inchise din motivele expuse in capitolul I. Sugestie

Realizati un program asemanator care sa faca inlocuirea mai multor siruri de caractere cu alte siruri, intr-un grup de fisiere. Aceste siruri vor fi citite dintr-un fisier ascii.

4.3.3. Programul FDESTR

Sa se scrie un program care sa distruga prin suprascriere un grup de fisiere al carui nume se da de la tastatura.

Cunoasteti, probabil, faptul ca un fisier sters poate fi refacut cu comanda UNDELETE a sistemului de operare. Chiar daca uneori aceasta comanda nu mai poate face nimic, cu ajutorul unui editor de disc se pot recupera fisiere sterse sau macar portiuni din aceste fisiere. Pentru ca acest lucru sa devina imposibil FDESTR suprascrie mai intai aceste fisiere cu zerouri si abia apoi le sterge.

Atentie!

Fisierele sterse cu acest program vor fi distruse definitiv. Cum se presupune ca il veti folosi pentru a sterge fisiere care contin date importante, verificati de doua ori inainte de a-1 lansa in executie daca este corect ceea ce faceti.

Acest program are o structura asemanatoare cu cel precedent. In procedura INT se citeste numele grupului de fisiere ce vor fi distruse (eventual
folosindu-se '*' si '?').

Procedura SCAN este o versiune simplificata a celei din programul INLOCSTR. In plus, apare functia CONFIRM care cere confirnarea de la tastatura daca intr-adevar se doreste stergerea. Se raspunde cu 'Y' pentru DA si 'N' pentru NU. Locul procedurii INLOC este luat de DESTR care primeste ca parametru numele fisierului si il asigneaza unei variabile F de tip file. In eventualitatea ca fisierul are atributul READONLY, acest atribut este sters cu procedura SETFATTR a unitului DOS. Fisierul este deschis cu RESET, i se afla dimensiunea cu FILESIZE , este suprascris cu BLOCKWRITE, iar in final este inchis cu CLOSE si sters cu procedura ERASE a unitului SYSTEM. Instructiunile care realizeaza suprascrierea sunt urmatoarele :

assign ( f, name );

setfattr ( f, archive

resel( f, l ) ,

size : = filesize ( f ) ;

for i:= 1 to (size div max ) do

blockwrite ( f, a, size mod max ) ;

close ( f);

erase ( f);

Sugestie

Uneori stergeti fisiere importante apeland la comenzile sistemului de operare si numai dupa aceea va dati seama ca acestea trebuiau distruse. Daca nu le puteti reface cu UNDELETE pentru ca apoi sa le distrugeti, prin suprascriere, pentru a fi siguri ca fisierele respective nu vor fi recuperate de altcineva va trebui sa rulati, un program, care sa suprascrie spatiul liber de pe disc. Realizati un astfel de program care creeaza un fisier in care scrie date aleatoare pana cand nu mai exista spatiu liber pe disc, stergand in final acest fisier. Dupa aceasta nici un fisier sters nu va mal putea fi recuperat, indiferent de modul in care s-a facut stergerea.

4.3.4. Programul EDPRIM

Sa se scrie un program care sa permita crearea unui fisier text, adaugarea de noi linii si listarea continutului acestuia pe ecran.

Programul contine mai multe proceduri, cea care se numeste MAIN fiind singura care este apelata de programul principal. Codul sursa al acesteia este prezentat in continuare :

procedure main ;

begin

clrscr ;

checkeof := true ;

checkbreak := false ;

if paramstr ( 1 )<> ' ' then

begin

assign (t, paramstr(1)) ;

settextbuf (t, buf) ;

end

else ;

p_ name ;

p_menu;

repeat

writeln ;

write (' ? ');

repeat

ch := upcase ( readkey );

until ch in [ 'M', 'N', T', 'C', 'A', 'D', 'Q' ];

writeln (ch);

case ch of

'M' : p_menu ;

N' : p_name ;

T' : p_type ;

'C' : p_create ;

'A' : p_append ;

'I' : p_dosshell;

en d ;

until ch := 'Q';

end;



Variabilelor CHECKEOF si CHECKBREAK li se atribuie valorile TRUE, respectiv FALSE pentru ca programul sa nu poata fi intrerupt cu CTLR+BREAK in timp ce se fac citiri de la tastatura sau este apelata de una de rutinele unitului CRT, iar CRT+Z este introdus de la tastatura si interpretat ca sfarsit de fisier.

Daca linia de comanda nu este vida, atunci primul parametru este luat in considerare. Altfel se cere introducerea de la tastatura a numelui fisierului care se doreste a fi editat.

Atentie!

Fiecare apel al procedurii ASSIGN este urmat de apelul lui SETTEXTBUF. Prin marirea buffer-ului asociat variabilei text T se mareste viteza de executie a programului, mai ales daca este vorba de fisiere mari.

Intr-o bucla REPEAT se cere apasarea uneia dintre taste 'M', 'N', 'T', 'C', 'A', 'D', 'Q'. In functie de tasta aleasa se afiseaza meniul programului, se cere introducerea de la tastatura a numelui fisierului, se afiseaza continutul fisierului pe ecran, se creeaza fisierul pe disc si se scriu in acesta caracterele introduse de la tastatura pana cand se intilneste CTRL+Z, se procedeaza la fel cu exceptia faptului ca in loc de crearea fisierului cu REWRITE, se deschide un fisier existent pe disc cu APPEND, ultimele doua taste corespunzand unei 'iesiri temporare in DOS', respectiv terminarii programului. Am folosit ghilimelele intrucat nu se face nici o 'iesire' din program, ci un apel al COMMAND.COM-ului din care se revine in program cu comanda EXIT.

S-a folosit directiva de compilare $M pentru a avea suficient loc in memorie pentru COMMAND.COM si pentru programele apelate de acesta.

Inaintea apelurilor procedurilor de deschidere sau creare a fisierelor (REWRITE, RESET, APPEND) se foloseste directiva , astfel incat daca numele fisierului a fost tastat gresit programul sa nu se intrerupa cu eroare de executie, ci sa fie semnalata eroare a dupa care sa se reia lucrul. Revenirea la starea implicita se face cu .

Sugestie

Modificati programul astfel incat sa permita inserarea, stregerea sau modificarea. unei linii a fisierului ascii 'editat'.

4.4. Sursele programului

4.4.1. Sursa programului ECRANSAV

while not eof (ts) do begin

readln (ts, s );

p := pos ( source , s );

while p > 0 do

begin

inc ( i);

delete ( s, p, length (source ));

insert ( dest, s, p );

p := pos ( source, s );

end ;

writeln (td, s);

end ;

close (ts);

close (td);

writeln (f ; 6, ' inlocuiri ' );

end ;

procedure scan ;

var

d : dirstr;

u : namestr;

e : extste ;

s : searchrec ;

begin

name := fexpand ( name );

fsplit ( name, d, n, e );

findfirst ( name, archive, s);

while doserror = 0 do

begin

fsplit ( d+s, name, d, n, e );

if e = ext then

begiu

writeln ( ' Eroare : Nume fisier sursa = nume fisier dest);

halt;

end ;

inloc ( d + s, name, d + n + ext);

findnext (s);

end;

end;

begin init;

scan;

end.

4.4.3. Sursa programului FDESTR

program fdestr;

uses crt, dos ;

const

max = 10000 ;

var

a : array [ l , max ] of byte ;

i : byte ;

name : pathstr;

procedure init; begin

wrile ( 'Nume fisiere : ' );

readln ( name );

fillchar ( a, max, 0 ); end ;

functioin confirm ( path : pathstr) : boolean ;

var ch : char ;

begin

write (path , ' OK [Y /N] ? ' );

repeat

ch := upcase ( readkey );

until ch in ['Y', 'N'];

writeln ( ch );

confirm := ( ch = 'Y' );

end ;

procedure destr (name ; pathstr);

var

f : file ;

i : word ;

size :longint;

begin

if confirm ( name ) then

begin

assign ( f, name );

setfattr ( f, archive ) ;

reset ( f, 1 );

size : = filesize (f);

for i: = l to (size div max ) do

blockwrite ( f, a , max );

if (size mod max ) > 0 then

blockwrite ( f, a, size mod max ) ;

close (f), erase (f);

end;

end ;

procedure scan;

var

d : dirstr :

o : namestr ;

e : extstr;

s : searchrec ;

begin

name : = expand ( name );

fsplit ( name, d, n, e ),

findfirst ( name, anyfile - volumeid - directory , s) ;

while doserror = 0 do

begin

findnext ( s );

end;

end;

begin

init;

scan;

end.

4.4.4. Sursa programului EDPRIM

program edprim ;

uses crt, dos ;

var

i : text ;

ch : char ;

buf : array [l 4000 ] of byte ;

procedure p_menu ;

begin

writeln ;

writeln (' Editor primitiv ' );

writeln ;

writeln ('M - Menu');

writeln ('N - Name');

writeln ('T - Type');

writeln ('C - Create');

writeln ('A - Append');

writeln ('D - Dosshell');

writeln ('Q - Quit' );

writeln ;

end ;

procedura p_type ;

var

s : string ;

begin

reset (t) ;

if ioresult<>0 then

begin

writeln ('Eroare la deschidere ');

exit ;

end;

end ;

while not eof (t) do

begin

readln (t, s);

writeln ( s );

end;

close (t);

end;

procedure p_create ;

var

s : string ;

begin

rewrite ( t ) ;

if ioresult <> 0 then

begin

writeln ( 'Eroare la creare ' ) ;

exit ;

end ;

while not eof do

begin

readln ( s ) ;

writeln ( t, s ) ;

end ;

close ( t ) ;

close ( input ) ;

reset ( input ) ;

end ;

procedure p_append ;

var

s : string ;

begin

append ( t ) ;

if ioresult <> 0 then

begin

writeln ( 'Eroare la deschidere ' ) ;

exit;

end ;

while not eof do

begin

readln ( s );

writeln (l, s);

end ;

close (t);

close (input);

reset (input);

end ;

procedura p_dosshell;

begin

swapvectors ;

exec(getenv('COMSPEC'),'' );

swapvectors;

end ;

procedure main ;

begin

clrscr ;

checkeof := true ;

checkbreak := false ;

if paramstr (1) <>'' then begin

assign (t, paramstr (1));

settextbuf(t,buf);

end

else

p_name ;

p_menu ;

repeat

writeln ;

write (' ? ');

repeat

ch : := upcase ( readkey );

until ch in ['M', 'N', 'T']

case ch of

'M' : p_menu ;

'N' : p_name ;

'T' : p_type;

'C' : p_create ;

'A' : p_append ;

'D' : p_dosshell;

end ;

until ch = 'Q' ;

end ;

begin

main ;

end.




Document Info


Accesari: 1709
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2025 )