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




Pascal ghid - invata pascal

Informatica


Capitolul 1

Today

(* >>> Today <<< -------- ----- ------ ---- *)

(* Nume fisier : TODAY.PAS *)

(* Programul asigura afisarea pe ecran a mesajelor *)



(* citite din fisierul text MESSAGE.TXT. *)

(* -------- ----- ------ ----- ----- -------- *)

PROGRAM Today;

USES DOS, CRT;

FUNCTION DateString: STRING;

(* -------- ----- ------ ----- ----- ------------ *)

(* Functia converteste data calendaristica a sistemului *)

(* intr-un sir afisabil de forma : ziua., mm.dd.yyyy *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

days: ARRAY[0..6] OF STRING[3]=

('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');

months: ARRAY[1..12] OF STRING[3]= ('Jan', 'Feb', 'Mar', 'Apr', 'May',

'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

VAR

year, month, day, weekday: WORD;

yearStr, monthStr, dayStr, WeekdayStr: STRING;

BEGIN

GetDate (year, month, day, weekday);

STR (year, yearStr);

STR (day, dayStr);

IF LENGTH (dayStr) = 1 THEN dayStr := ' ' + dayStr;

weekdayStr := days[weekday] + '.,';

monthStr := months[month] + '. ';

DateString := weekdayStr + monthStr + dayStr + ', ' + yearStr

END;

FUNCTION TimeString: STRING;

(* -------- ----- ------ ----- ----- ---------- *)

(* Functia converteste valorile numerice ale timpului *)

(* intr-un sir de forma : hh.mm. am/pm *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

hour, minute, second, hundredth: WORD;

ampm: STRING[2];

hourStr, minuteStr: STRING;

BEGIN

GetTime(hour, minute, second, hundredth);

IF hour > 11 THEN

BEGIN

ampm := 'pm';

IF hour > 12 THEN DEC(hour, 12)

END

ELSE

BEGIN

ampm := 'am';

IF hour = 0 THEN hour := 12

END;

STR(hour, hourStr); STR(minute, minuteStr);

IF LENGTH(hourStr) = 1 THEN hourStr := ' ' + hourStr;

IF LENGTH minuteStr) = 1 THEN minuteStr := '0' + minuteStr;

TimeString := hourStr + ':' + minuteStr + ' ' + ampm

END;

PROCEDURE TodaysMessage;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura deschide fisierul cu mesaje si afiseaza pe *)

(* ecran linie cu linie continutul acestuia. *)

(* -------- ----- ------ ----- ----- ----------- *)

CONST

messageFileName= 'MESSAGE.TXT';

screenStop= 13;

dots= 71;

VAR

messageFile: TEXT;

messageLine: STRING;

screenLines: BYTE;

PROCEDURE LineOfChars (dispChar: CHAR; lineLength: BYTE);

(* --- Afiseaza o linie avind lineLength caractere dispChar. --- *)

VAR

i: INTEGER;

BEGIN

FOR i := 1 TO lineLength DO Write(dispChar);

WriteLn

END;

PROCEDURE WaitForEnter;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura afiseaza pe ecran mesajul si asteapta *)

(* apasarea tastei <Enter> pentru continuare. *)

(* -------- ----- ------ ----- ----- ------- *)

BEGIN

GoToXY (20, 25);

Write('Apasati tasta <Enter> pentru continuare.'); ReadLn

END;

BEGIN

LineOfChars('.', dots); WriteLn;

screenLines := 0;

ASSIGN(messageFile, messageFileName); RESET(messageFile);

WHILE NOT EOF(messageFile) DO

BEGIN

ReadLn(messageFile, messageLine); WriteLn(messageLine);

IF screenLines = screenSto 24224c21y p THEN

BEGIN

screenLines := 0

WaitForEnter

END

END;

CLOSE(messageFile); LineOfChars('.', dots); WaitForEnter

END;

BEGIN

ClrScr; WriteLn; Write('Today is ', DateString,', ');

WriteLn(' The time is ', TimeString, '.');

TodaysMessage

END.

Capitolul 2

Hours

(* >>> Hours <<< -------- ----- ------ *)

(* Nume fisier : HOURS.PAS *)

(* Programul creaza si intretine o baza de date *)

(* organizata cronologic, pentru pastrarea orelor *)

(* lucrate la un anumit proiect. *)

(* -------- ----- ------ ----- ----- ---- *)

PROGRAM Hours;

USES CRT, DOS, ChrnUnit;

CONST

fixedLineLength = 48;

VAR

accountFile: TEXT;

accountFileName: STRING;

openFile: BOOLEAN;

PROCEDURE LineOfChars (displayChar: CHAR; lineLength: BYTE);

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura afiseaza pe ecran o line de displayChar *)

(* caractere. Argumentul lineLength reprezinta numarul de *)

(* caractere din linie. *)

(* -------- ----- ------ ----- ----- ----------- *)

VAR

i: INTEGER;

BEGIN

FOR i := 1 TO lineLength DO

WRITE(displayChar);

WRITELN

END;

PROCEDURE AccountUpdate;

(* -------- ----- ------ ----- ----- --------- *)

(* Procedura inregistreaza intr-un fisier cont data, *)

(* timpul si un numar real reprezentind orele de lucru *)

(* facturate. Procedura include doua rutine locale : *)

(* GetFileName si InReal. *)

(* -------- ----- ------ ----- ----- --------- *)

VAR

inHours: REAL;

FUNCTION GetFileName: STRING;

(* ---- Extrage de la tastatura un nume de fisier sau o ;masca; --- *)

VAR

goodName, dirRequest: BOOLEAN;

inName: STRING;

periodPos: BYTE;

PROCEDURE Directory (mask: STRING);

(* --- Listeaza cu EXEC fisierele selectate --- *)

BEGIN

LineOfChars('.', 75);

EXEC('\COMMAND.COM', '/C DIR ' + mask + ' /W');

LineOfChars('.', 75)

END;

BEGIN

goodName := FALSE;

WHILE NOT goodName DO

BEGIN

WRITELN; WRITE(' Numele contului ? '); READLN (inName);

IF inName = '' THEN

Directory('*.HRS')

ELSE

BEGIN

dirRequest:=(POS('*', inName) <> 0) Or (POS('?', inName) <> 0);

IF dirRequest THEN

Directory(inName)

ELSE

BEGIN

goodName := TRUE;

periodPos := POS('.', inName);

IF periodPos <> 0 THEN

inName := COPY(inName, 1, periodPos - 1)

END

END

END;

GetFileName := inName + '.HRS'

END;

FUNCTION InReal(prompt: STRING): REAL;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia citeste de la tastatura un numar real *)

(* si evita eroarea de executie daca nu s-a introdus *)

(* o data numerica corecta. *)

(* -------- ----- ------ ----- ----- ------ *)

VAR

trapReal: REAL;

goodInput: BOOLEAN;

saveX, saveY: BYTE;

BEGIN

REPEAT

WRITE(prompt);

saveX := WHEREX;

saveY := WHEREY;

READLN (trapReal);

goodInput := (IORESULT = 0);

IF NOT goodInput THEN BEGIN GOTOXY(saveX, saveY); CLREOL END

UNTIL goodInput;

InReal := trapReal

END;

BEGIN

accountFileName := GetFileName; openFile := TRUE;

ASSIGN(accountFile, accountFileName);

APPEND (accountFile);

IF IORESULT <> 0 THEN

BEGIN

REWRITE(accountFile);

IF IORESULT <> 0 THEN

BEGIN

WRITELN; WRITELN(' *** Fisierul nu poate fi deschis ***');

DELAY(5000); openFile := FALSE

END

END;

IF openFile THEN

BEGIN

inHours := InReal (' Ore contabilizate ? ');

WRITE(accountFile, DateString, ' ', TimeString, ' ');

WRITELN(accountFile, inHours:5:2);

CLOSE(accountFile)

END

END;

FUNCTION TotalAccount: REAL;

(* -------- ----- ------ ----- ----- --------- *)

(* Functia deschide din nou fisierul indicat pentru *)

(* a determina numarul total de ore inregistrate in mod *)

(* mod curent in contul specificat. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST

chronInfoLength = 28;

VAR

hours, total: REAL;

chronLine: STRING[chronInfoLength];

BEGIN

total := 0.0; RESET(accountFile);

WHILE NOT EOF (accountFile) DO

BEGIN

READLN(accountFile, chronLine, hours);

total := total + hours

END;

CLOSE(accountFile); TotalAccount := total

END;

BEGIN

CLRSCR; WRITELN(' Data : ', DateString, ' Timp : ', TimeString);

LineOfChars ('_', fixedLineLength);

WRITELN; WRITELN(' Inregistrarea orelor contabilizate ');

LineOfChars ('_', fixedLineLength);

AccountUpdate;

LineOfChars ('_', fixedLineLength); WRITELN;

IF openFile THEN

BEGIN

WRITE (' Numarul total de ore din acest cont : ');

WRITELN (TotalAccount:6:2);

LineOfChars ('_', fixedLineLength)

END

END.

Capitolul 4

BillTime

(* >>> BillTime <<< -------- ----- ------ -- *)

(* Nume fisier : BILLTIME.PAS *)

(* Programul tipareste facturi sub forma de rapoarte *)

(* obtinute prin consultarea fisierelor create prin *)

(* programul Hours. *)

(* -------- ----- ------ ----- ----- --------- *)

PROGRAM BillTime;

USES CRT, DOS, PRINTER, ChrnUnit, InUnit, StrUnit;

CONST

lineLength = 55;

maxScreenColumn = 80;

VAR

accountFile: TEXT;

accountFileName: STRING;

PROCEDURE PrintBill;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura tipareste factura-raport obtinuta prin *)

(* consultarea fisierului de cont selectat. *)

(* -------- ----- ------ ----- ----- -------- *)

CONST

dateInfoLength = 20;

timeInfoLength = 9;

VAR

hours, hourlyRate, total, amountDue: REAL;

cents, totalDue: LONGINT;

dateLine: STRING[dateInfoLength];

timeLine: STRING[timeInfoLength];

clientName:STRING;

okToPrint: BOOLEAN;

FUNCTION GetFileName:STRING;

(* -------- ----- ------ ----- ----- -------------- *)

(* Functia extrage numele unui fiser de cont, si afiseaza *)

(* lista director daca este necesar. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

goodName, dirRequest: BOOLEAN;

inName: STRING;

periodPos: BYTE;

PROCEDURE Directory (mask: STRING);

(* ----- Afisarea pe ecran a directorului. ----- *)

BEGIN

WRITELN(StringOfChars('.', 73));

EXEC('\COMMAND.COM','/C DIR ' + mask + ' /W');

WRITELN(StringOfChars('.', 73));

END;

BEGIN

goodName := FALSE;

WHILE NOT goodName DO

BEGIN

WRITELN; WRITE(' Numele contului ? '); READLN(inName);

IF inName = '' THEN

Directory('*.HRS')

ELSE

BEGIN

dirRequest := (POS('*', inName) <> 0) OR (POS('?', inName) <> 0);

IF dirRequest THEN

Directory(inName)

ELSE

BEGIN

goodName := TRUE;

periodPos := POS('.', inName);

IF periodPos <> 0 THEN

inName := COPY(inName, 1, periodPos - 1)

END

END

END;

GetFileName := inName

END;

PROCEDURE InvoiceHeading (VAR printerOn: BOOLEAN; client: STRING; rate: REAL);

(* ----- Tiparirea antetului facturii. ----- *)

VAR

rateString: STRING;

BEGIN

WRITE (LST, ' *** Facturarea orelor pentru :');

IF IORESULT = 0 THEN

BEGIN

printerOn := TRUE; WRITELN(LST, UpperCase (client), ' ***');

WRITELN(LST, StringOfChars (' ', 17), DateString); WRITELN(LST);

rateString := DollarDisplay (ROUND (rate * 100), 6);

WRITE(LST, ' Data Ore facturate ');

WRITELN(LST, '$', rateString, ' / ora');

WRITELN(LST, StringOfChars ('_', lineLength)); WRITELN(LST)

END

ELSE

BEGIN

printerOn := FALSE;

WRITELN(' *** Imprimanta nu este pregatita ***')

END

END;

PROCEDURE TotalLine;

(* ----- Tiparirea liniei finale a facturilor ---- *)

BEGIN

WRITELN(LST, StringOfChars ('_', lineLength)); WRITELN(LST);

WRITE(LST, ' TOTAL --> ');

WRITELN(LST, total:13:2, DollarDisplay (totalDue, 20));

CLOSE(accountFile)

END;

BEGIN

clientName := GetFileName;

accountFileName := clientName + '.HRS';

ASSIGN(accountFile, accountFileName);

RESET (accountFile);

IF IORESULT <> 0 THEN

BEGIN

WRITELN;

WRITELN(' *** Fisierul specificat nu poate fi deschis ***');

DELAY(5000)

END

ELSE

BEGIN

hourlyRate := InReal (' Tariful orar ? ');

WRITELN(StringOfChars ('-', lineLength)); WRITELN;

total := 0.0; totalDue := 0;

InvoiceHeading(okToPrint, clientName, hourlyRate);

IF okToPrint THEN

BEGIN

RESET(accountFile);

WHILE NOT EOF (accountFile) DO

BEGIN

READLN(accountFile, dateLine, timeLine, hours);

total := total + hours;

WRITE(LST, dateLine, hours:10:2);

amountDue := hours * hourlyRate;

cents := ROUND(amountDue *100);

totalDue := totalDue + cents;

WRITELN(LST, DollarDisplay (cents, 20))

END;

TotalLine

END

END

END;

BEGIN

CLRSCR;

WRITELN(' Data: ', DateString, ' Timp: ', TimeString);

WRITELN (StringOfChars ('_', lineLength));

WRITELN;

WRITELN(' Tiparirea facturii unui client');

WRITELN(StringOfChars ('_', lineLength));

PrintBill

END.

Capitolul 5

CliList

(* >>> CliList <<< -------- ----- ------ ------ *)

(* Nume fisier : CLILIST.PAS *)

(* Programul tipareste o lista cu toate fisierele .HRS *)

(* din directorul curent, impreuna cu numarul total de ore *)

(* facturate in fiecare cont, precum si starea fiecarui *)

(* cont : curent, recent sau inactiv. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM CliList;

USES CRT, DOS, PRINTER, StrUnit;

CONST

maxFiles = 100;

TYPE

fileRange = 1..maxFiles;

clientArray = ARRAY [fileRange] OF STRING;

VAR

clientFiles: clientArray;

listLength,

i: BYTE;

dirString: STRING;

PROCEDURE GetFiles (VAR numberOfFiles: BYTE);

(* -------- ----- ------ ----- ----- ------------- *)

(* Procedura investigheaza directorul curent si creaza o *)

(* lista cu toate fisierele .HRS depunind numele clientilor *)

(* in tabloul clientFiles. De asemenea procedura determina *)

(* si numarul de fisere pe care-l retransmite apelantului. *)

(* -------- ----- ------ ----- ----- ------------- *)

CONST

fileName = 'HRSDIR.TXT';

VAR

dirFile: TEXT;

recordNumber,

extensionPos,

firstSpace: BYTE;

dirLine: STRING[40];

clientName: STRING;

BEGIN

EXEC('\COMMAND.COM', '/C DIR *.HRS > '+ fileName);

ASSIGN(dirFile, fileName); RESET (dirFile);

recordNumber := 0;

WHILE NOT EOF(dirFile) DO

BEGIN

READLN(dirFile, dirLine);

extensionPos := POS(' HRS ',dirLine);

IF extensionPos <> 0 THEN

BEGIN

INC(recordNumber);

firstSpace := POS(' ', dirLine);

clientName := COPY(dirLine, 1, firstSpace - 1);

clientFiles[recordNumber] := clientName

END

END;

CLOSE(dirFile);

numberOfFiles := recordNumber

END;

PROCEDURE SortClientFiles (sortLength: BYTE);

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura utilizeaza algoritmul de sortare SHELL *)

(* pentru ordonarea alfabetica a listei clientilor. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

listJump, i, j: BYTE;

sortComplete: BOOLEAN;

saveName: STRING;

BEGIN

listJump :=1;

WHILE listJump <= sortLength DO listJump := listJump + 1;

WHILE listJump > 1 DO

BEGIN

listJump := (listJump - 1) DIV 2;

REPEAT

sortComplete := TRUE;

FOR j := 1 TO sortLength - listJump DO

BEGIN

i := j + listJump;

IF clientFiles[j] > clientFiles[i] THEN

BEGIN

saveName := clientFiles[j];

clientFiles[j] := clientFiles[i];

clientFiles[i] := saveName;

sortComplete := FALSE

END

END

UNTIL sortComplete

END

END;

PROCEDURE PrintClientList (printLength: BYTE);

(* -------- ----- ------ ----- ----- -------------- *)

(* Procedura tipareste lista sortata a numelor clientilor *)

(* impreuna cu totalul orelor facturate pentru fiecare cont *)

(* si starea acestui cont. *)

(* -------- ----- ------ ----- ----- -------------- *)

CONST

spaceBar = ' ';

escKey = #27;

formFeed = #12;

VAR

i, j: BYTE;

clientFile: STRING;

lastEntry: INTEGER;

inChar: CHAR;

FUNCTION TotalAccount (targetFileName: STRING; VAR lastDate: INTEGER): REAL;

(* -------- ----- ------ ----- ----- ------------- *)

(* Functia deschide fisierul de cont specificat, citeste *)

(* fiecare intrare si determina numarul total de ore curent *)

(* inregistrate in fisier. Acest total este furnizat ca *)

(* rezultat REAL al functiei. *)

(* -------- ----- ------ ----- ----- ------------- *)

CONST

yearColumn = 16;

yearLength = 4;

VAR

total,

hours: REAL;

targetFile: TEXT;

chronInfoString: STRING[29];

code: INTEGER;

BEGIN

total := 0.0;

ASSIGN(targetFile, targetFileName); RESET(targetFile);

WHILE NOT EOF (targetFile) DO

BEGIN

READLN(targetFile, chronInfoString, hours);

total := total + hours

END;

CLOSE (targetFile);

chronInfoString := COPY(chronInfoString, yearColumn, yearLength);

VAL (chronInfoString, lastDate, code);

TotalAccount := total

END;

FUNCTION ClientStatus (lastYear: INTEGER): STRING;

(* -------- ----- ------ ----- ----- ------------- *)

(* Functia furnizeaza un sir de asteriscuri reprezentind *)

(* starea contului astfel : *)

(* *** un cont activ; *)

(* ** un cont recent; *)

(* * un cont inactiv. *)

(* -------- ----- ------ ----- ----- ------------- *)

BEGIN

CASE lastYear OF

1990..1991: ClientStatus := '***';

1988..1989: ClientStatus := '**';

1980..1987: ClientStatus := '*';

ELSE ClientStatus := '';

END

END;

PROCEDURE PrintExplanations;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura tipareste semnificatia notatiilor din *)

(* coloana starea contului a raportului. *)

(* -------- ----- ------ ----- ----- ------- *)

BEGIN

WRITELN(LST); WRITELN(LST, StringOfChars ('-', 40));

WRITELN(LST); WRITELN(LST, ' *** Cont curent.');

WRITELN(LST, ' ** Cont recent.');

WRITELN(LST, ' * Cont inactiv.');

END;

BEGIN

WRITELN(' Apasati bara "spatiu" cind imprimanta este gata');

WRITELN(' sau "Esc" pentru iesire fara imprimare.');

REPEAT inChar := READKEY UNTIL (inChar = spaceBar) OR (inChar = escKey);

WRITELN;

IF inChar = ' ' THEN

BEGIN

WRITELN(LST, 'Nume client Ore facturate Stare');

WRITELN(LST, '____ ______ ___ _________ _____'); WRITELN(LST);

FOR i := 1 TO printLength DO

BEGIN

WRITE(LST, LeftAlign(InitialCap (clientFiles[i]), 18));

clientFile := clientFiles[i] + '.HRS';

WRITE(LST, TotalAccount(clientFile, lastEntry):7:2);

WRITELN(LST, Spaces (9), ClientStatus(lastEntry))

END;

PrintExplanations; WRITELN (LST,formFeed)

END

END;

BEGIN

CLRSCR;

WRITELN('Tiparirea listei cu fisierele clientilor');

WRITELN('_________ ______ __ _________ __________');

WRITELN;

GetFiles(listLength);

IF listLength > 0 THEN

BEGIN

SortClientFiles(listLength);

PrintClientList(listLength)

END

ELSE

BEGIN

WRITELN;

GETDIR(0, dirString);

WRITELN(' In directorul ', dirString,' nu exista ');

WRITELN('fisiere cu extensia .HRS')

END

END.

Capitolul 7

CliAddr

(* >>> CliAddr <<< -------- ----- ------ - *)

(* Nume fisier : CLIADDR.PAS *)

(* Programul creaza si intretine un fisier de date *)

(* continind adresele clientilor. *)

(* -------- ----- ------ ----- ----- ------- *)

PROGRAM CliAddr;

USES CRT, PRINTER, InUnit, StrUnit;

CONST

maxAddresses = 250;

addressFileName = 'ADDRLIST.TXT';

nameSort = '1';

refNoSort = '2';

TYPE

addressRecord = RECORD

name: STRING[30];

phone: STRING[20];

refNo: BYTE;

headOffice: BOOLEAN;

street: STRING[30];

city: STRING[20];

CASE usa: BOOLEAN OF

TRUE:

(state: STRING[2];

zip: STRING[5]);

FALSE:

(otherLoc,

country: STRING[15])

END;

indexRange = 1..maxAddresses;

AddressArray = ARRAY [indexRange] OF addressRecord;

VAR

done: BOOLEAN;

addresses: addressArray;

addressFile: TEXT;

currentRecord: BYTE;

PROCEDURE ReadAddresses;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura deschide fisierul ADDRLIST.TXT si citeste *)

(* fiecare adresa de client pe care o memoreaza intr-un *)

(* element al tabloului de adrese. *)

(* -------- ----- ------ ----- ----- ----------- *)

VAR

officeCode,

usaCode: BYTE;

BEGIN

RESET (addressFile);

IF IORESULT = 0 THEN

BEGIN

WHILE NOT EOF (addressFile(c) AND (currentRecord < maxAddresses) DO

BEGIN

INC (currentRecord);

WITH addresses[currentRecord] DO

BEGIN

READLN(addressFile, name);

READLN(addressFile, officeCode, usaCode, refNo);

headOffice := BOOLEAN(officeCode); usa := BOOLEAN(usaCode);

READLN(addressFile, phone); READLN(addressFile, street);

READLN(addressFile, city);

IF usa THEN

BEGIN

READLN(addressFile, state); READLN(addressFile, zip(c)

END

ELSE

BEGIN

READLN(addressFile, otherLoc);

READLN(addressFile, country(c)

END

END

END;

CLOSE(addressFile)

END

END;

PROCEDURE NewAddress;

(* -------- ----- ------ ----- ----- ------------- *)

(* Procedura dirijeaza dialogul de introducere pentru *)

(* inregistrarea unei noi adrese; totodata permite salvarea *)

(* sau abandonarea adresei introduse. *)

(* -------- ----- ------ ----- ----- ------------- *)

CONST

yesNo : SET OF CHAR = ['Y', 'N'];

VAR

usaForeign,

inRead,

okToSave : CHAR;

PROCEDURE GetStateAndZip;

(* ---- Extrage statul si codul postal pentru o adresa din SUA ---- *)

BEGIN

WITH addresses[currentRecord] DO

BEGIN

WRITE(' Statul : '); READLN(state);

WRITE(' Codul zip : '); READLN(zip)

END

END;

PROCEDURE GetCountryInfo;

(* ----- Extrage statul/provincia si tara pentru o adresa externa ---- *)

BEGIN

WITH addresses[currentRecord] DO

BEGIN

WRITE(' Statul sau provincia : '); READLN(otherLoc);

WRITE(' Tara : '); READLN(country)

END

END;

PROCEDURE SaveAddress;

(* ---- Salvarea unei noi adrese in fisierul ADDRLIST.TXT ---- *)

BEGIN

IF currentRecord > 1 THEN APPEND(addressFile)

ELSE REWRITE(addressFile);

WITH addresses[currentRecord] DO

BEGIN

WRITELN(addressFile, name);

WRITELN(addressFile, BYTE(headOffice), ' ', BYTE(usa), ' ', refNo);

WRITELN(addressFile, phone); WRITELN(addressFile, street);

WRITELN(addressFile, city);

IF usa THEN

BEGIN

WRITELN(addressFile, state); WRITELN(addressFile, zip)

END

ELSE

BEGIN

WRITELN(addressFile, otherLoc); WRITELN(addressFile, country)

END

END;

CLOSE (addressFile)

END;

BEGIN

WRITELN('Introducerea adresei unui client');

WRITELN('------------ ------- ---- ------'); WRITELN;

INC(currentRecord);

WITH addresses[currentRecord] DO

BEGIN

WRITE(' Numele clientului : '); READLN(name);

refNo := InByte(' Numarul de referinta : ');

WRITE(' Strada clientului : '); READLN(street);

WRITE(' Localitate : '); READLN(city);

usaForeign := InChar('SUA sau Extern (S E) : ', ['S', 'E']);

WRITELN(usaForeign);

usa := (usaForeign = 'S')

END;

CASE addresses[currentRecord].usa OF

TRUE : GetStateAndZip;

FALSE: GetCountryInfo

END;

WITH addresses[currentRecord] DO

BEGIN

WRITE(' Numar telefon : '); READLN(phone);

InRead := InChar(' Antet oficiu (Y N) : ', yesNo);

headOffice := (InRead = 'Y');

WRITELN(InRead)

END;

WRITELN; WRITELN(StringOfChars ('-', 35)); WRITELN;

okToSave := InChar(' Salvati aceasta adresa (Y N) ? ', yesNo);

WRITELN(okToSave);

IF okToSave = 'Y' THEN

SaveAddress

ELSE

DEC (currentRecord);

CLRSCR

END;

PROCEDURE SortAddresses (sortBy: CHAR);

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura foloseste un algoritm de sortare Shell *)

(* pentru aranjarea listei de adrese fie dupa numele *)

(* clientului fie dupa adresa lui; sortBy indica cheia *)

(* de sortare. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

listJump, i, j: BYTE;

sortComplete, sortTest: BOOLEAN;

saveRecord: addressRecord;

BEGIN

listJump := 1;

WHILE listJump <= currentRecord DO

listJump := listJump + 2;

WHILE listJump > 1 DO

BEGIN

listJump := (listJump - 1) DIV 2;

REPEAT

sortComplete := TRUE;

FOR j := 1 TO currentRecord - listJump DO

BEGIN

i := j + listJump;

IF sortBy = nameSort THEN

sortTest := addresses[j].name > addresses[i].name

ELSE

sortTest := addresses[j].refNo > addresses[i].refNo;

IF sortTest THEN

BEGIN

saveRecord := addresses[j]; addresses[j] := addresses[i];

addresses[i] := saveRecord; sortComplete := FALSE

END

END

UNTIL sortComplete

END

END;

PROCEDURE PrintList (addressDirectory: BOOLEAN);

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura asigura listarea fie a adreselor fie a *)

(* numerelor de telefon; argumentul addressesDirectory *)

(* specifica tipul listei de imprimat. *)

(* -------- ----- ------ ----- ----- -------- *)

CONST

formFeed = #12;

VAR

SortSelection, inSpace: CHAR;

FUNCTION Continue: BOOLEAN;

(* -------- ----- ------ ----- ----- ------------ *)

(* Functia accepta un semnal de la utilizator pentru a *)

(* indica actiunea ce urmeaza, astfel : bara spatiu pentru *)

(* tiparirea listei; Escape pentru revenirea in meniu. *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

spaceBar = ' ';

escKey = #27;

prompt 1/2 '<Spatiu> tiparire; <Esc> revenire in meniu';

VAR

inKey: CHAR;

BEGIN

inKey :1/2 InChar (prompt, [spaceBar, escKey]);

Continue := (inKey = spaceBar)

END;

PROCEDURE PrintAddresses;

(* ---- Tiparirea listei cu adresele clientilor ----- *)

VAR

i: BYTE;

BEGIN

WRITELN(LST, ' Lista adreselor clientilor');

WRITELN(LST, ' ----- --------- ----------'); WRITELN(LST);

FOR i := 1 TO currentRecord DO

WITH addresses[i] DO

BEGIN

WRITE(LST, LeftAlign (name, 35), refNo);

IF headOffice THEN WRITELN (LST, ' X'(c) ELSE WRITELN(LST, ' B');

WRITELN(LST, street); WRITE(LST, city, ', ');

IF usa THEN WRITELN (LST, UpperCase (state), ' ', zip)

ELSE WRITELN(LST, otherLoc, ' ', UpperCase (country));

WRITELN(LST, phone); WRITELN(LST); WRITELN(LST)

END

END;

PROCEDURE PrintPhone;

(* ---- Tiparirea listei cu telefoanele clientilor ----- *)

VAR

i: BYTE;

BEGIN

WRITELN(LST, ' Lista telefoanelor clientilor');

WRITELN(LST, ' ----- ------------ ----------'); WRITELN(LST);

WRITELN(LST, 'Nume', Spaces (29)¬ 'Nr.referinta', Spaces (7), 'Telefon');

WRITELN(LST);

FOR i :=1 TO currentRecord DO

WITH addresses[i] DO

BEGIN

WRITE(LST, LeftAlign (name, 35));

WRITE(LST, refNo:3, Spaces (15)); WRITELN(LST, phone)

END

END;

BEGIN

IF addressDirectory THEN

BEGIN

WRITELN('Tiparirea listei de adrese');

WRITELN('--------- ------ -- ------')

END

ELSE

BEGIN

WRITELN('Tiparirea listei de telefoane');

WRITELN('--------- ------ -- ---------')

END;

WRITELN; WRITELN('Sortare dupa :');

WRITELN(' 1. Nume');

WRITELN(' 2. Numar referinata'); WRITELN;

sortSelection :=

InChar(' Selectati 1 sau 2 --> ', [nameSort, refNoSort]);

WRITELN(sortSelection);

SortAddresses(sortSelection);

WRITELN; WRITELN(StringOfChars ('-', 50)); WRITELN;

IF Continue THEN

BEGIN

IF addressDirectory THEN PrintAddresses ELSE PrintPhone;

WRITELN(LST, formFeed)

END;

CLRSCR

END;

PROCEDURE Menu (VAR exitMenu: BOOLEAN);

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura afiseaza pe ecran in mode repetat meniul *)

(* principal si extrage optiunea utilizatorului. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

choice,

discardCode: CHAR;

CONST

menuChars: SET OF CHAR = ['A', 'C', 'I', 'T'];

addresses = TRUE;

phones = FALSE;

PROCEDURE DisplayOption (optionString: STRING);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura afiseaza pe ecran meniul cu optiuni; prima *)

(* litera a optiunii este afisata in video-invers. Aceasta *)

(* procedura foloseste rutina interna TEXTCOLOR. *)

(* -------- ----- ------ ----- ----- ------------ *)

BEGIN

TEXTCOLOR(LightBlue); WRITE (optionString[1]); TEXTCOLOR(LightGray);

WRITELN(COPY (optionString, 2, LENGTH (optionString) - 1))

END;

BEGIN

exitMenu := FALSE;

GOTOXY(20, 5); WRITELN('Managerul adreselor clientilor');

GOTOXY(20, 6); WRITELN('--------- --------- ----------');

GOTOXY(20, 7); DisplayOption('Adaugarea unei adrese.');

GOTOXY(20, 8); DisplayOption('Crearea directorului de adrese.');

GOTOXY(20, 9); DisplayOption('Imprimarea directorului de telefoane.');

GOTOXY(20, 10); DisplayOption('Terminare.'); GOTOXY(20, 12);

choice := InChar('** Optiuni meniu ( A C I T) --> ', menuChars); CLRSCR;

CASE choice OF

'A' : NewAddress;

'C' : IF currentRecord > 0 THEN PrintList (addresses);

'I' : IF currentRecord > 0 THEN PrintList (phones);

'T' : exitMenu := TRUE

END

END;

BEGIN

ASSIGN( addressFile, addressFileName);

currentRecord := 0; ClrScr;

ReadAddresses;

REPEAT Menu (done(c) UNTIL done

END.

CliMenu

(* >>> CliMenu <<< -------- ----- ------ ------ *)

(* Nume fisier : CLIMENU.PAS *)

(* Programul dirijeaza activitatile pe baza unui meniu. *)

(* El foloseste comanda EXEC pentru a lansa in executie *)

(* unul din urmatoarele programe executabile : HOURS.EXE, *)

(* BILLTIME.EXE, CLILIST.EXE si CLIADDR.EXE. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM CliMenu;

USES CRT, DOS, StrUnit;

TYPE

activities= (updateClient, billClient, listClients, listAddresses, quit);

activityRecord= RECORD

fileName: STRING[8];

row, column: BYTE;

menuString: STRING[25]

END;

CONST

columnPos= 24;

optionDisplay= ' U B L P Q ';

nullChar= #10;

enter= #13;

bell= #7;

upArrow= #72;

leftArrow= #75;

rightArrow= #77;

downArrow= #80;

activity: ARRAY[activities] OF activityRecord=

((fileName: 'HOURS'; row: 8; column: columnPos;

menuString: 'Update a client file.'),

(fileName: 'BILLTIME'; row: 9; column: columnPos;

menuString: 'Bill a client file.'),

(fileName: 'CLILIST'; row: 10; column: columnPos;

menuString: 'List account and totals.'),

(fileName: 'CLIADDR'; row: 11; column: columnPos;

menuString: 'Print client addresses.'),

(fileName: ''; row: 12; column: columnPos;

menuString: 'Quit.'));

menuChars: SET OF CHAR= ['U', 'B', 'L', 'P', 'Q', nullChar, enter];

cursorScanCodes: SET OF CHAR= [upArrow, leftArrow, rightArrow, downArrow];

VAR

done: BOOLEAN;

currentSelection: activities;

PROCEDURE ReverseVideo (status: BOOLEAN);

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura afiseaza optiunile in video-normal sau in *)

(* video-invers, in functie de valoarea argumentului. *)

(* -------- ----- ------ ----- ----- ----------- *)

BEGIN

IF status THEN

BEGIN TextColor(Black); TextBackGround(White(c) END

ELSE

BEGIN TextColor(White); TextBackGround(Black(c) END

END;

PROCEDURE HighLightSelection;

(* -------- ----- ------ ----- ----- -------- *)

(* Marcheaza selectia curenta din meniu. Aceasta se *)

(* va afisa in video-invers, cu litere mari. *)

(* -------- ----- ------ ----- ----- -------- *)

BEGIN

ReverseVideo (TRUE);

WITH activity[currentSelection] DO

BEGIN

GoToXY(column, row); WriteLn(UpperCase (menuString))

END;

ReverseVideo(FALSE)

END;

PROCEDURE InitializeMenu;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura asigura afisarea initiala a meniului pe *)

(* ecran, stabilind selectia curenta pe prima optiune(r) *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

option: activities;

BEGIN

ClrScr;

ReverseVideo(TRUE); GoToXY(columnPos - 8, 6);

WriteLn('*** Client-File Management activities ***'); ReverseVideo(FALSE);

FOR option := updateClient TO quit DO

WITH activity[option] DO

BEGIN GoToXY(column, row); WriteLn(menuString(c) END;

currentSelection := updateClient;

HighLightSelection;

GoToXY(columnPos - 12, 16); Write('(Use ');

ReverseVideo(TRUE); Write(#24, ' ', #25, ' ', #26, ' ', #27);

ReverseVideo(FALSE); Write(' or '); ReverseVideo (TRUE);

Write(optionDisplay); ReverseVideo(FALSE); Write(' to highlight on option');

GoToXY(columnPos - 12, 17);

Write('then press <Enter> to complete the selection.)')

END;

PROCEDURE GetSelection (VAR quitSignal: BOOLEAN);

(* ---- Accepta sa execute optiunea selectata ---- *)

CONST

firstChar= 'UBLPQ';

VAR

inChar: CHAR;

PROCEDURE Continue;

(* ---- Pastreaza informatia pe ecran ----- *)

VAR

inSpace: CHAR;

BEGIN

GoToXY(10, 25); Write('Press the space bar to return to the menu.');

REPEAT inSpace := ReadKey UNTIL inSpace = ' '

END;

PROCEDURE RemoveHighLight;

(* ----- Restaurarea optiunii deselectate ----- *)

BEGIN

WITH activity[currentSelection] DO

BEGIN GoToXY(column, row); WriteLn(menuString(c) END

END;

PROCEDURE SelectNextActivity;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura marcheaza optiunea urmatoare din meniu, *)

(* raspunzind astfel la tasta sageata jos sau dreapta. *)

(* -------- ----- ------ ----- ----- ---------- *)

BEGIN

RemoveHighLight;

IF currentSelection = quit THEN currentSelection := updateClient

ELSE currentSelection := SUCC(currentSelection);

HighLightSelection

END;

PROCEDURE SelectPreviousActivity;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura marcheaza optiunea anterioara din meniu, *)

(* raspunzind astfel la tasta sageata sus sau stinga. *)

(* -------- ----- ------ ----- ----- ---------- *)

BEGIN

RemoveHighLight;

IF currentSelection = updateClient THEN currentSelection := quit

ELSE currentSelection := PRED(currentSelection);

HighLightSelection

END;

BEGIN

quitSignal := FALSE;

REPEAT

inChar := UPCASE (ReadKey);

IF NOT (inChar IN menuChars) THEN Write (bell)

UNTIL (inChar IN menuChars);

CASE inChar OF

'U', 'B', 'L', 'P', 'Q':

BEGIN

RemoveHighLight;

currentSelection := activities(POS(inChar, firstChar) - 1);

HighLightSelection

END;

nullChar:

BEGIN

inChar := ReadKey;

IF inChar IN cursorScanCodes THEN

CASE inChar OF

upArrow, leftArrow: SelectPreviousActivity;

downArrow, rightArrow: SelectNextActivity

END

ELSE Write (bell)

END;

enter:

BEGIN

IF currentSelection = quit THEN quitSignal := TRUE

ELSE

BEGIN

WITH activity[currentSelection] DO

EXEC (fileName + '.EXE', '');

Continue; ClrScr;

InitializeMenu

END

END

END

END;

BEGIN

InitializeMenu;

REPEAT

GetSelection (done)

UNTIL done;

ClrScr

END.

Capitolul 8

PtrTest

(* >>> PtrTest <<< -------- ----- ------ - *)

(* Nume fisier : PTRTEST.PAS *)

(* Programul demonstreaza principiile de lucru cu *)

(* variabilele dinamice si cu listele inlantuite. *)

(* Programul creaza o lista inlantuita de articole. *)

(* Fiecare articol din lista contine trei cimpuri : *)

(* ;nextLetter; - pointer catre urmatorul articol; *)

(* ;prevLetter; - pointer catre articolul anterior; *)

(* ;alphChar; - contine un caracter (de la A la Z)*)

(* -------- ----- ------ ----- ----- ------- *)

PROGRAM PtrTest;

USES CRT;

TYPE

alphPtr = ^alphRecord;

alphRecord= RECORD

nextLetter,

prevLetter: alphPtr;

alphChar: CHAR

END;

VAR

firstLetter,

lastLetter,

newLetter,

oldLetter: alphPtr;

letter: CHAR;

PROCEDURE SetLetterPointers;

(* ---- Crearea listei dublu inlantuite ----- *)

BEGIN

letter := 'A'; NEW(newLetter); firstLetter := newLetter;

firstLetter^.prevLetter := NIL; firstLetter^.alphChar := letter;

oldLetter := firstLetter;

WHILE letter <> 'Z' DO

BEGIN

letter := SUCC (letter); NEW (newLetter);

newLetter^.alphChar := letter;

newLetter^.prevLetter := oldLetter;

oldLetter^.nextLetter := newLetter; oldLetter := newLetter

END;

lastLetter := newLetter;

lastLetter^.nextLetter := NIL

END;

PROCEDURE PrintForward;

(* -------- ----- ------ ------------- *)

(* Rutina parcurge, ;inainte;, lista inlantuita *)

(* si afiseaza ficare cimp alphChar. *)

(* -------- ----- ------ ------------- *)

VAR

nextPrintLetter: alphPtr;

BEGIN

nextPrintLetter := firstLetter;

WHILE nextPrintLetter^.nextLetter <> NIL DO

BEGIN

WRITE(nextPrintLetter^.alphChar,' ');

nextPrintLetter := nextPrintLetter^.nextLetter

END;

WriteLn(nextPrintLetter^.alphChar)

END;

PROCEDURE PrintBackward;

(* -------- ----- ------ ------------- *)

(* Rutina parcurge, inapoi, lista inlantuita si *)

(*afiseaza ficare cimp alphChar. *)

(* -------- ----- ------ ------------- *)

VAR

prevPrintLetter: alphPtr;

BEGIN

prevPrintLetter := lastLetter;

WHILE prevPrintLetter^.prevLetter <> NIL DO

BEGIN

WRITE(prevPrintLetter^.alphChar,' ');

prevPrintLetter := prevPrintLetter^.prevLetter

END;

WriteLn (prevPrintLetter^.alphChar)

END;

BEGIN

SetLetterPointers; ClrScr;

WriteLn(' Afisare de la A la Z :'); PrintForward;

WriteLn; WriteLn (' Afisare de la Z la A :'); PrintBackward;

WriteLn; Readln

END.

PtrAddr

(* >>> PtrAddr <<< -------- ----- ------ --- *)

(* Nume fisier : PTRADDR.PAS *)

(* PtrAddr este un program controlat prin meniu. *)

(* El permite adaugarea unei adrese noi, imprimarea *)

(* adreselor sau a telefoanelor clientilor din fisierul *)

(* ADDRLIST.TXT si exemplificarea lucrului cu pointeri. *)

(* -------- ----- ------ ----- ----- --------- *)

PROGRAM PtrAddr;

USES CRT, PRINTER, InUnit, StrUnit;

CONST

addressFileName= 'ADDRLIST.TXT';

numRecords : INTEGER = 0;

TYPE

addressPointer= ^addressRecord;

addressRecord= RECORD

nextName, prevName, nextRefNo, prevRefNo: addressPointer;

name: STRING[30];

phone: STRING[20];

refNo: BYTE;

headOffice: BOOLEAN;

street: STRING[30];

city: STRING[20];

CASE usa: BOOLEAN OF

TRUE : (state: STRING[2];

zip: STRING[6]);

FALSE: (otherLoc, country: STRING[15])

END;

CONST

firstName: addressPointer= NIL;

VAR

firstRefNo, lastName, lastRefNo, newRecord: addressPointer;

addressFile: TEXT;

done: BOOLEAN;

PROCEDURE SetPointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura stabileste pointerii listei inlantuite. *)

(* Aceasta seteaza cele patru cimpuri pointer ale unui *)

(* articol in fiecare nou articol de adresa citit din *)

(* fisierul ADDRLIST.TXT. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

current, previous: addressPointer;

locFound: BOOLEAN;

PROCEDURE FindNamePointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura stabileste pointerii pentru doua tipuri *)

(* de sortare : in ordine alfabetica si in ordine *)

(* invers alfabetica, dupa cimpul name. *)

(* -------- ----- ------ ----- ----- -------- *)

BEGIN

IF newRecord^.name < firstName^.name THEN

BEGIN

newRecord^.nextName := firstName; newRecord^.prevName := NIL;

firstName^.prevName := newRecord; firstName := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstName; current := firstName;

WHILE (NOT locFound) AND (current^.nextName <> NIL) DO

BEGIN

current := current^.nextName;

IF newRecord^.name < current^.name THEN

BEGIN

locFound := TRUE; previous^.nextName := newRecord;

newRecord^.prevName := previous;

newRecord^.nextName := current; current^.prevName := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevName := current; current^.nextName := newRecord;

newRecord^.nextName := NIL; lastName := newRecord

END

END

END;

PROCEDURE FindRefNoPointers;

(* -------- ----- ------ ----- ----- --------- ----- ------ *)

(* Procedura stabileste pointerii pentru doua tipuri de sortare *)

(* numerica: crescatoare si descrescatoare dupa valorile din refNo.*)

(* -------- ----- ------ ----- ----- --------- ----- ------ *)

BEGIN

IF newRecord^.refNo < firstRefNo^. refNo THEN

BEGIN

newRecord^.nextRefNo := firstRefNo; newRecord^.prevRefNo := NIL;

firstRefNo^.prevRefNo := newRecord; firstRefNo := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstRefNo; current := firstRefNo;

WHILE (NOT locFound) AND (current^.nextRefNo <> NIL) DO

BEGIN

current := current^.nextRefNo;

IF newRecord^.refNo < current^.refNo THEN

BEGIN

locFound := TRUE; previous^.nextRefNo := newRecord;

newRecord^.prevRefNo := previous;

newRecord^.nextRefNo := current;

current^.prevRefNo := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevRefNo := current; current^.nextRefNo := newRecord;

newRecord^.nextRefNo := NIL; lastRefNo := newRecord

END

END

END;

BEGIN

IF firstName = NIL THEN

BEGIN

firstName := newRecord; lastName := newRecord;

firstRefNo := newRecord; lastRefNo := newRecord;

WITH newRecord^ DO

BEGIN

nextName := NIL; prevName := NIL;

nextRefNo := NIL; prevRefNo := NIL

END

END

ELSE

BEGIN FindNamePointers; FindRefNoPointeró END

END;

PROCEDURE ReadAddresses;

(* -------- ----- ------ ----- ----- ---------------- *)

(* Procedura deschide fisierul ADDRLIST.TXT si creaza o noua *)

(* variabila dinamica pentru fiecare adresa din fisier. *)

(* -------- ----- ------ ----- ----- ---------------- *)

VAR

OfficeCode, usaCode: BYTE;

BEGIN

RESET (addressFile);

IF IORESULT = 0 THEN

BEGIN

WHILE NOT EOF(addressFile) DO

BEGIN

NEW(newRecord); INC(numRecords);

WITH newRecord^ DO

BEGIN

ReadLn(addressFile, name);

ReadLn(addressFile, officeCode, usaCode, refNo);

headOffice := BOOLEAN(officeCode);

usa := BOOLEAN usaCode); ReadLn(addressFile, phone);

ReadLn(addressFile, street); ReadLn(addressFile, city);

IF usa THEN

BEGIN

ReadLn(addressFile, state); ReadLn(addressFile, zip))

END

ELSE

BEGIN

ReadLn(addressFile,otherLoc); ReadLn(addressFile, country)

END

END;

SetPointers

END;

CLOSE(addressFile);

END

END;

PROCEDURE NewAddress;

(* -------- ----- ------ ----- ----- ------ *)

(* Procedura dirijeaza dialogul de introducere a *)

(* datelor pentru o noua adresa de client si asigura *)

(* salvarea sau nu a adresei introduse. *)

(* -------- ----- ------ ----- ----- ------ *)

CONST

yesNo: SET OF CHAR = ['Y', 'N'];

VAR

UsaForeign, inHead, okToSave: CHAR;

inAddress: addressPointer;

PROCEDURE GetStateAndZip;

(* ---- Extrage codul statului si codul postal (adrese USA) --- *)

BEGIN

WITH inAddress^ DO

BEGIN

Write(' Statul : '); ReadLn(state);

Write(' Codul postal : '); ReadLn(zip)

END

END;

PROCEDURE GetCountryInfo;

(* ----- Extrage statul/provincia si localitatea (adrese externe) --- *)

BEGIN

WITH inAddress^ DO

BEGIN

Write(' Statul sau provincia : '); ReadLn (otherLoc);

Write(' Localitatea : '); ReadLn (country)

END

END;

PROCEDURE SaveAddress;

(* --- Slavarea articolulue introdus in fisierul ADDRLIST.TXT --- *)

BEGIN

IF numRecords > 1 THEN APPEND(addressFile)

ELSE REWRITE(addressFile);

WITH inAddress^ DO

BEGIN

WriteLn(addressFile, name);

WriteLn(addressFile, BYTE (headOffice), ' ', BYTE(usa), ' ', refNo);

WriteLn(addressFile, phone); WriteLn(addressFile, street);

WriteLn(addressFile, city);

IF usa THEN

BEGIN WriteLn(addressFile, state); WriteLn(addressFile, zip) END

ELSE

BEGIN

WriteLn(addressFile, otherLoc); WriteLn(addressFile, country)

END

END;

CLOSE(addressFile)

END;

BEGIN

NEW(inAddress); WriteLn('Se introduce adresa unui nou client');

WriteLn('-- --------- ------ ---- --- ------'); WriteLn;

WITH inAddress^ DO

BEGIN

Write(' Numele clientului : '); ReadLn(name);

refNo := InByte(' Numarul de referinta : ');

Write(' Strada : '); ReadLn(street);

Write(' Localitate : '); ReadLn(city);

usaForeign := InChar('USA sau strain ? (U F) : ', ['U', 'F']);

WriteLn(usaForeign); usa := (usaForeign = 'U')

END;

CASE inAddress^.usa OF

TRUE: GetStateAndZip;

FALSE: GetCountryInfo

END;

WITH inAddress^ DO

BEGIN

Write(' Numar telefon : '); ReadLn (phone);

inHead := InChar(' Oficiu principal ? (Y N) : ', yesNo);

headOffice := (inHead = 'Y'); WriteLn (inHead)

END;

WriteLn; WriteLn(StringOfChars ('-', 30));

WriteLn; okToSave := InChar('Salvati acest articol ? (Y N) : ', yesNo);

IF okToSave = 'Y' THEN

BEGIN

INC(numRecords); SaveAddress;

newRecord := inAddress; SetPointers

END

ELSE

DISPOSE(inAddress);

ClrScr

END;

PROCEDURE PrintList (addressDirectory: BOOLEAN);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura tipareste fie lista adreselor fie lista *)

(* telefoanelor; argumentul addressDirectory specifica *)

(* lista de tiparit, iar sortSelection specifica sortarea. *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

formFeed= #12;

nameAtoZ= '1';

nameZtoA= '2';

refNoAscend= '3';

refNoDescend= '4';

sortSet : SET OF CHAR 1/2 [nameAtoZ, nameZtoA, refNoAscend, refNoDescend];

VAR

sortSelection: CHAR;

firstAddress: addressPointer;

FUNCTION Continue: BOOLEAN;

(* -------- ----- ------ ----- ----- --------- *)

(* Functia asteapta indicatia utilizatorului pentru a *)

(* trece la actiune: bara spatiu pentru tiparire sau *)

(* Escape pentru revenire in program. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST

spaceBar= ' ';

escKey= #27;

prompt= '<Spatiu> tiparire; <Escape> revenire in DOS.';

VAR

inKey: CHAR;

BEGIN

inKey := InChar(prompt, [spaceBar, escKey]);

Continue := (inKey = spaceBar); WriteLn

END;

PROCEDURE PrintAddresses (address: addressPointer; wichSort: CHAR);

(* -------- ----- ------ ----- ----- ------------- *)

(* Procedura tipareste lista adreselor. ;address¢ contine *)

(* pointerul articolului ce se tipareste primul. ;wichSort¢ *)

(* indica cheia si directia operatiei de sortare. *)

(* -------- ----- ------ ----- ----- ------------- *)

VAR i: BYTE;

BEGIN

WriteLn(LST, 'Lista adreselor clientilor');

WriteLn(LST, '----- --------- ----------'); WriteLn(LST);

WHILE address <> NIL DO

BEGIN

WITH address^ DO

BEGIN

Write(LST, LeftAlign(name, 35), refNo:3);

IF headOffice THEN WriteLn(LST, 'H') ELSE WriteLn(LST, 'B');

WriteLn(LST, street); Write(LST, city, ', ');

IF usa THEN WriteLn(LST, UpperCase (state), ' ', zip)

ELSE WriteLn(LST, otherLoc, ' ', UpperCase(country));

WriteLn(LST, phone); WriteLn(LST)

END;

CASE wichSort OF

nameAtoZ : address := address^.nextName;

nameZtoA : address := address^.prevName;

refNoAscend : address := address^.nextRefNo;

refNoDescend : address := address^.prevRefNo

END

END

END;

PROCEDURE PrintPhones (address: addressPointer; wichSort: CHAR);

(* -------- ----- ------ ----- ----- ----------------- *)

(* Procedura tipareste lista telefoanelor. address contine *)

(* pointerul articolului ce se tipareste primul. wichSort *)

(* indica cheia si directia operatiei de sortare. *)

(* -------- ----- ------ ----- ----- ----------------- *)

VAR i: BYTE;

BEGIN

WriteLn(LST, 'Lista telefoanelor clientilor');

WriteLn(LST, '----- ------------ ----------'); WriteLn (LST);

WriteLn(LST, 'Client', Spaces(27), 'Nr.referinta', Spaces(7), 'Telefon');

WriteLn (LST);

WHILE address <> NIL DO

BEGIN

WITH address^ DO

BEGIN

Write(LST,LeftAlign(name,35));

Write(LST,refNo:3,Spaces(10));WriteLn(LST,phone)

END;

CASE wichSort OF

nameAtoZ : address := address^.nextName;

nameZtoA : address := address^.prevName;

refNoAscend : address := address^.nextRefNo;

refNoDescend : address := address^.prevRefNo

END

END

END;

BEGIN

WriteLn;

IF addressDirectory THEN

BEGIN

WriteLn('Tiparirea adreselor'); WriteLn('--------- ---------')

END

ELSE

BEGIN

WriteLn('Tiparirea telefoanelor'); WriteLn('--------- ------------')

END;

WriteLn('Sortare dupa :'); WriteLn;

WriteLn(' 1. Nume (de la A la Z);');

WriteLn(' 2. Nume (de la Z la A);');

WriteLn(' 3. Numar de referinta (crescator);');

WriteLn(' 4. Numar de referinta (descrescator).'); WriteLn;

sortSelection := InChar(' Selectati (1 2 3 4) ---> ', sortSet);

CASE sortSelection OF

nameAtoZ: firstAddress := firstName;

nameZtoA: firstAddress := lastName;

refNoAscend: firstAddress := firstRefNo;

refNoDescend: firstAddress := lastRefNo

END;

WriteLn(StringOfChars ('-', 30)); WriteLn;

IF Continue THEN

BEGIN

IF AddressDirectory THEN

PrintAddresses(firstAddress, sortSelection)

ELSE

PrintPhones(firstAddress, sortSelection);

WriteLn(LST, formFeed)

END

END;

PROCEDURE Menu (VAR exitMenu: BOOLEAN);

(* -------- ----- ------ ----- ----- --------- *)

(* Procedura afiseaza recursiv meniul principal pe *)

(* ecran, si extrage optiunea de meniu a utilizatorului *)

(* -------- ----- ------ ----- ----- --------- *)

VAR

Choice, discardCode: CHAR;

CONST

menuChars: SET OF CHAR = ['A', 'C', 'T', 'I'];

addresses= TRUE;

phones= FALSE;

PROCEDURE DisplayOption (optionString: STRING);

(* -------- ----- ------ ----- ----- ------ *)

(* Procedura afiseaza pe ecran optiunile meniului, *)

(* cu primul caracter afisat in video invers. *)

(* -------- ----- ------ ----- ----- ------ *)

BEGIN

TextColor(White); Write(optionString[1]); TextColor(LightGray);

WriteLn(COPY (optionString, 2, LENGTH (optionString) - 1))

END;

BEGIN

exitMenu := FALSE;

GoToXY(20, 5); WriteLn('Administratorul adreselor clientilor');

GoToXY(20, 6); WriteLn('----- ----- ----- --------- ----------');

GoToXY(20, 7); DisplayOption('Adaugarea unei adrese.');

GoToXY(20, 8); DisplayOption('Crearea directorului de adrese.');

GoToXY(20, 9); DisplayOption('Tiparirea telefoanelor.');

GoToXY(20, 10); DisplayOption('Iesire.'); GoToXY(20, 12);

choice := InChar('** Optiune meniu (A C T I) ---> ', menuChars);

ClrScr;

CASE choice OF

'A': NewAddress;

'C': IF numRecords > 0 THEN PrintList(addresses);

'T': IF numRecords > 0 THEN PrintList(phones);

'I': exitMenu := TRUE

END

END;

BEGIN

ASSIGN (addressFile, addressFileName);

ReadAddresses;

ClrScr;

REPEAT

Menu (done)

UNTIL done

END.

Capitolul 9

NumDemo

(* >>> NumDemo <<< ----- ----- --------- ----- -------- *)

(* Nume fisier : NUMDEMO.PAS *)

(* Programul demonstreaza lucrul cu o parte din *)

(* rutinele numerice standard din Turbo Pascal. *)

(* -------- ----- ------ ----- ----- ----- *)

PROGRAM NumDemo;

USES CRT, InUnit, StrUnit;

VAR

done: BOOLEAN;

arg : REAL;

PROCEDURE ExpLnDemo;

(* -------- ----- ------ ----------- *)

(* Procedura ExpLnDemo demonstreaza modul de *)

(* lucru cu functiile standard EXP si LN. *)

(* -------- ----- ------ ----------- *)

VAR

i: SHORTINT;

BEGIN

WRITELN(Spaces(6), 'n', Spaces(6),'EXP (n)', Spaces(4), 'LN (n)'); WRITELN;

FOR i:= -6 TO 7 DO

BEGIN

arg := i/2;

WRITE(arg:10:4, EXP(arg):10:4);

IF i <= 0 THEN WRITELN(' ~') ELSE WRITELN(LN(arg):10:4)

END

END;

PROCEDURE TrigDemo;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura TrigDemo demonstreaza lucrul cu functiile *)

(* trigonometrice SIN, COS, ARCTAN si cu constanta PI. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

i: SHORTINT;

BEGIN

WRITE(Spaces (4), 'n', Spaces(7), 'SIN (n*PI)', Spaces(4), 'COS (n*PI)');

WRITELN(Spaces (2), 'ARCTAN (n)'); WRITELN;

FOR i:= -8 TO 8 DO

BEGIN

arg := PI * i / 8;

WRITE(i/8:7:4, SIN (arg):13:4, COS(arg):13:4);

WRITELN(ARCTAN(i/8):13:4)

END

END;

PROCEDURE IntDemo;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura IntDemo demonstreaza functiile intregi : *)

(* INT, ROUND si TRUNC, precum si cu functia FRAC. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

i: SHORTINT;

BEGIN

WRITE(' n', Spaces(6), 'INT (n)', Spaces(3), 'ROUND (n)');

WRITELN(Spaces(2), 'TRUNC (n)', Spaces (3), 'FRAC (n)'); WRITELN;

FOR i:= -10 TO 10 DO

BEGIN

arg := i / 4;

WRITE(arg:5:2, INT(arg):10:1, ROUND(arg):10);

WRITELN(TRUNC(arg):10, FRAC(arg):10:2)

END

END;

PROCEDURE ArithDemo;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura ArithDemo demonstreaza modul de lucru *)

(* al functiile : ABS, SQR si SQRT. *)

(* -------- ----- ------ ----- ----- ------- *)

VAR

i: SHORTINT;

BEGIN

WRITE(' n', Spaces(6), 'ABS (n)', Spaces(4), 'SQR (n)');

WRITELN(Spaces(2), 'SQRT (n)'); WRITELN;

FOR i:= -10 to 10 DO

BEGIN

WRITE (i:3, ABS(i):10, SQR(i):10);

IF i < 0 THEN WRITELN (' ~')

ELSE WRITELN(SQRT(i):12:4)

END

END;

PROCEDURE Menu (VAR exitMenu: BOOLEAN);

(* -------- ----- ------ ----- ----- --------- *)

(* Rutina afiseaza pe ecran un meniu si raspunde in *)

(* conformitate cu optiunea utilizatorului. Parametrul *)

(* VAR exitMenu transmite valoarea TRUE daca a fost *)

(* selectata optiunea Iesire. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST

col = 25;

VAR

optiune : CHAR;

contSemnal: STRING;

BEGIN

CLRSCR; exitMenu := FALSE;

GOTOXY(col - 5,5); WRITELN('Functii numerice standard');

GOTOXY(col, 7); WRITELN('1, Exponentiale');

GOTOXY(col, 8); WRITELN('2, Trigonometrice');

GOTOXY(col, 9); WRITELN('3, Intregi');

GOTOXY(col,10); WRITELN('4, Aritmetice');

GOTOXY(col,11); WRITELN('5, Iesire'); GOTOXY(col-3, 13);

optiune:= InChar(' ** Optiune meniu : 1 - 5 *** ',['1'..'5']); CLRSCR;

CASE optiune OF

'1': ExpLnDemo;

'2': TrigDemo;

'3': IntDemo;

'4': ArithDemo;

'5': exitMenu := TRUE

END;

IF optiune <> '5' THEN

BEGIN

WRITELN;

contSemnal := InChar(' Apasati <spatiu> pentru continuare ',[' ']);

END;

CLRSCR

END;

BEGIN

REPEAT

Menu (done)

UNTIL done

END.

RandAddr

(* >>> RandAddr <<< -------- ----- ------ ------ *)

(* Nume fisier : RANDADDR.PAS *)

(* Programul simuleaza date pentru testarea algoritmilor *)

(* din PtrAddr. RandAddr creaza fisierul RANDTEST.TXT, care *)

(* contine liste de nume si numere de referinta generate *)

(* aleator si sortate dupa patru criterii diferite. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM RandAddr;

USES CRT, RandUnit;

CONST

recsToCreate= 8;

numRecords: INTEGER = 0;

TYPE

addressPointer= ^addressRecord;

addressRecord= RECORD

nextName, prevName, nextRefNo, prevRefNo: addressPointer;

name: STRING[30];

phone: STRING[20];

refNo: BYTE;

headOffice: BOOLEAN;

street: STRING[30];

city: STRING[20];

CASE usa: BOOLEAN OF

TRUE: (state: STRING[2];

zip: STRING[5]);

FALSE: (otherLoc, country: STRING[13])

END;

CONST

firstName: addressPointer= NIL;

VAR

FirstRefNo, lastName, LastRefNo, newRecord: addressPointer;

PROCEDURE SetPointers;

(* -------- ----- ------ ----- ----- ----------- *)

(* Rutina stabileste pointerii listei inlantuite, adica *)

(* valorile pentru cele patru cimpuri de tip pointer din *)

(* fiecare nou articol generat. *)

(* -------- ----- ------ ----- ----- ----------- *)

VAR

current, previous: addressPointer;

locFound: BOOLEAN;

PROCEDURE FindNamePointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Rutina stabileste poinerii pentru doua ordini de *)

(* sortare : alfabetica si invers alfabetica, pentru *)

(* datele simulate si inregistrate in cimpul ;name;. *)

(* -------- ----- ------ ----- ----- -------- *)

BEGIN

IF newRecord^.name < firstName^.name THEN

BEGIN

newRecord^.nextName := firstName; newRecord^.prevName := NIL;

firstName^.prevName := newRecord; firstName := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstName; current := firstName;

WHILE (NOT locFound) AND (current^.nextName <> NIL) DO

BEGIN

current := current^.nextName;

IF newRecord^.name < current^.name THEN

BEGIN

locFound := TRUE; previous^.nextName := newRecord;

newRecord^.prevName := previous;

newRecord^.nextName := current;

current^.prevName := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevName := current; current^.nextName := newRecord;

newRecord^.nextName := NIL; lastName := newRecord

END

END

END;

PROCEDURE FindRefNoPointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura stabileste pointerii pentru doua tipuri *)

(* de sortare numerica : crescatoare si descrescatoare *)

(* dupa valorile generate aleator pentru cimpul refNo. *)

(* -------- ----- ------ ----- ----- -------- *)

BEGIN

IF newRecord^.refNo < firstRefNo^. refNo THEN

BEGIN

newRecord^.nextRefNo := firstRefNo; newRecord^.prevRefNo := NIL;

firstRefNo^.prevRefNo := newRecord; firstRefNo := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstRefNo; current := firstRefNo;

WHILE (NOT locFound) AND (current^.nextRefNo <> NIL) DO

BEGIN

current := current^.nextRefNo;

IF newRecord^.refNo < current^.refNo THEN

BEGIN

locFound := TRUE; previous^.nextRefNo := newRecord;

newRecord^.prevRefNo := previous;

newRecord^.nextRefNo := current;

current^.prevRefNo := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevRefNo := current; current^.nextRefNo := newRecord;

newRecord^.nextRefNo := NIL; lastRefNo := newRecord

END

END

END;

BEGIN

IF firstName = NIL THEN

BEGIN

firstName := newRecord; lastName := newRecord;

firstRefNo := newRecord; lastRefNo := newRecord;

WITH newRecord^ DO

BEGIN

nextName := NIL; prevName := NIL;

nextRefNo := NIL; prevRefNo := NIL

END

END

ELSE BEGIN FindNamePointers; FindRefNoPointers END

END;

PROCEDURE CreateAddressPointers;

(* -------- ----- ------ ----- ----- ---------- *)

(* Rutina creaza date simulate pentru fiecare articol *)

(* dinamic nou; foloseste rutinele unit-ului RandUnit. *)

(* -------- ----- ------ ----- ----- ---------- *)

BEGIN

WriteLn (' Creaza si sorteaza ', recsToCreate, ' articole.');

REPEAT

NEW (newRecord); INC (numRecords); WriteLn ('Articolul : ',numRecords:3);

WITH newRecord^ DO

BEGIN

name := RandStr(10); refNo := RandInt(1, 255);

headOffice := RandBoolean; usa := RandBoolean;

phone := RandStr(10); street := RandStr(30); city := RandStr(20);

IF usa THEN

BEGIN state := RandStr(2); zip := RandStr(5) END

ELSE

BEGIN otherLoc := RandStr(15); country := RandStr(15) END

END;

SetPointers

UNTIL (numRecords = recsToCreate)

END;

PROCEDURE PrintList;

(* -------- ----- ------ ----- ----- ------------ *)

(* Rutina creaza patru liste sortate si le inregistreza *)

(* in fisierul RANDTEST.TXT. Listele contin doua coloane, *)

(* sirurile numelor si numerele de referinta simulate. *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

textFileName= 'RANDTEST.TXT';

TYPE

sortTypes= (nameAtoZ, nameZtoA, refNoAscend, refNoDescend);

VAR

nextRecord: addressPointer;

wichSort: sortTypes;

textFile: TEXT;

BEGIN

ASSIGN (textFile, textFileName); REWRITE (textFile);

WriteLn; WriteLn; WriteLn (' Se creaza fisierul ', textFileName, '.');

FOR wichSort := nameAtoZ TO refNoDescend DO

BEGIN

CASE wichSort OF

nameAtoZ: BEGIN

nextRecord := firstName;

WriteLn(textFile, 'Sortare dupa nume, A la Z :')

END;

nameZtoA: BEGIN

nextRecord := lastName;

WriteLn(textFile, 'Sortare dupa nume, Z la A :')

END;

refNoAscend: BEGIN

nextRecord := firstRefNo;

WriteLn(textFile, 'Sortare dupa nr.ref., ascendent:')

END;

refNoDescend: BEGIN

nextRecord := lastRefNo;

WriteLn(textFile, 'Sortare dupa nr.ref., descendent:')

END

END;

WriteLn (textFile);

WHILE nextRecord <> NIL DO

WITH nextRecord^ DO

BEGIN

WriteLn (textFile, name, ' ', refNo);

CASE wichSort OF

nameAtoZ: nextRecord := nextName;

nameZtoA: nextRecord := prevName;

refNoAscend: nextRecord := nextRefNo;

refNoDescend: nextRecord := prevRefNo

END

END; WriteLn(textFile); WriteLn(textFile);

END;

CLOSE (textFile)

END;

BEGIN

RANDOMIZE;

ClrScr;

CreateAddressPointers;

PrintList; ReadLn

END.

Capitolul 10

AddrCom

(* >>> AddrCom <<< -------- ----- ------ ------ *)

(* Nume fisier : ADDRCOM.PAS *)

(* AddrCom este o versiune in stil comanda a programului *)

(* PtrAddr. Programul tipareste lista adreselor sau lista *)

(* telefoanelor consultind fisierul ADDRLIST.TXT. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM AddrCom;

USES CRT, PRINTER, InUnit, StrUnit;

CONST

addressFileName= 'ADDRLIST.TXT';

numRecords : INTEGER = 0;

TYPE

addressPointer= ^addressRecord;

addressRecord= RECORD

nextName, prevName, nextRefNo, prevRefNo: addressPointer;

name: STRING[30];

phone: STRING[20];

refNo: BYTE;

headOffice: BOOLEAN;

street: STRING[30];

city: STRING[20];

CASE usa: BOOLEAN OF

TRUE : (state: STRING[2];

zip: STRING[6]);

FALSE: (otherLoc, country: STRING[15])

END;

sortOptions= (nameAtoZ, nameZtoA, refNoAscend, refNoDescend);

argString= STRING[3];

CONST

firstName: addressPointer= NIL;

VAR

firstRefNo, lastName, lastRefNo, newRecord: addressPointer;

addressFile: TEXT;

args: argString;

PROCEDURE SetPointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura stabileste pointerii listei inlantuite. *)

(* Aceasta seteaza cele patru cimpuri pointer ale unui *)

(* articol in fiecare nou articol de adresa citit din *)

(* fisierul ADDRLIST.TXT. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

current, previous: addressPointer;

locFound: BOOLEAN;

PROCEDURE FindNamePointers;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura stabileste pointerii pentru sortarea *)

(* alfabetica si invers alfabetica, dupa cimpul name. *)

(* -------- ----- ------ ----- ----- ------- *)

BEGIN

IF newRecord^.name < firstName^.name THEN

BEGIN

newRecord^.nextName := firstName; newRecord^.prevName := NIL;

firstName^.prevName := newRecord; firstName := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstName; current := firstName;

WHILE (NOT locFound) AND (current^.nextName <> NIL) DO

BEGIN

current := current^.nextName;

IF newRecord^.name < current^.name THEN

BEGIN

locFound := TRUE; previous^.nextName := newRecord;

newRecord^.prevName := previous;

newRecord^.nextName := current;

current^.prevName := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevName := current; current^.nextName := newRecord;

newRecord^.nextName := NIL; lastName := newRecord

END

END

END;

PROCEDURE FindRefNoPointers;

(* -------- ----- ------ ----- ----- -------- *)

(* Procedura stabileste pointerii pentru doua tipuri *)

(* de sortare numerica : crescatoare si descrescatoare *)

(* dupa valorile cimpului refNo. *)

(* -------- ----- ------ ----- ----- -------- *)

BEGIN

IF newRecord^.refNo < firstRefNo^. refNo THEN

BEGIN

newRecord^.nextRefNo := firstRefNo; newRecord^.prevRefNo := NIL;

firstRefNo^.prevRefNo := newRecord; firstRefNo := newRecord

END

ELSE

BEGIN

locFound := FALSE; previous := firstRefNo; current := firstRefNo;

WHILE (NOT locFound) AND (current^.nextRefNo <> NIL) DO

BEGIN

current := current^.nextRefNo;

IF newRecord^.refNo < current^.refNo THEN

BEGIN

locFound := TRUE; previous^.nextRefNo := newRecord;

newRecord^.prevRefNo := previous;

newRecord^.nextRefNo := current;

current^.prevRefNo := newRecord

END

ELSE previous := current

END;

IF (NOT locFound) THEN

BEGIN

newRecord^.prevRefNo := current; current^.nextRefNo := newRecord;

newRecord^.nextRefNo := NIL; lastRefNo := newRecord

END

END

END;

BEGIN

IF firstName = NIL THEN

BEGIN

firstName := newRecord; lastName := newRecord;

firstRefNo := newRecord; lastRefNo := newRecord;

WITH newRecord^ DO

BEGIN

nextName := NIL; prevName := NIL;

nextRefNo := NIL; prevRefNo := NIL

END

END

ELSE BEGIN FindNamePointers; FindRefNoPointers END

END;

PROCEDURE ReadAddresses;

(* -------- ----- ------ ----- ----- -------------- *)

(* Procedura deschide fisierul ADDRLIST.TXT si creaza o *)

(* noua variabila dinamica pentru fiecare adresa din fisier. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

officeCode, usaCode: BYTE;

BEGIN

RESET (addressFile);

IF IORESULT = 0 THEN

BEGIN

WHILE NOT EOF(addressFile) DO

BEGIN

NEW(newRecord); INC(numRecords);

WITH newRecord^ DO

BEGIN

ReadLn(addressFile, name);

ReadLn(addressFile, officeCode, usaCode, refNo);

headOffice := BOOLEAN (officeCode);

usa := BOOLEAN(usaCode); ReadLn(addressFile, phone);

ReadLn(addressFile, street); ReadLn(addressFile, city);

IF usa THEN

BEGIN

ReadLn(addressFile, state); ReadLn(addressFile, zip)

END

ELSE

BEGIN

ReadLn(addressFile, otherLoc); ReadLn(addressFile, country)

END

END;

SetPointers

END; CLOSE (addressFile);

END

END;

PROCEDURE PrintList (addressDirectory: BOOLEAN; sortSelection: sortOptions);

(* -------- ----- ------ ----- ----- --------- *)

(* Procedura tipareste fie lista adreselor fie lista *)

(* telefoanelor; argumentul addressDirectory specifica *)

(* ce lista se tipareste, iar sortSelection specifica *)

(* tipul ordonarii. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST

formFeed= #12;

VAR

firstAddress: addressPointer;

FUNCTION Continue: BOOLEAN;

(* -------- ----- ------ ----- ----- --------- *)

(* Functia asteapta indicatia utilizatorului pentru a *)

(* trece la actiune: bara spatiu pentru tiparire sau *)

(* Escape pentru revenire in program. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST

spaceBar= ' ';

escKey= #27;

prompt= '<Spatiu> tiparire; <Escape> revenire in DOS.';

VAR

inKey: CHAR;

BEGIN

inKey := InChar(prompt, [spaceBar, escKey]);

Continue := (inKey = spaceBar);

WriteLn

END;

PROCEDURE PrintAddresses (address: addressPointer; wichSort: sortOptions);

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura tipareste lista adreselor. Argumentul *)

(* address contine pointerul articolului ce se tipareste *)

(* primul. Parametrul wichSort indica cheia si directia *)

(* operatiei de sortare. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

i: BYTE;

BEGIN

WriteLn(LST, 'Lista adreselor clientilor');

WriteLn(LST, '----- --------- ----------'); WriteLn(LST);

WHILE address <> NIL DO

BEGIN

WITH address^ DO

BEGIN

Write(LST, LeftAlign(name, 35), refNo:3);

IF headOffice THEN WriteLn(LST, 'H')

ELSE WriteLn(LST, 'B');

WriteLn(LST, street); Write(LST, city, ', ');

IF usa THEN

WriteLn(LST, UpperCase(state), ' ', zip)

ELSE

WriteLn(LST, otherLoc, ' ', UpperCase(country));

WriteLn(LST, phone); WriteLn(LST)

END;

CASE wichSort OF

nameAtoZ : address := address^.nextName;

nameZtoA : address := address^.prevName;

refNoAscend : address := address^.nextRefNo;

refNoDescend : address := address^.prevRefNo

END

END

END;

PROCEDURE PrintPhones (address: addressPointer; wichSort: SortOptions);

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura tipareste lista telefoanelor. Argumentul *)

(* address contine pointerul articolului ce se tipareste *)

(* primul. Parametrul wichSort indica cheia si directia *)

(* operatiei de sortare. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

i: BYTE;

BEGIN

WriteLn(LST, 'Lista telefoanelor clientilor');

WriteLn(LST, '----- ------------ ----------'); WriteLn (LST);

WriteLn(LST, 'Client', Spaces(27), 'Nr.referinta', Spaces(7), 'Telefon');

WriteLn(LST);

WHILE address <> NIL DO

BEGIN

WITH address^ DO

BEGIN

Write(LST, LeftAlign(name, 35));

Write(LST, refNo:3, Spaces(10)); WriteLn(LST, phone)

END;

CASE wichSort OF

nameAtoZ : address := address^.nextName;

nameZtoA : address := address^.prevName;

refNoAscend : address := address^.nextRefNo;

refNoDescend : address := address^.prevRefNo

END

END

END;

BEGIN

WriteLn;

IF addressDirectory THEN

BEGIN WriteLn('Tiparirea adreselor'); WriteLn('--------- ---------') END

ELSE

BEGIN

WriteLn('Tiparirea telefoanelor'); WriteLn('--------- ------------')

END;

CASE sortSelection OF

nameAtoZ: firstAddress := firstName;

nameZtoA: firstAddress := lastName;

refNoAscend: firstAddress := firstRefNo;

refNoDescend: firstAddress := lastRefNo

END;

IF Continue THEN

BEGIN

IF AddressDirectory THEN

PrintAddresses(firstAddress, sortSelection)

ELSE

PrintPhones(firstAddress, sortSelection);

WriteLn(LST, formFeed)

END

END;

PROCEDURE Explain;

(* -------- ----- ------ ----- ----- --------- ----- ------- *)

(* Procedura afiseaza instructiunile de utilizarea a programului. *)

(* -------- ----- ------ ----- ----- --------- ----- ------- *)

CONST indent= 13;

BEGIN

WriteLn; WriteLn; WriteLn; WriteLn(StringOfChars ('-', 64));

Write(' Programul ADDRCOM tipareste lista ');

WriteLn('adreselor sau telefoanelor');

WriteLn('clientilor din fisierul ADDRLIST.TXT.'); WriteLn;

Write(' In linia de comanda a programului ');

WriteLn('trebuie sa se includa trei');

WriteLn('argumente separate prin spatii :'); WriteLn;

WriteLn(' Primul argument :');

Write(Spaces(indent), '"a" sau "address" : ');

WriteLn('lista adreselor.');

Write(Spaces(indent), '"p" sau "phone" : ');

WriteLn('lista telefoanelor.'); WriteLn;

WriteLn(' Al doilea argument :');

Write(Spaces(indent), '"n" sau "names" : ');

WriteLn('sortarea dupa nume.');

Write(Spaces(indent), '"r" sau "ref" : ');

WriteLn('sortarea dupa nr. referinta.'); WriteLn;

WriteLn(' Al treilea argument :');

Write(Spaces (indent), '"a" sau "ascending" : ');

WriteLn('sortare crescatoare');

Write(Spaces(indent), '"d" sau "descending" : ');

WriteLn('sortare descrescatoare.'); WriteLn;

WriteLn(StringOfChars ('-', 64))

END;

FUNCTION CheckArguments(VAR userArgs: argString): BOOLEAN;

(* -------- ----- ------ ----- ----- ---------- *)

(* Functia citeste cele trei argumente furnizate de *)

(* catre utilizator si determina daca ele sint corecte. *)

(* Daca argumentele sint corecte functia returneaza TRUE,*)

(* iar caracterele argumentelor se vor gasi in userArgs. *)

(* -------- ----- ------ ----- ----- ---------- *)

TYPE

testSet= SET OF CHAR;

CONST

setArray: ARRAY[1..3] OF testSet1/2 (['A', 'P'], ['N', 'R'], ['A', 'D']);

VAR

ok: BOOLEAN;

i: BYTE;

temp: CHAR;

BEGIN

ok := TRUE; userArgs := '';

IF PARAMCOUNT = 3 THEN

FOR i := 1 TO 3 DO

BEGIN

temp := UPCASE(FirstChar (PARAMSTR(i)));

ok := ok AND (temp IN setArray[i]);

IF ok THEN userArgs := userArgs + temp

END

ELSE ok := FALSE;

CheckArguments := ok

END;

PROCEDURE DoCommand (arguments: argString);

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura prelucreaza cerintele utilizatorului prin *)

(* apelarea rutinelor de tiparire, transmitind acestora *)

(* instructiunile corecte pentru sortare. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

printAddresses: BOOLEAN;

wichSort: sortOptions;

BEGIN

IF (Left(Arguments, 1) = 'A') THEN printAddresses := TRUE

ELSE printAddresses := FALSE;

IF (COPY(arguments, 2, 1) = 'N') THEN

BEGIN

IF (Right(arguments, 1) = 'A') THEN wichSort := nameAtoZ

ELSE wichSort := nameZtoA

END

ELSE

BEGIN

IF (Right(arguments, 1) = 'A') THEN wichSort := refNoAscend

ELSE wichSort := refNoDescend

END;

PrintList(printAddresses, wichSort)

END;

BEGIN

ClrScr;

IF CheckArguments (args) THEN

BEGIN

ASSIGN(addressFile, addressFileName);

ReadAddresses;

DoCommand(args)

END

ELSE

explain;

END.

Capitolul 11

CliChart

(* >>> CliChart <<< -------- ----- ------ - *)

(* Nume fisier : CLICHART.PAS *)

(* Programul pregateste o statistica care reprezinta *)

(* grafic orele inregistrate in fisierele .HRS gasite *)

(* in directorul curent. Statistica este memorata in *)

(* fisierul text HRSCHART.TXT. *)

(* -------- ----- ------ ----- ----- -------- *)

PROGRAM CliChart;

USES CRT, DOS, StrUnit;

CONST

maxClients = 100;

TYPE

clientRecord = RECORD

name: STRING;

totalHours: REAL

END;

VAR

clientFiles: ARRAY [1..maxClients] OF clientRecord;

listLength, i: BYTE;

chartFactor: REAL;

PROCEDURE GetFiles (VAR numberOfFiles: BYTE; VAR scaleFactor: REAL);

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura formeaza o lista cu toate fisierele .HRS *)

(* din directorul curent. Numele fisierelor si totalul *)

(* orelor din fiecare fisier sint memorate in articolele *)

(* clientFiles. De asemenea, procedura determina factorul *)

(* de scala ce va fi utilizat de program pentru grafica. *)

(* -------- ----- ------ ----- ----- ----------- *)

CONST

fileName = 'HRSDIR.TXT';

chartWidth = 40;

largestTotal: REAL = 0.0;

VAR

dirFile: TEXT;

recNum, extensionPos, firstSpace: BYTE;

dirLine: STRING[40];

clientName: STRING;

FUNCTION MaxReal (value1, value2: REAL): REAL;

(* -------- ----- ------ ----- ----- -------- *)

(* Functia determina care dintre cele doua argumente *)

(* receptionate este cel mai mare. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

temp: REAL;

BEGIN

IF value1 > value2 THEN temp := value1 ELSE temp := value2;

MaxReal := temp

END;

FUNCTION TotalAccount (targetFileName: STRING): REAL;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia deschide un fisier .HRS, citeste toate *)

(* intrarile lui si determina numarul total de ore *)

(* inregistrate in fisier. *)

(* -------- ----- ------ ----- ----- ------ *)

VAR

total, hours: REAL;

targetFile: TEXT;

chronInfoString: STRING[29];

BEGIN

total := 0.0; ASSIGN(targetFile, targetFileName); RESET(targetFile);

WHILE NOT EOF (targetFile) DO

BEGIN

READLN(targetFile, chronInfoString, hours); total := total + hours

END;

CLOSE(targetFile);

TotalAccount := total

END;

BEGIN

EXEC('\COMMAND.COM', '/C DIR *.HRS > ' + fileName);

ASSIGN(dirFile, fileName); RESET(dirFile); recNum := 0;

WHILE NOT EOF(dirFile) DO

BEGIN

READLN(dirFile, dirLine); extensionPos := POS('.HRS', dirLine);

IF extensionPos <> 0 THEN

BEGIN

INC(recNum); firstSpace := POS(' ', dirLine);

clientName := LeftAlign(dirLine, firstSpace - 1);

WITH clientFiles[recNum] DO

BEGIN

name := clientName;

totalHours := TotalAccount (clientName + '.HRS');

largestTotal := MaxReal(largestTotal, totalHours)

END

END

END;

CLOSE(dirFile);

scaleFactor := chartWidth / largestTotal; numberOfFiles := recNum

END;

PROCEDURE SortClientFiles (sortLength: BYTE);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura foloseste algoritmul Shell pentru sortarea *)

(* tabloului de articole, clientFiles, dupa cimpul nume. *)

(* -------- ----- ------ ----- ----- ------------ *)

VAR

listJump, i, j: BYTE;

sortComplete: BOOLEAN;

saveRecord: clientRecord;

BEGIN

listJump := 1;

WHILE listJump <= sortLength DO listJump := listJump + 2;

WHILE listJump > 1 DO

BEGIN

listJump := (listJump - 1) DIV 2;

REPEAT

sortComplete := TRUE;

FOR j := 1 TO sortLength - listJump DO

BEGIN

i := j + listJump;

IF clientFiles[j].name > clientFiles[i].name THEN

BEGIN

saveRecord := clientFiles[j];

clientFiles[j] := clientFiles[i];

clientFiles[i] := saveRecord; sortComplete := FALSE

END

END

UNTIL sortComplete

END

END;

PROCEDURE CreateChart (printLength: BYTE; scaleFactor: REAL);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura creaza un fisier grafic numit HRSCHART.TXT. *)

(* Graficul contine o linie de text pentru fiecare articol *)

(* din tabloul clientFiles. *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

chartFileName = 'HRSCHART.HRS';

chartChar = '*';

VAR

i, j: BYTE;

inChar: CHAR;

chartFile: TEXT;

lengthOfChart: BYTE;

BEGIN

ASSIGN(chartFile, chartFileName); REWRITE(chartFile);

FOR i := 1 TO printLength DO

WITH clientFiles[i] DO

BEGIN

WRITE(chartFile, Left(InitialCap (name), 11));

WRITE(chartFile, totalHours:3:0);

lengthOfChart := ROUND(totalHours * scaleFactor);

WRITE(chartFile, ' ');

WRITELN(chartFile, StringOfChars(chartChar, lengthOfChart))

END;

CLOSE(chartFile)

END;

BEGIN

CLRSCR; WRITELN('Crearea statisticii fisierelor clientilor');

WRITELN('------- ----------- ---------- ----------'); WRITELN;

GetFiles(listLength, chartFactor);

SortClientFiles (listLength);

WRITELN('Crearea fisierului HRSCHART.TXT pe disc');

WRITELN(' Acesta este un fisier de tip ;text;');

WRITELN(' care poate fi citit cu un editor.'); WRITELN;

CreateChart(listLength, chartFactor)

END.

RandFile

(* >>> RandFile <<< -------- ----- ------ ---- *)

(* Nume fisier : RANDFILE.PAS *)

(* Programul RandFile ilustreaza folosirea rutinelor *)

(* standard SEEK, FILEPOS, FILESIZE, READ si WRITE pentru *)

(* fisiere cu tip (fisiere in acces direct). Programul *)

(* creaza fisierul reprezentat prin variabila fisier *)

(* randFileVar, inregistrind o succesiune de articole, *)

(* dupa care se executa cautarea aleatore si afisarea pe *)

(* ecran a articolului cerut. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM RandFile;

CONST

randFileName = 'RANDFILE.DAT';

maxRecords = 26;

TYPE

fileRecordType = RECORD

ordChar: CHAR;

ordByte: BYTE

END;

VAR

randFileVar: FILE OF fileRecordType;

fileRecord: fileRecordType;

PROCEDURE FillFile;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura FillFile memoreaza maxRecords articole in *)

(* fisierul cu tip reprezentat prin randFileVar. *)

(* -------- ----- ------ ----- ----- ----------- *)

CONST

letter: CHAR = 'A';

VAR

i: BYTE;

BEGIN

ASSIGN(randFileVar, randFileName); REWRITE(randFileVar);

FOR i := 1 TO maxRecords DO

BEGIN

WITH fileRecord DO BEGIN ordChar := letter; ordByte := i END;

WRITE(randFileVar, fileRecord);

letter := SUCC (letter)

END;

CLOSE(randFileVar)

END;

PROCEDURE RandRead;

(* -------- ----- ------ ----- ----- ----------- *)

(* Rutina citeste in acces direct articolele selectate *)

(* si afiseaza valorile cimpurilor. *)

(* -------- ----- ------ ----- ----- ----------- *)

CONST

doneRecord: fileRecordType = (ordChar: ' '; ordByte: 0);

maxRead = 5;

VAR

i, targetRecordNum: BYTE;

BEGIN

RESET(randFileVar); i := 0;

REPEAT

targetRecordNum := RANDOM(FILESIZE (randFileVar) - 1);

SEEK(randFileVar, targetRecordNum);

READ(randFileVar, fileRecord);

SEEK(randFileVar, targetRecordNum);

WITH fileRecord DO

IF ordChar <> ' ' THEN

BEGIN

WRITELN(' Articolul #', FILEPOS (randFileVar));

WRITELN(' cimpul Char: ', ordChar);

WRITELN(' cimpul Byte: ', ordByte);

WRITE(randFileVar, doneRecord); INC(i); WRITELN

END;

UNTIL i = maxRead;

CLOSE(randFileVar)

END;

BEGIN

RANDOMIZE;

FillFile;

RandRead;

READLN

END.

CliProf

(* >>> CliProf <<< -------- ----- ------ ---- *)

(* Nume Fisier : CLIPROF.PAS *)

(* Programul intretine o baza de date cu informatii *)

(* despre clienti. Baza de date este inregistrata in *)

(* fisierul PROFILE.DAT. Fisierul PROFILE.NDX serveste *)

(* pentru indexarea bazei de date. *)

(* Programul este controlat print-un meniu, permitind *)

(* adaugarea unui nou articol, afisarea unui articol sau *)

(* modificarea unui articol existent. *)

(* -------- ----- ------ ----- ----- ---------- *)

PROGRAM CliProf;

USES CRT, ChrnUnit, InUnit, StrUnit;

TYPE

nameString = STRING[30];

profileRecord = RECORD

name: nameString;

refNo: BYTE;

businessType: STRING[15];

recordDate: STRING[20];

contactPerson: STRING[20];

phoneNumber: STRING[15];

hoursLastYear: REAL

END;

indexRecord = RECORD

clientName: nameString;

recordNumber: INTEGER

END;

activities = (adaugare, listare, modificare, iesire);

activityRange = adaugare..iesire;

activityRecord = RECORD

row, column: BYTE;

menuString: STRING[35]

END;

CONST

maxRecords = 250;

columnPos = 24;

optionDisplay= ' A L M I ';

profileDone = 'PROFILE.DAT';

indexFileName= 'PROFILE.NDX';

activity: ARRAY[activityRange] OF activityRecord =

((row: 10; column: columnPos;

menuString: 'Adaugarea datelor unui nou client.'),

(row: 11; column: columnPos;

menuString: 'Listarea datelor unui client.'),

(row: 12; column: columnPos;

menuString: 'Modificarea datelor unui client.'),

(row: 13; column: columnPos;

menuString: 'Iesire din program'));

nullChar = #0;

enter = #13;

bell = #7;

upArrow = #72;

leftArrow = #75;

rightArrow = #77;

downArrow = #80;

menuChars: SET OF CHAR = ['A', 'L', 'M', 'I', nullChar, enter];

cursorScanCode: SET OF CHAR = [upArrow, downArrow, rightArrow, leftArrow];

VAR

profile : profileRecord;

index : ARRAY[1..maxRecords] OF indexRecord;

profileFile : FILE OF profileRecord;

indexFile : TEXT;

fileLength: INTEGER;

done, ready: BOOLEAN;

currentSelection: activities;

PROCEDURE ReverseVideo (status: BOOLEAN );

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura comuta starea afisarii ecranului in video *)

(* invers sau video normal in functie de valoarea de tip *)

(* boolean receptionata. *)

(* -------- ----- ------ ----- ----- ---------- *)

BEGIN

IF status THEN BEGIN TEXTCOLOR(Blue); TEXTBACKGROUND(LightGray) END

ELSE BEGIN TEXTCOLOR(White); TEXTBACKGROUND(Black) END

END;

PROCEDURE HighLightSelection;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura supralumineaza selectia curenta. Selectia *)

(* si toate literele mari sint afisate in video-invers. *)

(* -------- ----- ------ ----- ----- ----------- *)

BEGIN

ReverseVideo (TRUE);

WITH activity[currentSelection] DO

BEGIN GOTOXY(column, row); WRITELN(UpperCase(menuString)) END;

ReverseVideo (FALSE); GOTOXY (60,17)

END;

PROCEDURE InitializeMenu;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura afiseaza meniul pe ecran si stabileste *)

(* currentSelection pe prima optiune a meniului. *)

(* -------- ----- ------ ----- ----- ------- *)

VAR

option: activities;

BEGIN

CLRSCR; ReverseVideo(TRUE);

GOTOXY(columnPos - 7, 6); WRITELN('*** Dispecerul bazei de date ***');

ReverseVideo(FALSE);

GOTOXY(columnPos - 12, 16); WRITE('(Folositi ');

ReverseVideo(TRUE); WRITE(#24, ' ', #25, ' ', #26, ' ', #27);

ReverseVideo(FALSE); WRITE(' sau '); ReverseVideo(TRUE);

WRITE(optionDisplay); ReverseVideo(FALSE);

WRITE(' pentru a marca o optiune,'); GOTOXY(columnPos - 10, 17);

WRITE('apoi apasati <Enter> pentru a termina selectia.)');

FOR option := adaugare TO iesire DO

WITH activity[option] DO

BEGIN GOTOXY(column, row); WRITELN(menuString) END;

GOTOXY(columnPos + 5, 2);

WRITE('In baza de date exista ', fileLength:3, ' articol');

IF fileLength = 1 THEN WRITELN ('.') ELSE WRITELN ('e.');

currentSelection := adaugare; HighLightSelection

END;

FUNCTION SearchIndex(targetName: nameString): INTEGER;

(* -------- ----- ------ ----- ----- ----------- *)

(* Functia utilizeaza un algoritm de cautare binara a *)

(* numelui clientului in tabela index. Daca numele este *)

(* in tabela, functia furnizeaza numarul articolului *)

(* corespunzator in baza de date. Altfeì functia da -1. *)

(* -------- ----- ------ ----- ----- ----------- *)

VAR

found, notThere: BOOLEAN;

first, last, midPoint, targetRecord: INTEGER;

BEGIN

found:= FALSE; notThere:= FALSE; first:= 1;

last:= fileLength; targetRecord:= -1;

REPEAT

midPoint := (first + last) DIV 2;

WITH index[midPoint] DO

BEGIN

IF clientName = targetName THEN

BEGIN found := TRUE; targetRecord := recordNumber END

ELSE

BEGIN

IF clientName < targetName THEN first := midPoint + 1

ELSE last := midPoint - 1

END

END; notThere := (last < first)

UNTIL (found OR notThere);

SearchIndex := targetRecord

END;

PROCEDURE SortIndex(sortLength: BYTE);

(* -------- ----- ------ ----- ----- -------------- *)

(* Procedura foloseste algoritmul de sortare Shell pentru *)

(* a ordona tabloul index dupa cimpul clientName. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

listJump, i, j: BYTE;

sortComplete: BOOLEAN;

saveRecord: indexRecord;

BEGIN

listJump := 1;

WHILE listJump <= sortLength DÏ listJump := listJump + 2;

WHILE listJump > 1 DO

BEGIN

listJump := (listJump -1) DIV 2;

REPEAT

sortComplete := TRUE;

FOR j := 1 TO sortLength - listJump DO

BEGIN

i := j + listJump;

IF index[j].clientName > index[i].clientName THEN

BEGIN

saveRecord := index[j]; index[j] := index[i];

index[i] := saveRecord; sortComplete := FALSE

END

END

UNTIL sortComplete

END

END;

PROCEDURE AddClient;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura dirijeaza dialogul pentru introducerea *)

(* datelor unui nou client. Daca utilizatorul confirma, *)

(* atunci articolul se adauga la sfirsitul bazei de date. *)

(* -------- ----- ------ ----- ----- ----------- *)

VAR

searchName: nameString;

okRecord: BOOLEAN;

answer: CHAR;

BEGIN

WRITELN ('Adaugarea datelor pentru un nou client');

WRITELN ('--------- ------- ------ -- --- ------'); WRITELN;

WITH profile DO

BEGIN

WRITE('Numele clientului : '); READLN (name);

searchName := LeftAlign (UpperCase (name), 30);

IF searchIndex (searchName) >= 0 THEN

BEGIN WRITELN; WRITELN ('Clientul deja este in baza de date'(c) END

ELSE

BEGIN

refNo := InByte('Numarul de referinta : ');

WRITE('Tipul afacerii : '); READLN(businessType);

WRITE('Persoana contactata : '); READLN(contactPerson);

WRITE('Numarul de telefon : '); READLN(phoneNumber);

hoursLastYear :=

InReal('Totalul orelor contabilizate in ultimul an : ');

recordDate := DateString; WRITELN; WRITELN;

answer := InChar('Salvati acest articol ? ', ['D', 'N']);

okRecord := (answer = 'D'); WRITELN (answer);

IF okRecord THEN

BEGIN

SEEK(profileFile, fileLength);

INC(fileLength);

WRITELN('Se salveaza articolul #',fileLength:3);

WRITE(profileFile, profile);

WITH index[fileLength] DO

BEGIN

clientName := searchName;

recordNumber := fileLength -1

END;

SortIndex(fileLength)

END

ELSE

WRITELN('S-a abandonat introducerea acestui articol ...')

END

END

END;

PROCEDURE GetClient (VAR wichRecord: INTEGER);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura este apelata de rutinele DisplayClient si *)

(* ReviseClient. Ea solicita un nume, cauta numele in *)

(* indexul bazei de date, citeste articolul respectiv din *)

(* baza de date si afiseaza articolul pe ecran. GetClient *)

(* furnizeaza numarul articolului citit (wichRecord). *)

(* -------- ----- ------ ----- ----- ------------ *)

VAR

inName: nameString;

BEGIN

WRITE('Numele clientului : '); READLN(inName);

inName := LeftAlign(UpperCase(inName), 30);

wichRecord := SearchIndex(inName);

IF wichRecord >= 0 THEN

BEGIN

SEEK (profileFile, wichRecord);

READ (profileFile, profile);

CLRSCR; WRITELN; WRITELN;

WITH profile DO

BEGIN

WRITELN(name);

WRITELN(StringOfChars('-', LENGTH(name)));

WRITELN('Numarul de referinta: ', refNo);

WRITELN('Tipul afacerii: ', businessType);

WRITELN('Data articolului: ', recordDate);

WRITELN('Persoana contactata: ', contactPerson);

WRITELN('Numarul de telefon: ', phoneNumber);

WRITELN('Ore lucrate in ultimul an: ', hoursLastYear:7:2)

END

END

ELSE

BEGIN

WRITELN; WRITELN; WRITELN('Articolul nu este in baza de date.'); WRITELN

END

END;

PROCEDURE DisplayClient;

(* ---- Afisarea unue articoì pe ecran ---- *)

VAR

location: INTEGER;

BEGIN

WRITELN('Afisarea informatiilor despre un client.');

WRITELN('-------- ------------- ------ -- -------'); WRITELN;

GetClient (location)

END;

PROCEDURE ReviseClient;

(* -------- ----- ------ ----- ----- -------------- *)

(* Procedura dirijeaza utilizatorul in modificarea datelor *)

(* unui client. Daca utilizatorul confirma, rutina rescrie *)

(* articolul modificat in baza de date, PROFILE.DAT. *)

(* -------- ----- ------ ----- ----- -------------- *)

TYPE

changeType = (contact, phone, hours);

changeRange = contact..hours;

promptString = RECORD

question, inPrompt: STRING

END;

CONST

prompts : ARRAY[changeRange] OF promptString =

((question: 'Schimbati persoana contactata ? ';

inPrompt:'Noua persoana contactata : '),

(question: 'Schimbati numarul de telefon ? ';

inPrompt: 'Noul numar de telefon : '),

(question: 'Schimbati orele contabilizate in ultimul an ? ';

inPrompt: 'Noua valoare a orelor contabilizate : '));

VAR

currentChange: changeType;

location: INTEGER;

changed: BOOLEAN;

BEGIN

WRITELN('Modificarea datelor unui client.');

WRITELN('----------- ------- ---- -------'); WRITELN;

GetClient(location); changed := FALSE;

IF location >= 0 THEN

BEGIN

WRITELN;

FOR currentChange := contact TO hours DO

BEGIN

WITH prompts[currentChange] DO

IF InChar(question, ['D', 'N']) = 'D' THEN

BEGIN

WRITELN('Da');

WRITE(inPrompt);

WITH profile DO

CASE currentChange OF

contact: READLN(contactPerson);

phone: READLN(phoneNumber);

hours: hoursLastYear := InReal('')

END;

changed := TRUE

END

ELSE WRITELN('Nu')

END;

IF changed THEN

BEGIN

WRITELN;

IF InChar('Salvati articolul modificat ? ', ['D', 'N']) = 'D' THEN

BEGIN

WRITELN('Da'); WRITELN('Salvarea articolului modificat ...');

profile.recordDate := DateString;

SEEK(profileFile, location); WRITE(profileFile, profile)

END

ELSE

BEGIN

WRITELN('Nu'); WRITELN('Abandonarea modificarilor ...')

END

END

END

END;

PROCEDURE GetSelection (VAR quitSignal: BOOLEAN);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura accepta o selectia de meniu de la tastatura *)

(* si apeleaza rutinele corespunzatoare. *)

(* -------- ----- ------ ----- ----- ------------ *)

CONST

options:ARRAY[1..4] OF activities=(adaugare, listare, modificare, iesire);

firstChars = 'ALMI';

VAR

inChar: CHAR;

PROCEDURE Continue;

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura indica utilizatorului sa apese bara spatiu *)

(* pentru a reveni in meniu la terminarea unei activitati. *)

(* -------- ----- ------ ----- ----- ------------ *)

VAR

inSpace: CHAR;

BEGIN

GOTOXY(10, 23); WRITE('Apasati bara spatiu pentru revenire in meniu ...');

REPEAT inSpace := READKEY UNTIL inSpace = ' '

END;

PROCEDURE RemoveHighLight;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura restaureaza optiunea de meniu deselectata *)

(* pentru a fi afisata normal. *)

(* -------- ----- ------ ----- ----- ---------- *)

BEGIN

WITH activity[currentSelection] DO

BEGIN GOTOXY(column, row); WRITELN(menuString) END

END;

PROCEDURE SelectionNextActivity;

(* -------- ----- ------ ----- ----- --------- *)

(* Procedura marcheaza luminos urmatoarea optiune din *)

(* meniu, raspunzind tastei sageata sus. *)

(* -------- ----- ------ ----- ----- --------- *)

BEGIN

RemoveHighLight;

IF currentSelection = iesire THEN currentSelection := adaugare

ELSE currentSelection := SUCC(currentSelection);

HighLightSelection

END;

PROCEDURE SelectionPreviousActivity;

(* -------- ----- ------ ----- ----- ------- *)

(* Procedura marcheaza luminos optiunea anterioara, *)

(* raspunzind tastei sageata jos. *)

(* -------- ----- ------ ----- ----- ------- *)

BEGIN

RemoveHighLight;

IF currentSelection = adaugare THEN currentSelection := iesire

ELSE currentSelection := PRED(currentSelection);

HighLightSelection

END;

BEGIN

quitSignal := FALSE;

REPEAT

inChar :=UPCASE(READKEY);

IF NOT (inChar IN menuChars) THEN WRITE(bell)

UNTIL (inChar IN menuChars);

CASE inChar OF

'A', 'L', 'M', 'I':

BEGIN

RemoveHighLight;

currentSelection := options[POS(inChar, firstChars)];

HighLightSelection

END;

nullChar:

BEGIN

inChar := READKEY;

IF inChar IN cursorScanCode THEN

CASE inChar OF

upArrow, leftArrow: SelectionPreviousActivity;

downArrow, rightArrow: SelectionNextActivity

END

ELSE

WRITE (bell)

END;

enter:

BEGIN

IF currentSelection = iesire THEN quitSignal := TRUE

ELSE

BEGIN

CLRSCR;

CASE currentSelection OF

adaugare: BEGIN AddClient; Continue END;

listare:

IF fileLength > 0 THEN BEGIN DisplayClient; Continue END;

modificare:

IF fileLength > 0 THEN BEGIN ReviseClient; Continue END

END;

CLRSCR; InitializeMenu

END

END

END

END;

PROCEDURE OpenFiles (VAR filesOk: BOOLEAN);

(* -------- ----- ------ ----- ----- ------------- *)

(* Procedura deschide fisierul bazei de date si fisierul *)

(* index. Procedura retransmite valoarea booleana filesOk. *)

(* Valoarea rezultatului este fals daca baza de date exista *)

(* dar indexul nu poate fi localizat. In acest caz versiunea*)

(* curenta a programului nu poate continua. *)

(* -------- ----- ------ ----- ----- ------------- *)

VAR

i: INTEGER;

BEGIN

ASSIGN(profileFile, profileDone);

ASSIGN(indexFile, indexFileName); filesOk := TRUE;

{$I-ý RESET (profileFile);

IF IORESULT <> 0 THEN REWRITE(profileFile);

fileLength := FILESIZE(profileFile);

IF fileLength > 0 THEN

BEGIN

RESET(indexFile);

IF IORESULT = 0 THEN

BEGIN

FOR i :=1 TO fileLength DO

WITH index[i] DO READLN(indexFile, clientName, recordNumber);

CLOSE (indexFile)

END

ELSE

BEGIN

filesOk := FALSE;

WRITELN('PROFILE.DAT exista, dar PROFILE.NDX nu exista.');

WRITELN('... Nu pot continua.');

CLOSE(profileFile)

END

END

END;

PROCEDURE SaveIndex;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura salveaza tabloul index intr-un fisier pe *)

(* disc, numit fisier index, la terminarea programului. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

i: INTEGER;

BEGIN

REWRITE(indexFile);

FOR i := 1 TO fileLength DO

WITH index[i] DO WRITELN(indexFile, clientName, recordNumber);

CLOSE (indexFile)

END;

BEGIN

CLRSCR;

OpenFiles (ready);

IF ready THEN

BEGIN

InitializeMenu;

REPEAT

GetSelection(done)

UNTIL done;

CLRSCR;

CLOSE(profileFile);

IF fileLength > 0 THEN SaveIndex

END

END.

GraphDemo

(* >>> GRPHDEMO.PAS <<<----- ----- --------- ----- -----*)

(* Programul demonstreaza citeva din facilitatile *)

(* grafice posibile prin apelarea rutinelor din *)

(* unit-ul GRAPH intr-un program TURBO PASCAL 5.5 *)

(*-------- ----- ------ ----- ----- -------*)

PROGRAM GraphDemo;

USES CRT,GRAPH;

VAR

driverVar, modeVar: INTEGER;

PROCEDURE GraphTitle (inTitle: STRING);

(* -------- ----- ------ ----- ----- -------------- *)

(* Procedura scrie un titlu cu caractere SPECIALE, centrat *)

(* la partea superioara a ecranului. *)

(* -------- ----- ------ ----- ----- -------------- *)

BEGIN

SETTEXTJUSTIFY(CENTERTEXT, TOPTEXT);

SETTEXTSTYLE(TRIPLEXFONT, HORIZDIR, 4);

OUTTEXTXY GETMAXX DIV 2, 1, inTitle)

END;

PROCEDURE GraphContinue;

(* -------- ----- ------ ----- ----- --------- *)

(* Procedura scrie un mesaj la partea inferioara a *)

(* ecranului si asteapta pina la apasarea barei spatiu. *)

(* -------- ----- ------ ----- ----- --------- *)

CONST mesaj =' Tastati spatiu pentru continuare ...';

VAR inKey: CHAR;

BEGIN

SETTEXTJUSTIFY(CENTERTEXT, TOPTEXT);

SETTEXTSTYLE GOTHICFONT, HORIZDIR, 3);

OUTTEXTXY(GETMAXX DIV 2, GETMAXY - 40, mesaj);

REPEAT inKey := READKEY UNTIL inKey = ' ';

CLEARDEVICE

END;

PROCEDURE DrawSine;

(* -------- ----- ------ ----- ----- ------ *)

(* Procedura traseaza o sinusoida folosind functia *)

(* standard PUTPIXEL. *)

(* -------- ----- ------ ----- ----- ------ *)

CONST

maxLength= 200; maxHeight= 40;

VAR

centerX, centerY, startX, endX, i, plotHeight: INTEGER;

angle: REAL;

BEGIN

GraphTitle('Trasare sinusoida');

centerX := GETMAXX DIV 2; centerY := GETMAXY DIV 2;

startX := centerX - maxLength; endX := centerX + maxLength;

FOR i := startX TO endX DO

BEGIN

angle := ((i - centerX) / (maxLength / 2)) * PI;

plotHeight := centerY - TRUNC (maxHeight * SIN (angle));

PUTPIXEL(i, plotHeight, 1)

END;

LINE(startX - 10, centerY, endX +10, centerY);

LINE(centerX, centerY - maxHeight, centerX, centerY + maxHeight);

GraphContinue

END;

PROCEDURE DrawCircles;

(* ---- Desenare cercure cõ rutina CIRCLE ----- *)

VAR

Orientare, raza: INTEGER;

InitColor, color: WORD;

BEGIN

GraphTitle('Trasare cercuri');

initColor := GETCOLOR; color:=red;

FOR Orientare := -1 to 1 DO

BEGIN

SETCOLOR(color);

FOR raza := 1 TO 4 DO

CIRCLE(GETMAXX DIV 2 + orientare * 100, GETMAXY DIV 2,

raza * 30 + ABS (orientare) * 20);

color := SUCC(color)

END;

SETCOLOR(initColor);

GraphContinue

END;

PROCEDURE DrawPie;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura traseaza un grafic cu sectoare circulare, *)

(* numite ;pie chart;, ilustrind lucrul cu rutinele *)

(* PIESLICE si SETFILLSTYLE. *)

(* -------- ----- ------ ----- ----- ---------- *)

CONST

articole = 5;

simpleDate : ARRAY[1..ARTICOLE] OF REAL 1/2 (7.5, 3.0, 4.5, 9.0, 6.0);

VAR

i, portiune, startUnghi, endUnghi: WORD;

total: REAL;

BEGIN

GraphTitle('Statistica de suprafata'); total := 0.0;

FOR i := 1 TO articole DÏ total := total + simpleDate[i]; startUnghi := 0;

FOR i := 1 TO articole DO

BEGIN

portiune := trunc (360.0 * (simpleDate[i] / total));

IF i = articole THEN endUnghi := 359

ELSE endUnghi := startUnghi + portiune;

SETFILLSTYLE(5 + i, 2);

PIESLICE(GETMAXX DIV 2, GETMAXY DIV 2,

startUnghi, endUnghi, 150); startUnghi := endUnghi

END;

GraphContinue

END;

PROCEDURE DrawBars;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura traseaza un grafic cu paralelipipede, *)

(* ilustrind lucrul cu rutinele BAR3D si SETFILLSTYLE. *)

(* -------- ----- ------ ----- ----- ---------- *)

CONST

articole = 9;

simpleDate : ARRAY [1..articole, 1..2] OF BYTE 1/2

((19,10),(25,25),(37,10),(16,5)¬ (18,25),(35,43),(43,58),(32,55),(43,32));

VAR

x1, x2, y1, y2, y3, depth: INTEGER;

i: BYTE;

BEGIN

GraphTitle (§ Desenare paralelipipede '); x1 := 50; depth := 9;

FOR i := 1 TO articole DO

BEGIN

y1 := GETMAXY - 50; y2 := y1 - simpleDate[i,1];

y3 := y2 - simpleDate[i,2];

INC(x1, 50); x2 := x1 + 36;

SETFILLSTYLE(6,2); BAR3D(x1, y1, x2, y2, depth, FALSE);

SETFILLSTYLE(7,2); BAR3D(x1, y2, x2, y3, depth, TRUE)

END; GraphContinue

END;

PROCEDURE DrawShapes;

(* -------- ----- ------ ----- ----- ----------- *)

(* Procedura traseaza un dreptunghi, o elipsa si un *)

(* un trunghi ilustrind utilizarea procedurilor RECTANGLE,*)

(* ELLIPSE si DRAWPOLY. *)

(* -------- ----- ------ ----- ----- ----------- *)

CONST

poliPct : ARRAY [1..8] OF WORD 1/2 (200, 60, 50, 140, 250, 140, 200, 60);

VAR color: WORD;

BEGIN

GraphTitle('Diferite forme geometrice'); color := GETCOLOR;

SETCOLOR(2); RECTANGLE(30, 50, GETMAXX - 30, 350);

SETCOLOR(3); ELLIPSE(GETMAXX DIV 2 + 100, GETMAXY DIV 2, 0, 359, 100, 20);

SETCOLOR(4); DRAWPOLY (4, poliPct); SETCOLOR(14); CIRCLE(130, 200, 50);

SETCOLOR(color); GraphContinue

END;

BEGIN

driverVar := 0; INITGRAPH (driverVar, modeVar, ''); DrawSine;

DrawCircles; DrawPie; DrawBars; DrawShapes; CLOSEGRAPH

END.

Capitolul 14

LateCli

(* >>> LateCli <<< ----- ----- --------- ----- ---- *)

(* Nume fisier : LATECLI.PAS *)

(* Programul tipareste instiintari pentru *)

(* creditorii rau platnici. *)

(* -------- ----- ------ ----------- *)

PROGRAM LateCli;

USES CRT, PRINTER, InUnit, StrUnit, ChrnUnit;

CONST

company= 'Custom Solutions, Inc.';

formFeed= #12;

VAR

clientName: STRING;

invoiceDate: LONGINT;

invoiceAmount: REAL;

PROCEDURE InData;

(ª -------- ----- ------ ----- ----- ----- *)

(* Procedura extrage de la utilizator urmatoarele *)

(* informatii : numele clientului, data facturarii *)

(* si suma facturata. *)

(* -------- ----- ------ ----- ----- ----- *)

BEGIN

WriteLn('Tiparirea instiintarii pentru rau platnici');

WriteLn('--------- ------------ ------ --- --------'); WriteLn;

Write('Numele clientului : '); ReadLn(clientName);

invoiceDate := InDate('Data facturarii : ');

invoiceAmount := InReal('Suma facturata : '); WriteLn; WriteLn

END;

PROCEDURE Heading;

(ª ----- Tipareste partea comuna a instiintariloò ----- *)

BEGIN

WriteLn(LST);

WriteLn(LST, RightJustify ('Instiintare pentru intirzierea platilor', 30));

WriteLn(LST, RightJustify ('=========== ====== =========== ========', 30));

WriteLn(LST);WriteLn(LST, LeftAlign('Data instiintarii: ', 22), DateString);

WriteLn(LST); WriteLn (LST, LeftAlign('Catre: ', 22), clientName);

WriteLn(LST, LeftAlign('De la: ', 22), company); WriteLn (LST);

WriteLn(LST,LeftAlign('Data facturarii: ',22),ScalarToString(invoiceDate));

WriteLn(LST, LeftAlign('Suma facturata: ', 22),

DollarDisplay(ROUND(invoiceAmount * 100), 9));

WriteLn(LST, LeftAlign('Termen: ', 22), 'Plata completa in 30 zile.');

WriteLn; WriteLn;

END;

PROCEDURE Warning(daysOld: LONGINT);

(* -------- ----- ------ ----- ----- -------- *)

(* Rutina tipareste un mesaj de atentionare pentru *)

(* facturile al caror termen este depasit cu cel mult *)

(* 30 de zile. *)

(* -------- ----- ------ ----- ----- -------- *)

CONST

message: ARRAY[1..5] OF STRING =

('Plata pentru aceasta factura este intirziata cu ',

'zile. Pentru a evita orice intirziere in lucru la',

'proiectul dv., noi vom aprecia promptitudinea dv.',

'in aceasta problema. Daca nu primim suma pina la :',

'sintem obligati sa oprim lucru la proiectul dv.');

VAR

i: BYTE;

BEGIN

Heading; WriteLn(LST, message[1], daysOld - 30);

FOR i := 2 TO 4 DO WriteLn(LST, message[i]);

WriteLn(LST); WriteLn(LST, Spaces(10), ScalarToString(TodaysDate + 14));

WriteLn(LST); WriteLn(LST, message[5]); WriteLn(LST, formFeed)

END;

PROCEDURE Serious(daysOld: LONGINT);

(* -------- ----- ------ ----- ----- -------- *)

(* Rutina tipareste o instiintare in termeni mult mai *)

(* drastici la intirzierea platii cu peste 30 zile. *)

(* -------- ----- ------ ----- ----- -------- *)

CONST

message : ARRAY[1..4] OF STRING =

('Intirzierea pentru aceasta factura este de ',

'zile. Lucrul la proiectul dv. va fi oprit',

'imediat. Daca nu achitati factura pina la ',

'sintem obligati sa va actionam pe alte cai.');

VAR

i: BYTE;

BEGIN

Heading; WriteLn(LST, message[1], daysOld - 30);

FOR i := 2 TO 3 DÏ WriteLn (LST, message[i]);

WriteLn(LST); WriteLn(LST, Spaces(10), ScalarToString(TodaysDate + 7));

WriteLn(LST); WriteLn(LST, message[4]); WriteLn(LST, formFeed);

END;

PROCEDURE TakeAction;

(* -------- ----- ------ ----- ----- --------- *)

(* Rutina examineaza vechimea facturii si decide daca *)

(* se va tipari sau nu o instiintare. *)

(* -------- ----- ------ ----- ----- --------- *)

VAR

age: LONGINT;

FUNCTION Continue: BOOLEAN;

(* -------- ----- ------ ----- ----- -------- *)

(* Functia accepta un semnal de la utilizator pentru *)

(* a cunoaste daca imprimanta este pregatita pentru *)

(* listare sau <ESC> pentru revenire in meniu. *)

(* -------- ----- ------ ----- ----- -------- *)

CONST

spaceBar= ' ';

escKey= #27;

prompt= '<Bara spatiu> pentru tiparire. <Escape> pentru terminare.';

VAR

inKey: CHAR;

BEGIN

inKey := InChar (prompt, [spaceBar, escKey]);

Continue := (inkey = spaceBar)

END;

BEGIN

age := TodaysDate - invoiceDate;

IF age < 60 THEN

BEGIN

WriteLn('*** Nu este necesara tiparirea instiintarii.');

WriteLn(' Factura are o vechime de ', age, ' zile.')

END

ELSE

IF Continue THEN

IF age > 90 THEN

Serious (age)

ELSE

Warning (age)

END;

BEGIN

ClrScr;

InData;

TakeAction

END.

Capitolul 15

ShowOff

(* >>> ShowOff <<< -------- ----- ------ -- *)

(* Nume fisier : SHOWOFF.PAS *)

(* Programul este destinat demonstrarii modului de *)

(* lucru al algoritmului "quick sort" pentru ordonarea *)

(* unei liste de date de tip sir generate aleator. *)

(* -------- ----- ------ ----- ----- -------- *)

PROGRAM ShowOff;

USES CRT, RandUnit;

CONST

listLength= 200;

TYPE

arrayType= ARRAY[1..listLength] OF STRING[7];

VAR

nameList: arrayType;

continue: STRING;

PROCEDURE PrintList;

(* -------- ----- ------ ----- ----- -------- *)

(* Rutina afiseaza tabelul cu cele 200 de siruri *)

(* generate aleator, atit inainte cit si dupa sortare. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

i, j: BYTE;

BEGIN

FOR i := 1 TO 20 DO

FOR j := 1 TO 10 DO

Write(nameList[(j -1) * 20 + i], ' ')

END;

PROCEDURE FillList;

(* -------- ----- ------ ----- ----- ---------- *)

(* Procedura asigura generarea aleatoare a sirurilor *)

(* tabelului, folosind functia RandStr din RandUnit. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

i: BYTE;

BEGIN

FOR i := 1 TO listLength DO

nameList[i] := RandStr (7)

END;

PROCEDURE QuickSort(VAR stringList:arrayType; firstElement,lastElement:INTEGER);

(* -------- ----- ------ ----- ----- ------------ *)

(* Procedura reprezinta algoritmul recursiv de sortare. *)

(* Ea apeleaza in mod repetat rutina locala DivideList *)

(* pentru separarea listei de sortare in doua parti. *)

(* Dupa fiecare apel la DivideList, rutina QuickSort se *)

(* apeleaza pe sine insasi pentru a sorta cele doua parti *)

(* ale listei. *)

(* -------- ----- ------ ----- ----- ------------ *)

VAR newFirst, newLast: INTEGER;

PROCEDURE DivideList(VAR workList: arrayType;

VAR begin1, final1, begin2, final2: INTEGER);

(* -------- ----- ------ ----- ----- -------------- *)

(* Rutina imparte portiune curenta a listei in doua parti *)

(* si schimba intre ele perechile de elemente atunci cind *)

(* acestea nu sint in ordinea corespunzatoare. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

referince, tempStr: STRING[7];

BEGIN

referince := workList[(begin2 + final2) DIV 2];

begin1 := begin2;

final1 := final2;

WHILE begin1 < final1 DO

BEGIN

WHILE workList[begin1] < referince DO

INC(begin1);

WHILE referince < workList[final1] DO

DEC(final1);

IF begin1 <= final1 THEN

BEGIN

tempStr := workList[begin1];

workList[begin1] := workList[final1];

workList[final1] := tempStr;

INC (begin1); DEC (final1)

END

END

END;

BEGIN

IF firstElement < lastElement THEN

BEGIN

DivideList(stringList, newFirst, newLast, firstElement, lastElement);

QuickSort(stringList, firstElement, newLast);

QuickSort(stringList, newFirst, lastElement)

END

END;

BEGIN

RANDOMIZE;

ClrScr; WriteLn(' Lista nesortata :'); WriteLn;

FillList;

PrintList;

QuickSort(nameList, 1, listLength);

WriteLn; Write('Tastati <Enter> pentru afisarea listei sortate.');

Readln(continue);

ClrScr; WriteLn(' Lista sortata :'); WriteLn;

PrintList; WriteLn; ReadLn

END.

Unit-uri

ChrnUnit

(* >>> ChrnUnit <<< -------- ----- ------ - *)

(* Nume fisier : CHRNUNIT.PAS *)

(* Unit-ul ChrnUnit contine o colectie de rutine care *)

(* asigura prelucrare completa a datei si timpului. *)

(* -------- ----- ------ ----- ----- -------- *)

UNIT ChrnUnit;

INTERFACE

USES DOS, CRT;

FUNCTION ChronString(year, month, day, weekDay: WORD): STRING;

FUNCTION DateString: STRING;

FUNCTION TimeString: STRING;

FUNCTION DaysInMonth (month, year: WORD): BYTE;

FUNCTION DaysInYear(year: WORD): WORD;

FUNCTION ScalarDate(month, day, year: WORD): LONGINT;

FUNCTION InDate(prompt: STRING): LONGINT;

FUNCTION TodaysDate: LONGINT;

FUNCTION DayOfWeek(scDate: LONGINT): BYTE;

FUNCTION ScalarToString(scDate: LONGINT): STRING;

IMPLEMENTATION

FUNCTION ChronString (year, month, day, weekDay: WORD): STRING;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia converteste cele patru valori numerice *)

(* transmise ca parametri intr-un sir de forma : *)

(* 'Ziua,ll. zz. aaaa'. *)

(* -------- ----- ------ ----- ----- ----- *)

CONST

days:ARRAY[0..6] OF STRING[3]=('Dum','Lun','Mrt','Mrc','Joi','Vin','Smb');

months: ARRAY[1..12] OF STRING[3] = ('Ian','Feb','Mar','Apr','Mai','Iun',

'Iul','Aug','Sep','Oct','Nov','Dec');

VAR

yearStr, monthStr, dayStr, weekdayStr: STRING;

BEGIN

STR(year, yearStr); STR(day, dayStr);

IF LENGTH(dayStr) = 1 THEN dayStr := ' ' + dayStr;

weekdayStr := days[weekday] + '.,'; monthStr := months[month] + '. ';

ChronString := weekdayStr + monthStr ; dayStr + ', ' + yearStr

END;

FUNCTION DateString;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia converteste valorile numerice furnizate *)

(* de procedura interna GETDATE intr-un sir, de *)

(* forma : 'Ziua,ll. zz. aaaa'. *)

(* -------- ----- ------ ----- ----- ----- *)

VAR

year, month, day, weekday: WORD;

BEGIN

GETDATE(year, month, day, weekday);

DateString := ChronString (year, month, day, weekDay)

END;

FUNCTION TimeString;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia converteste valorile numerice furnizate *)

(* procedura interna GETTIME intr-un sir de forma : *)

(* 'hh.mm am/pm'. *)

(* -------- ----- ------ ----- ----- ----- *)

VAR

hour, minute, second, hundredth: WORD;

ampm: STRING[2];

hourStr, minuteStr: STRING;

BEGIN

GETTIME(hour, minute, second, hundredth);

IF hour > 11 THEN

BEGIN

ampm := 'pm';

IF hour > 12 THEN DEC(hour, 12)

END

ELSE

BEGIN

ampm := 'am';

IF hour = 0 THEN hour := 12

END;

STR(hour, hourStr); STR (minute, minuteStr);

IF LENGTH (hourStr) = 1 THEN hourStr := ' ' + hourStr;

IF LENGTH (minuteStr) = 1 THEN minuteStr := '0' + minuteStr;

TimeString := hourStr + ':' + minuteStr + ' ' + ampm

END;

FUNCTION DaysInMonth(month, year: WORD): BYTE;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia furnizeaza numarul de zile ale unei luni *)

(* -------- ----- ------ ----- ----- ------ *)

VAR temp: BYTE;

BEGIN

CASE month OF

1, 3, 5, 7, 8, 10, 12 : temp := 31;

4, 6, 9, 11 : temp := 30;

2 : IF (year MOD 4) = 0 THEN temp := 2¹ ELSE temp := 28

END;

DaysInMonth := temp

END;

FUNCTION DaysInYear (year: WORD): WORD;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia furnizeaza numarul de zile ale unei an *)

(* -------- ----- ------ ----- ----- ----- *)

VAR temp: WORD;

BEGIN

IF (Year MOD 4) = 0 THEN temp := 364

ELSE temp := 365;

DaysInYear := temp

END;

FUNCTION ScalarDate(month, day, year: WORD): LONGINT;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia returneaza scalarul echivalent datei *)

(* calendaristice receptionata. In acest sistem data *)

(* 01.01.1901 este ziua 1, iar ultima data corecta *)

(* este 31.12.1999, care este ziua 36139. *)

(* -------- ----- ------ ----- ----- ------ *)

VAR

temp: LONGINT;

i: BYTE;

BEGIN

temp := 0;

FOR i := 1 to (year - 1) DO INC(temp, DaysInYear (i));

FOR i := 1 TO (month - 1) DO INC(temp, DaysInMonth (i, year));

INC (temp, day);

ScalarDate := temp

END;

FUNCTION InDate (prompt: STRING): LONGINT;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia citeste de la tastatura o data corecta *)

(* in format LL ZZ AA. Functia accepta ca separatori*)

(* caracterele '/', '-', '.' si ' ' intre elementele*)

(* unei date calendaristice. *)

(* -------- ----- ------ ----- ----- ----- *)

CONST

numChars = 4;

divisionChars : ARRAY[1..numChars] OF CHAR = ('/', '-', '.', ' ');

VAR

xSave, ySave, charIndex, firstDiv, secondDiv: BYTE;

month, day, year, monthCode, dayCode, yearCode: WORD;

inDateString, monthStr, dayStr, yearStr: STRING;

good: BOOLEAN;

targetChar: CHAR;

FUNCTION Pos2 (inChar: CHAR; inStr: STRING): BYTE;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia cauta a doua pozitie a caracterului *)

(* inChar in sirul inStr. *)

(* -------- ----- ------ ----- ----- ----- *)

VAR

firstPos, secondPos: BYTE;

secondString: STRING;

BEGIN

firstPos := POS (inChar, inStr);

secondString := COPY(inStr, firstPos + 1, LENGTH(inStr) - firstPos);

secondPos := POS (inChar, secondString) + firstPos; Pos2 := secondPos

END;

BEGIN

REPEAT

Write (prompt); xSave := WhereX; ySave := WhereY; ReadLn (inDateString);

charIndex := 1;

REPEAT

targetChar := divisionChars[charIndex];

firstDiv := POS(targetChar, inDateString);

secondDiv := Pos2(targetChar, inDateString);

good := (firstDiv > 0) AND (secondDiv > 0);

IF (NOT good) THEN INC(charIndex)

UNTIL good OR (charIndex > numChars);

IF good THEN

BEGIN

monthStr := COPY(inDateString, 1, firstDiv - 1);

dayStr := COPY(inDateString, firstDiv + 1, secondDiv - firstDiv + 1);

yearStr := COPY(inDateString, secondDiv + 1,

LENGTH(inDateString) - secondDiv);

VAL(monthStr, month, monthCode);

VAL(dayStr, day, dayCode); VAL(yearStr, year, yearCode);

IF (monthCode + dayCode + yearCode = 0) THEN

BEGIN

IF year > 99 THEN year := year MOD 100;

good := (1 <= month) AND (month <= 12);

good := good AND (year > 0);

good := good AND (day <= DaysInMonth(month, year))

END

ELSE

good := FALSE

END;

IF NOT good THEN

BEGIN GoToXY(xSave, ySave); ClrEoì END

UNTIL good;

InDate:= ScalarDate(month, day, year)

END;

FUNCTION TodaysDate: LONGINT;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia furnizeaza echivalentul scalar al datei *)

(* curente din calendarul sistemului. *)

(* -------- ----- ------ ----- ----- ----- *)

VAR

year, month, day, weekday: WORD;

BEGIN

GetDate(year, month, day, weekday);

TodaysDate := ScalarDate(month, day, (year MOD 100))

END;

FUNCTION DayOfWeek (scDate: LONGINT): BYTE;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia furnizeaza un intreg cuprins intre 0 si *)

(* 6, reprezentind ziua din saptamina pentru data *)

(* scalara transmisa. 0 reprezinta ziua de Duminica.*)

(* -------- ----- ------ ----- ----- ----- *)

BEGIN

DayOfWeek := ((scDate + 1) MOD 7)

END;

FUNCTION ScalarToString(scDate: LONGINT): STRING;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia converteste o data scalara intr-un sir *)

(* de forma : Ziua., Luna., ZZ, AAAA. *)

(* -------- ----- ------ ----- ----- ----- *)

VAR

remainder: LONGINT;

year, month, day, weekday: WORD;

BEGIN

remainder := scDate;

year := 1;

WHILE (remainder > DaysInYear(year)) DO

BEGIN DEC(remainder, DaysInYear (year)); INC(year) END;

month := 1;

WHILE (remainder > DaysInMonth(month, year)) DO

BEGIN DEC(remainder, DaysInMonth(month, year)); INC(month) END;

day := remainder; weekday := DayOfWeek (scDate);

ScalarToString := ChronString((year + 1900), month, day, weekday)

END;

END.

InUnit

(* >>> InUnit <<< -------- ----- ------ ---- *)

(* Nume fisier : INUNIT.PAS *)

(* Unit-ul contine rutine speciale pentru acceptarea *)

(* si validarea datelor introduse de la tastatura. *)

(* -------- ----- ------ ----- ----- --------- *)

UNIT InUnit;

INTERFACE

USES CRT;

TYPE

validSet = SET OF CHAR;

FUNCTION InReal(prompt: STRING): REAL;

FUNCTION InByte(prompt: STRING): BYTE;

FUNCTION InChar(prompt: STRING; goodChars: validSet): CHAR;

IMPLEMENTATION

FUNCTION InReal(prompt: STRING): REAL;

(* -------- ----- ------ ----- ----- ------------ *)

(* Functia afiseaza pe ecran prompterul de intrare si *)

(* extrage numarul real introdus. Daca introducerea *)

(* utilizatorului nu este corecta - spre exemplu, a tastat *)

(* caractere nenumerice - atunci InReal sterge caracterele *)

(* introduse si continua sa afiseze prompterul de intrare. *)

(* -------- ----- ------ ----- ----- ------------ *)

VAR

trapReal: REAL;

goodInput: BOOLEAN;

saveX, saveY: BYTE;

BEGIN

REPEAT

WRITE(prompt); saveX := WHEREX; saveY := WHEREY;

READLN(trapReal);

goodInput := (IORESULT = 0);

IF NOT goodInput THEN BEGIN GOTOXY(saveX, saveY); ClrEol END;

UNTIL goodInput; InReal := trapReal

END;

FUNCTION InByte(prompt: STRING): BYTE;

(* -------- ----- ------ ----- ----- ------------- *)

(* Functia afiseaza prompterul de intrare si extrage o *)

(* valoare BYTE de la tastatura. Daca introducerea contine *)

(* caractere nenumerice sau nu este in intervalul valorilor *)

(* de tip BYTE se sterge introducerea si continua afisarea *)

(* prompterului de intrare. *)

(* -------- ----- ------ ----- ----- ------------- *)

VAR

trapInteger: INTEGER;

goodInput: BOOLEAN;

saveX, saveY: BYTE;

BEGIN

REPEAT

WRITE (prompt); saveX := WHEREX; saveY := WHEREY;

READLN (trapInteger);

goodInput := (IORESULT=0) AND (trapInteger>=0) AND (trapInteger<=255);

IF NOT goodInput THEN BEGIN GOTOXY(saveX, saveY); CLREOL END

UNTIL goodInput; InByte := trapInteger

END;

FUNCTION InChar(prompt: STRING; goodChars: validSet): CHAR;

(* -------- ----- ------ ----- ----- -------------- *)

(* Functia accepta un singur caracter introdus de la *)

(* tastarura si valideaza introducerea numai daca s-a tastat *)

(* un caracter apartinind multimii stabilite : goodChars. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

trapChar, codeDiscard: CHAR;

BEGIN

WRITE (prompt);

REPEAT

trapChar := UPCASE(READKEY);

IF trapChar = #0 THEN codeDiscard := READKEY

UNTIL trapChar IN goodChars;

InChar := trapChar

END;

END.

StrUnuit

(* >>> StrUnit <<< -------- ----- ------ *)

(* Nume fisier : STRUNIT.PAS *)

(* Unit-ul furnizeaza proceduri si functii pentru *)

(* prelucrarea speciala a sirurilor. *)

(* -------- ----- ------ ----- ----- ------ *)

UNIT StrUnit;

INTERFACE

CONST

maxScreenColumn = 80;

TYPE

screenRange = 1..maxScreenColumn;

screenLine = STRING[maxScreenColumn];

FUNCTION StringOfChars(displayChar: CHAR; lineLength: screenRange): screenLine;

FUNCTION RightJustify(inString: STRING; fieldLength: BYTE): STRING;

FUNCTION DollarDisplay(inAmount: LONGINT; width: BYTE): STRING;

FUNCTION UpperCase(inString: STRING): STRING;

FUNCTION LowerCase(inString: STRING): STRING;

FUNCTION InitialCap(inString: STRING): STRING;

FUNCTION Spaces(inLength: BYTE): STRING;

FUNCTION LeftAlign(inString: STRING; fieldLength: BYTE): STRING;

FUNCTION FirstChar(inString: STRING): CHAR;

FUNCTION Left(inString: STRING; numChars: BYTE): STRING;

FUNCTION Right(inString: STRING; numChars: BYTE): STRING;

IMPLEMENTATION

FUNCTION StringOfChars(displayChar: CHAR; lineLength: screenRange): screenLine;

(* -------- ----- ------ ----- ----- ---- *)

(* Functia construieste un sir cu caracterele *)

(* displayChar; lungimea sirului fiind lineLength. *)

(* -------- ----- ------ ----- ----- ---- *)

VAR

i: screenRange;

trap: screenLine;

BEGIN

trap := '';

FOR i:=1 TO lineLength DO

trap := trap + displayChar;

StringOfChars := trap

END;

FUNCTION RightJustify (inString: STRING; fieldLength: BYTE): STRING;

(* -------- ----- ------ ----- ----- --------- *)

(* Functia returneaza un sir de lungime fieldLength. *)

(* Valoarea inString este aliniata la dreapta in sirul *)

(* rezultat. *)

(* -------- ----- ------ ----- ----- --------- *)

BEGIN

WHILE LENGTH (inString) < fieldLength DO

inString := ' ' + inString;

RightJustify := inString

END;

FUNCTION DollarDisplay (inAmount: LONGINT; width: BYTE): STRING;

(* -------- ----- ------ ----- ----- -------- *)

(* Functia produce un sir de forma dolar-cent din *)

(* valoarea numerica inAmount (un intreg lung care *)

(* reprezinta centii). Sirul rezultat este aliniat la *)

(* dreapta in cimpul de lungime data. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

inString: STRING;

inLength, commaMarker, newPos: BYTE;

BEGIN

STR(inAmount, inString);

WHILE LENGTH(inString) < 3 DO

INSERT('0', inString, 1);

inLength := LENGTH(inString);

newPos := inLength;

commaMarker := 4;

WHILE (newPos > 3) DO

BEGIN

INSERT(',', inString, inLength - commaMarker);

INC(inLength);

INC(commaMarker, 4);

DEC(newPos, 3)

END;

INSERT('.', inString, inLength - 1);

INSERT('$', inString, 1);

DollarDisplay := RightJustify (inString, width)

END;

FUNCTION UpperCase(inString: STRING): STRING;

(* -------- ----- ------ ----- ----- ---- *)

(* Functia returneaza o versiune cu majuscule a *)

(* sirului receptionat ca argument. *)

(* -------- ----- ------ ----- ----- ---- *)

VAR

i: INTEGER;

outString: STRING;

BEGIN

outString := '';

FOR i:=1 TO LENGTH(inString) Do

outString := outString + UPCASE(inString[i]);

UpperCase := outString

END;

FUNCTION LowerCase (inString: STRING): STRING;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia furnizeaza o versiune cu litere mici a *)

(* sirului receptionat ca argument. *)

(* -------- ----- ------ ----- ----- ------ *)

VAR

i: INTEGER;

targetChar, lowerChar: CHAR;

outString: STRING;

upperCaseLetters: SET OF CHAR;

BEGIN

upperCaseLetters := ['A'..'Z'];

outString := '';

FOR i := 1 TO LENGTH(inString) DO

BEGIN

targetChar := inString[i];

IF targetChar IN upperCaseLetters THEN

BEGIN

lowerChar := CHR(ORD(targetChar) + 32);

outString := outString + lowerChar

END

ELSE

outString := outString + targetChar

END;

LowerCase := outString

END;

FUNCTION InitialCap(inString: STRING): STRING;

(* -------- ----- ------ ----- ----- --------- *)

(* Functia transforma in majuscula litera initiala *)

(* a sirului transmis ca argument, iar celelalte litere *)

(* le converteste in litere mici. Foloseste functiile *)

(* UpperCase si LowerCase. *)

(* -------- ----- ------ ----- ----- --------- *)

VAR

firstLetter, remainingLetters: STRING;

BEGIN

firstLetter := UpperCase(inString[1]);

remainingLetters := LowerCase(COPY(inString, 2, LENGTH(inString) - 1));

InitialCap := firstLetter + remainingLetters

END;

FUNCTION Spaces(inLength: BYTE): STRING;

(* -------- ----- ------ ----- ----- -------- *)

(* Functia furnizeaza un sir de inLength blancuri. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

i: BYTE;

trapSpace: STRING;

BEGIN

trapSpace := '';

FOR i := 1 TO inLength DO

trapSpace := trapSpace + ' ';

Spaces := trapSpace

END;

FUNCTION LeftAlign(inString: STRING; fieldLength: BYTE): STRING;

(* -------- ----- ------ ----- ----- -------- *)

(* Functia alinie la stinga argumentul sir inString *)

(* in cimpul de lungime fieldLength. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

spacesToAdd: BYTE;

BEGIN

spacesToAdd := fieldLength - LENGTH(inString);

LeftAlign := inString + Spaces(spacesToAdd)

END;

FUNCTION FirstChar(inString: STRING): CHAR;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia furnizeaza primul caracter al sirului *)

(* receptionat ca argument. *)

(* -------- ----- ------ ----- ----- ------ *)

BEGIN

FirstChar := inString[1]

END;

FUNCTION Left(inString: STRING; numChars: BYTE): STRING;

(* -------- ----- ------ ----- ----- ----- *)

(* Functia furnizeaza primele numChars caractere *)

(* din sirul receptionat ca argument. *)

(* -------- ----- ------ ----- ----- ----- *)

BEGIN

Left := COPY (inString, 1, numChars)

END;

FUNCTION Right (inString: STRING; numChars: BYTE): STRING;

(* -------- ----- ------ ----- ----- ------ *)

(* Functia furnizeaza ultimele numChars caractere *)

(* din sirul receptionat ca argument. *)

(* -------- ----- ------ ----- ----- ------ *)

VAR

index : BYTE;

BEGIN

IF numChars >= LENGTH (inString) THEN

Right := inString

ELSE

BEGIN

index := LENGTH(inString) - numChars +1;

Right := COPY(inString, index, numChars)

END

END;

END.


Document Info


Accesari: 3242
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. 2024 )