Citirea datelor numerice (simple): read, readln

Numai într-o singura privinta este mai simplu sa ne ocupam de input decât de output. Motivul este urmatorul - nu este necesara specificarea formatelor din moment ce input-ul este preparat sub "forma libera". Astfel, datele numerice pot fi plasate oriunde în fisierul de input, fara a fi nevoie de a ne referi la pozitiile particulare. Valorile (numerice) din cadrul aceleiasi linii (de input) trebuie sa fie separate prin unul sau mai multe spatii libere.

Tools-urile (uneltele) pentru procesarea datelor în fisierul text de input sunt:

Diagramele de sintaxa pentru enunturile read si readln sunt prezentate mai jos.

Diagramele de sintaxa ale enunturilor read si readln

Observati ca readln este similar cu writeln în ceea ce priveste lista optionala de parametri. Dar read, ca si write trebuie sa aiba cel putin o variabila de prelucrat. Pentru write, aceasta entitate poate fi si o expresie; pentru read si readln ea trebuie sa fie o variabila.

Remarca:

Formal "identificator variabila" este mai putin complexa decât o expresie, dar nu este atât de restrictiva ca "identificator".

Conventie. Pentru a usura conversatia despre datele de intrare, vom conveni sa folosim W pentru a reprezenta un spatiu (blanc) si <CR> pentru end - of - line. În plus, vom folosi "^" pentru urmatorul caracter necitit si "eof" pentru a marca pozitia end - of - file, dincolo de ultimul caracter citibil al unei secvente de caractere de intrare.

În continuare, ne propunem sa citim (numerele) din urmatoarele doua linii de intrare:

Exemplu:
254W-13WWW4.87W59<CR>
WW18.7W94<CR>

Dupa cum observati, valorile de introdus sunt întregi si reale - patru valori în prima linie si doua în cea de-a doua linie. Pentru a citi aceste valori trebuie avute în vedere tipurile de variabile specificate, ca parametrii ai procedurilor read si readln. Urmatoarea secventa de program reprezinta o solutie corecta pentru citirea celor sase numere de pe cele doua linii de input.

...
VAR
...i,j,k,l:integer;
...r,s:real;
BEGIN
......
...readln(i,j,r,k);
...readln(s,l);
......

Remarca.

Tipul fiecarei variabile este în concordanta cu tipul valorilor din cele doua linii de intrare.

Rezultatul executiei secventei de program:

Variabila Valoare
i 254
j -13
r 4.87
k 59
s 18.7
l 94

O alta solutie, de asemenea corecta, dar mai lunga, pentru citirea celor sase valori este urmatoarea:

read(i,j);
readln(r,k);
readln(s,l);

Secventa de program lucreaza corect, întrucât la întâlnirea enuntului read, procesorul face pauza în mijlocul liniei de intrare si continua prelucrarea valorilor pe aceeasi linie la întâlnirea enuntului readln(r,k).

În urma executiei primului enunt read(i,j), imaginea primei linii de input este urmatoarea:

254W -13W W W 4.87W 59<CR>
.................­

Când executia programului continua cu readln(r,k) pointerul va avansa peste blancurile intercalate pentru a atribui valori variabilelor r si k.

Sa ne oprim putin si sa încercam sa raspundem la urmatoarea întrebare. Ce se întâmpla atunci când caracterul eof (end - of - file) este întâlnit înaintea urmatoarei valori ?

Daca ar urma alta linie cu date corecte, atunci nu ar fi probleme. Daca nu exista alta linie si programul este rulat interactiv, calculatorul intra în asteptare.

O alta solutie, pentru citirea celor sase valori este:

read(i,j,r,k,s,l);
readln;

Secventa de program prezentata lucreaza deoarece, la întâlnirea lui read, programul va citi patru valori care sunt pe prima linie si le va cauta pe celelalte doua ramase pe liniile care urmeaza.

Sa urmarim în continuare câteva încercari nereusite de citire a celor sase valori de pe cele doua linii pe care le-am avut în considerare.

Întâi secventa (gresita):

read(i,j,k,l,r,s);
readln;

care este identica cu precedenta, dar parametrii sunt listati în ordine diferita. Procedura va atribui lui 'i' valoarea 254, lui 'j' -13 dar nu va izbuti sa gaseasca doi întregi consecutivi pentru a-i atribui variabilelor k si l.

Remarca.Un program PASCAL standard va citi numai 4 din valoarea reala 4.87 si o va atribui variabilei k, apoi ceea ce ramâne .87 nu este un numar valid astfel încât nu poate fi atribuit variabilei întregi (eroare la executie).

Sa privim o noua solutie:

readln(i,j,r);
readln(k,r,s,l);

De remarcat ca valorile pentru variabilele i,j si r vor fi citite corect. Dar dupa aceea pointerul va trece pe a doua linie, lasând a patra valoare din prima linie (59) neprelucrata (necitita).

Programul nu se va supara, dar va obiecta când va încerca sa citeasca a doua linie, deoarece valoarea 18.7 nu va putea fi atribuita variabilei întregi k, deoarece 18.7 nu are o forma valida pentru numere întregi.

Secventa de program care urmeaza cauzeaza cea mai subtila si poate cea mai exasperanta eroare:

readln(i,j);
readln(r,k,s,l);

Aceasta secventa lasa doi orfani (4.87 si 59) în prima linie de input, valorile atribuindu-se numai variabilelor i, j, r, k . In plus variabilele s si l nu vor fi citite niciodata (nu mai exista informatie disponibila la input):

Variabila Valoare
i 254
j -13
r 4.87
k 59
s ?
l ?

Reguli:
  • Readln provoaca un salt la linia urmatoare;
  • Read (sau readln, sau combinatii ale acestora) atribuie valori numai variabilelor de intrare definite ca parametrii ai procedurii;
  • Fiecare valoare citita este atribuita unei variabile de tip corespunzator. În caz contrar (format invalid, mai ales la numere) se genereaza o eroare la executie.