Oppure

Loading
Program Esempio2;
Uses Crt,WinDos;
Var nome1,nome2,stringa:string;
    file1,file2:text;

begin
    clrscr;
    write(‘Inserire il nome di un file: ‘);
    readln(nome1);
    write(‘Inserire il nome del file copia: ‘);
    readln(nome2);
    Assign(file1,nome1);
    Assign(file2,nome2);
    Reset(file1);
    Rewrite(file2);
    repeat
    readln(file1,stringa);
    writeln(file2,stringa);
    until eof(file1);
    Close(file1);
    Close(file2);
    writeln(‘Copia completata!’);
    readln
end.


Bene, questo programma non è di immediata comprensione, poiché contiene un concentrato di procedure e regole nuove non indifferente. Procediamo con calma:

Assign(nome1,file1); : questa procedura assegna alla variabile file1 di tipo text il nome del file contenuto nella stringa nome1.
Per questo, è doveroso aprire una parentesi su come Pascal legge i nomi dei file: innanzitutto, un nome può essere composto da al massimo 8 caratteri, estensione esclusa; se il nome supera gli 8 caratteri viene troncato a 6 e si aggiunge un ‘~1’ (il codice ASCII di ~ è 126). Perciò il nome ‘testouno.txt’ è giusto e viene mantenuto così; ‘testoquattro.txt’ è sbagliato e il compilatore vi manderà un messaggio di errore (error 2: File not found); ‘testoq~1.txt’ è la versione giusta dell’esempio precedente: i caratteri vengono troncati a 6 e aggiunto un ‘~1’. Inoltre, il nome può contenere anche l’indirizzo completo di un file, dove ogni cartella deve sottostare alla legge degli 8 caratteri, perciò: ‘C:\Documents and settings\Proprietario\Fileone.txt’ è sbagliato, mentre ‘C:\Docume~1\Propri~1\Fileone.txt’ è giusto.
Per non convertire tutti i nomi a mano, potete scaricare il codice sorgente vb nella sezione Sorgenti->VB.NET, che contiene delle funzioni vb per convertire il nome normale di un file in nome corto.

Reset(file1); : l’istruzione reset(x), dove x è una variabile inizializzata con Assign e di tipo text o file, serve per aprire il file x, in vista di operazioni di lettura/scrittura su di esso.

Rewrite(file2); : valgono le stesse regole di reset. Rewrite(x:text o file) è una procedura che crea un nuovo file x (se non è specificata la directory nel suo nome, viene creato nel path corrente). Se esiste già un file di nome x, lo sovrascrive.

repeat...until eof(file1); : ripete un ciclo di istruzioni finché l’espressione indicata dopo until è vera. Nel nostro caso, il programma continua a leggere, riga per riga, ogni sequenza di caratteri contenuta in file1 e la copia in file2, finché la variabile reimpostata eof (che significa End Of File; supporta solo parametri di tipo text o file) non è vera (se non si mette un segno di comparazione, il compilatore sottintende un ‘=true’), e quindi il file da cui leggere è al termine.

Close(file1); : la procedura close chiude un file.

Questo programma è già di un livello più alto: meriterebbe uno studio più accurato per capire il funzionamento, da parte del lettore.

Come si è ben visto, il ciclo repeat...until serve per ripetere un istruzione o un blocco di istruizioni fino a che una condizione non è vera: come avrete sicuramente notato, in questo caso non serve racchiudere il blocco di istruzioni fra un begin ed un end, poichè i confini del blocco sono già repeat e until.
Un ultima osservazione: si può trovare anche un ciclo repeat...until senza istruzioni, così:

(*ripete un ciclo di istruzioni vuoto finchè non viene premuto un pulsante*)
repeat until keypressed;


Anche se è un caso usato non molto spesso, è giusto saperlo.

Nelle strutture iterative, ossia le istruzioni che fanno ripetere sempre uno stesso blocco di istruzioni un certo numero di volte o finchè una condizione è vera, è opportuno controllare sempre che le condizioni di uscita siano giuste. per esempio:

Program CicloInfinito;
Uses crt;
var n:longint;

begin
    clrscr;
    writeln('Inserire un numero: ');
    readln(n);
    repeat
    n:=n+2;
    until n mod 2=0;
    readln
end.


Come si vede, viene letta una variabile longint n che viene aumentata di 2 fino a che il resto di n/2 è 0. Ma se n è dispari il ciclo non finirà mai, in quanto n è sempre dispari e perciò n/2 dà come resto sempre 1.
E' bene stare in guardia dai cicli infiniti, sebbene qualche volta possano essere utili.

Per esempio, PRobot è un programma, che forse qualcuno di voi conoscerà, che permette di programmare un robot virtuale con il linguaggio Pascal e di farlo poi combattere. Ecco, in questo case si deve usare un ciclo infinito con molte istruzioni if al suo interno:

repeat
(*ciclo di istruzioni*)
if ... then
  ...
...
until false;


Il codice ripete sempre il ciclo finchè false non è uguale a true, il che non può mai accadere, in quanto falso è sempre diverso da vero.
Anche se casi border-line, può essere utile conoscerli.
A cura di: Il Totem