I file sequenziali in QBASIC - Corsi di Laurea a Distanza
I file sequenziali in QBASIC - Corsi di Laurea a Distanza
I file sequenziali in QBASIC - Corsi di Laurea a Distanza
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
I <strong>file</strong> 1<br />
I <strong>file</strong> <strong>sequenziali</strong><br />
<strong>in</strong> <strong>QBASIC</strong><br />
Clau<strong>di</strong>o Fornaro<br />
24 febbraio 2003
2<br />
I <strong>file</strong><br />
1. I <strong>file</strong><br />
Un <strong>file</strong> è un’area <strong>di</strong> memoria su un <strong>di</strong>spositivo <strong>di</strong> memoria <strong>di</strong> massa<br />
quale ad esempio un <strong>di</strong>sco, ad essa è stato dato un nome per poterla<br />
identificare. Il sistema operativo non conosce la struttura <strong>in</strong>terna del <strong>file</strong><br />
né ne è <strong>in</strong>teressato, per esso si tratta semplicemente <strong>di</strong> una sequenza <strong>di</strong><br />
byte con un nome. Il sistema operativo è comunque <strong>in</strong> grado <strong>di</strong> leggere o<br />
scrivere dei byte da o sul <strong>file</strong>.<br />
Esistono sostanzialmente due tipi <strong>di</strong> <strong>file</strong>:<br />
• <strong>file</strong> ad accesso sequenziale<br />
• <strong>file</strong> ad accesso <strong>di</strong>retto (detti anche ad accesso casuale o random)<br />
In un <strong>file</strong> ad accesso sequenziale i dati sono scritti uno dopo l’altro,<br />
poiché si possono scrivere valori <strong>di</strong> tipo <strong>di</strong>verso (e qu<strong>in</strong><strong>di</strong> <strong>di</strong> <strong>di</strong>mensione<br />
<strong>di</strong>versa) per accedere all’elemento i-esimo è necessario leggere tutti i<br />
precedenti (non ho modo <strong>di</strong> sapere da quale byte (rispetto al primo byte<br />
del <strong>file</strong>) del <strong>file</strong> <strong>in</strong>izia l’i-esimo dato essendo quelli <strong>in</strong>terme<strong>di</strong> <strong>di</strong><br />
<strong>di</strong>mensione varia).<br />
In un <strong>file</strong> ad accesso <strong>di</strong>retto i dati hanno tutti la stessa <strong>di</strong>mensione: si<br />
def<strong>in</strong>isce una struttura dati <strong>di</strong> <strong>di</strong>mensione (ossia un numero <strong>di</strong> byte)<br />
adeguata a contenere tutti i tipi <strong>di</strong> dati da considerare. Detta struttura si<br />
chiama record. Essendo i record <strong>di</strong> <strong>di</strong>mensione fissa (tutti ad esempio <strong>di</strong><br />
20 byte), per accedere all’i-esimo dato basta accedere all’i-esimo record<br />
che <strong>in</strong>izia alla posizione (cioè dal byte numero) i*<strong>di</strong>mensione_record (ad<br />
es. il 4 o record <strong>in</strong>izia dal byte 4*20=160, essendo il primo byte del <strong>file</strong> il<br />
numero 1), e qu<strong>in</strong><strong>di</strong> la velocità <strong>di</strong> accesso è assai più elevata rispetto al<br />
caso dei <strong>file</strong> <strong>sequenziali</strong>.<br />
Se la <strong>di</strong>mensione del record è adeguata a contenere dati <strong>di</strong> <strong>di</strong>versa<br />
lunghezza, quando si utilizzano questi record per dati <strong>di</strong> lunghezza<br />
<strong>in</strong>feriore si ha uno spreco <strong>di</strong> memoria (su <strong>di</strong>sco), cioè rimangono dei<br />
“buchi” <strong>in</strong>utilizzati all’<strong>in</strong>terno <strong>di</strong> alcuni record (si veda lo schema sotto),<br />
ma questo è i prezzo da pagare per un accesso più veloce.<br />
I <strong>file</strong> ad accesso sequenziale più utilizzati sono i cosiddetti <strong>file</strong> <strong>di</strong> testo,<br />
ossia <strong>file</strong> composti da soli caratteri ASCII (standard). Questi <strong>file</strong><br />
contengono solo caratteri, qu<strong>in</strong><strong>di</strong> anche i numeri sono espressi come<br />
sequenze <strong>di</strong> caratteri. Per creare un <strong>file</strong> <strong>di</strong> testo (estensione .TXT) si usa<br />
un e<strong>di</strong>tor come EDIT, NOTEPAD, BLOCCO NOTE, o altri (non Word<br />
che è <strong>in</strong>vece un word processor). Un <strong>file</strong> <strong>di</strong> testo ha normalmente varie<br />
righe, ciascuna term<strong>in</strong>ata da un carattere <strong>in</strong>visibile <strong>di</strong> ritorno a capo<br />
(immesso premendo il tasto INVIO). Nel seguito utilizzeremo
I <strong>file</strong> 3<br />
esclusivamente <strong>file</strong> <strong>di</strong> testo <strong>in</strong> quanto costituiscono il caso più generale <strong>di</strong><br />
<strong>file</strong> e <strong>in</strong> altri l<strong>in</strong>guaggi importanti sono l’unico tipo <strong>di</strong> <strong>file</strong> che il<br />
programmatore può utilizzare. Una volta che si è imparato a utilizzare<br />
questi <strong>file</strong> è molto semplice estendere le proprie conoscenze agli altri.<br />
1.1 Aprire e chiudere un <strong>file</strong><br />
E’ possibile utilizzare più <strong>file</strong> contemporaneamente, ad esempio<br />
leggendo da due <strong>file</strong> e mettendo i risultati <strong>in</strong> un altro <strong>file</strong>. In BASIC è<br />
necessario <strong>in</strong>formare il sistema che si <strong>in</strong>tende operare su un certo <strong>file</strong> <strong>in</strong><br />
un certo modo, questa operazione si chiama apertura del <strong>file</strong> e deve<br />
chiaramente avvenire prima <strong>di</strong> accedere effettivamente al <strong>file</strong> stesso.<br />
Ecco come si apre un <strong>file</strong>:<br />
OPEN nome<strong>file</strong> FOR modo AS #numero<br />
nome<strong>file</strong> è una str<strong>in</strong>ga, costante o variabile, contenente il nome del <strong>file</strong><br />
da aprire,<br />
modo <strong>in</strong><strong>di</strong>ca se si <strong>in</strong>tende leggere (prelevare dei valori da quel <strong>file</strong>) o<br />
scrivere (aggiungervene),<br />
numero è un numero <strong>in</strong>tero compreso tra 1 e 255 (costante o variabile)<br />
che identificherà d’ora <strong>in</strong> poi il <strong>file</strong> nome<strong>file</strong> aperto <strong>in</strong> quel<br />
modo.<br />
Nel seguito, quando vorremo trattare il <strong>file</strong> così aperto basterà <strong>in</strong><strong>di</strong>carne<br />
il numero.<br />
Se vogliamo aprire più <strong>file</strong>, è sufficiente dare a ciascuno un numero<br />
<strong>di</strong>verso.<br />
Un <strong>file</strong> può essere aperto o solo <strong>in</strong> lettura o solo <strong>in</strong> scrittura, ma non <strong>in</strong><br />
entrambi i mo<strong>di</strong> (neppure con due OPEN <strong>di</strong>verse).<br />
I mo<strong>di</strong> <strong>di</strong> accesso al <strong>file</strong> si è detto essere o <strong>in</strong> lettura o <strong>in</strong> scrittura, <strong>in</strong><br />
realtà ci sono tre mo<strong>di</strong> <strong>di</strong> accesso, ossia modo può essere una delle<br />
seguenti keyword:<br />
INPUT modalità <strong>di</strong> <strong>in</strong>put, per leggere valori dal <strong>file</strong>; se il <strong>file</strong> non<br />
esiste e si cerca <strong>di</strong> aprirlo il programma si ferma segnalando il<br />
problema,<br />
OUTPUT modalità <strong>di</strong> output, per scrivere valori nel <strong>file</strong>; se il <strong>file</strong> non<br />
esiste viene creato nuovo vuoto, pronto per essere scritto, se<br />
già esiste viene prima cancellato e poi creato nuovo come<br />
sopra,<br />
APPEND modalità <strong>di</strong> output, per scrivere valori nel <strong>file</strong>; se il <strong>file</strong> non<br />
esiste viene creato nuovo vuoto, pronto per essere scritto, se<br />
già esiste NON viene prima cancellato, ma le successive<br />
scritture verranno aggiunte <strong>in</strong> fondo (appunto appese).
4<br />
I <strong>file</strong><br />
Esempio<br />
OPEN "mio<strong>file</strong>.txt" FOR INPUT AS #12<br />
Questa istruzione apre un <strong>file</strong> <strong>di</strong> nome mio<strong>file</strong>.txt <strong>in</strong> modo da<br />
leggerlo e gli assegna il numero 12.<br />
Il <strong>file</strong> da aprire viene cercato o creato nella <strong>di</strong>rectory corrente, se si vuole<br />
<strong>in</strong><strong>di</strong>care un altro percorso lo si deve <strong>in</strong><strong>di</strong>care esplicitamente (es.<br />
“C:\MIEIBAS\mio<strong>file</strong>.txt”). Si rammenti che l’<strong>in</strong>terprete<br />
<strong>QBASIC</strong> non è stato aggiornato da molto tempo per cui i <strong>file</strong> e le<br />
<strong>di</strong>rectory non possono contenere spazi o essere ciascuno più lungo <strong>di</strong> 8<br />
caratteri, oltre ai 3 <strong>di</strong> estensione .TXT).<br />
Quando un <strong>file</strong> non serve più lo si chiude con:<br />
CLOSE(numero)<br />
dove numero è quello assegnato dalla OPEN. Ogni <strong>file</strong> deve avere la sua<br />
CLOSE. Dopo la CLOSE il numero può essere riutilizzato per un<br />
qualsiasi altro <strong>file</strong> e il <strong>file</strong> che era stato aperto può essere eventualmente<br />
riaperto, magari con un altro modo <strong>di</strong> accesso. La guida <strong>di</strong>ce che la<br />
CLOSE viene effettuata automaticamente quando il programma term<strong>in</strong>a,<br />
non è sempre vero. Se si scrive <strong>in</strong> un <strong>file</strong> e non lo si chiude<br />
esplicitamente con una CLOSE c’è il pericolo <strong>di</strong> perdere gli ultimi dati<br />
scritti. Il problema ovviamente non si presenta se il <strong>file</strong> viene letto.<br />
1.2 Scrivere <strong>in</strong> un <strong>file</strong><br />
Quando si tratta <strong>di</strong> <strong>file</strong> <strong>di</strong> testo, per il sistema è <strong>in</strong><strong>di</strong>fferente mandare i<br />
caratteri sul video o <strong>in</strong> un <strong>file</strong>. L’istruzione per scrivere su un <strong>file</strong> è<br />
sempre PRINT, ma con una piccola mo<strong>di</strong>fica:<br />
PRINT #numero, espressione; espressione; ...<br />
La piccola mo<strong>di</strong>fica sta nell’<strong>in</strong><strong>di</strong>cazione #numero come primo parametro<br />
della PRINT, questo specifica che i caratteri da stampare non devono<br />
andare sul video, bensì nel <strong>file</strong> numero. Esempio:<br />
OPEN "mio<strong>file</strong>.txt" FOR OUTPUT AS #6<br />
PRINT #6, "Risultato: "; Risult<br />
Anche qui per non andare a capo si può mettere un punto e virgola alla<br />
f<strong>in</strong>e dell’istruzione PRINT. Si noti che <strong>in</strong> sistemi MS-DOS e MS-<br />
W<strong>in</strong>dows il ritorno a capo viene memorizzato nei <strong>file</strong> per mezzo <strong>di</strong> due<br />
caratteri, non uno solo.<br />
Ecco un esempio <strong>di</strong> programma che legge dalla tastiera delle str<strong>in</strong>ghe<br />
(ma possono anche essere dei numeri) e le mette <strong>in</strong> un <strong>file</strong> il cui nome<br />
viene chiesto all’utente. Si cont<strong>in</strong>ua a chiedere una str<strong>in</strong>ga da mettere nel
I <strong>file</strong> 5<br />
<strong>file</strong> f<strong>in</strong>ché non si immette la str<strong>in</strong>ga basta, le righe vengono scritte nel<br />
<strong>file</strong> come se fosse il video, una sotto l’altra.<br />
DIM Nome<strong>file</strong> AS STRING<br />
DIM Riga AS STRING<br />
OPEN Nome<strong>file</strong> FOR OUTPUT AS #5<br />
LINE INPUT "Riga da aggiungere:", Riga<br />
DO WHILE Riga "basta"<br />
PRINT #5, Riga<br />
LINE INPUT "Riga da aggiungere:", Riga<br />
LOOP<br />
CLOSE(5)<br />
1.3 Leggere da un <strong>file</strong><br />
Leggere da un <strong>file</strong> è quasi come leggere dalla tastiera, l’istruzione da<br />
usare è sempre INPUT, ma con una piccola mo<strong>di</strong>fica:<br />
INPUT #numero, espressione; espressione; ...<br />
La piccola mo<strong>di</strong>fica sta nell’<strong>in</strong><strong>di</strong>cazione #numero come primo parametro<br />
della INPUT, questo specifica che i caratteri da leggere non devono<br />
essere prelevati dalla tastiera, bensì dal <strong>file</strong> numero. Non si deve mettere<br />
il prompt nella INPUT <strong>in</strong> quanto l’<strong>in</strong>put è richiesto ad un <strong>file</strong> e non ad un<br />
essere umano. Per il resto non ci sono <strong>di</strong>fferenze con l’<strong>in</strong>put da tastiera:<br />
se la variabile dell’INPUT è numerica i caratteri letti dal <strong>file</strong> vengono<br />
convertiti <strong>in</strong> numero così come succedeva per l’<strong>in</strong>put da tastiera <strong>di</strong> un<br />
numero, se <strong>in</strong>vece è str<strong>in</strong>ga i caratteri vengono memorizzati tali e quali.<br />
Una str<strong>in</strong>ga viene letta f<strong>in</strong>o alla virgola o f<strong>in</strong>o al ritorno a capo, per<br />
ignorare le virgole come separatori si usa LINE INPUT.<br />
Esempio:<br />
DIM Valore AS DOUBLE<br />
DIM Riga AS STRING<br />
OPEN "mio<strong>file</strong>.txt" FOR INPUT AS #4<br />
INPUT #4, Valore<br />
LINE INPUT #4, Riga<br />
Ogni istruzione INPUT “consuma” una parte <strong>di</strong> <strong>file</strong>: la successiva<br />
INPUT va a considerare i caratteri che la precedente INPUT non ha<br />
considerato, così ad esempio nel seguente co<strong>di</strong>ce la prima INPUT legge<br />
la prima riga del <strong>file</strong> f<strong>in</strong>o al ritorno a capo, la seconda INPUT la seconda<br />
riga, ogni successiva INPUT legge un altra riga f<strong>in</strong>o alla f<strong>in</strong>e del <strong>file</strong>.<br />
LINE INPUT #4, Riga1<br />
LINE INPUT #4, Riga2
6<br />
I <strong>file</strong><br />
Non è possibile ritornare <strong>in</strong><strong>di</strong>etro a rileggere un qualcosa che è già stato<br />
letto, a meno che non si chiuda il <strong>file</strong> e lo si riapra: quando si apre un <strong>file</strong><br />
si <strong>in</strong>izia sempre a leggerlo da capo.<br />
Ma come facciamo a sapere se abbiamo letto tutto il <strong>file</strong> o c’è<br />
qualcos’altro da leggere? Esiste la funzione EOF (End Of File) che<br />
applicata ad un numero <strong>di</strong> <strong>file</strong> restituisce il valore vero se il <strong>file</strong> è<br />
term<strong>in</strong>ato, falso se c’è ancora qualcosa da leggere prima <strong>di</strong> raggiungerne<br />
la f<strong>in</strong>e. Ovviamente la EOF deve essere utilizzata prima <strong>di</strong> effettuare<br />
ciascuna operazione <strong>di</strong> INPUT. Lo schema generale per leggere un <strong>file</strong> è<br />
costituito da un ciclo WHILE che term<strong>in</strong>a quando il <strong>file</strong> è f<strong>in</strong>ito:<br />
DO WHILE NOT EOF(9)<br />
LINE INPUT #9, Riga<br />
PRINT Riga<br />
LOOP<br />
F<strong>in</strong>tantoché non c’è la f<strong>in</strong>e del <strong>file</strong> numero 9, leggi un riga e stampala.<br />
Ecco un esempio completo dove il programma chiede all’utente il nome<br />
<strong>di</strong> un <strong>file</strong> <strong>in</strong> <strong>in</strong>put (contenente uno per riga dei valori frazionari), chiede il<br />
nome <strong>di</strong> un <strong>file</strong> <strong>in</strong> output e calcola e scrive <strong>in</strong> questo <strong>file</strong> i valori elevati al<br />
quadrato, sempre uno per riga. Alla f<strong>in</strong>e stampa sul video il numero <strong>di</strong><br />
valori elaborati.<br />
DIM V as DOUBLE<br />
DIM Cont AS INTEGER<br />
DIM FileIN AS STRING<br />
DIM FileOUT AS STRING<br />
INPUT "File <strong>in</strong> <strong>in</strong>put"; FileIN<br />
INPUT "File <strong>in</strong> output"; FileOUT<br />
OPEN FileIN FOR INPUT AS # 1<br />
OPEN FileOUT FOR OUTPUT AS # 2<br />
Cont = 0<br />
DO WHILE NOT EOF(1)<br />
INPUT #1, V<br />
PRINT #2, V*V<br />
Cont = Cont + 1<br />
LOOP<br />
PRINT "Sono stati elaborati; Cont; " numeri"<br />
CLOSE(1)<br />
CLOSE(2)<br />
END
I <strong>file</strong> 7<br />
L’istruzione END serve per far term<strong>in</strong>are un programma, non l’abbiamo<br />
mai messa <strong>in</strong> quanto può essere tralasciata se è l’ultima istruzione del<br />
programma. Anche qui ovviamente poteva essere tralasciata.<br />
1.4 Esercizi<br />
1) Scrivere con un e<strong>di</strong>tor un <strong>file</strong> contenente uno per riga dei numeri.<br />
Scrivere ora un programma che chieda all’utente il nome <strong>di</strong> questo<br />
<strong>file</strong>, lo apra e calcoli e stampi a video quanti sono i valori letti, il<br />
valore massimo, il valore m<strong>in</strong>imo, la somma e la me<strong>di</strong>a <strong>di</strong> tutti i<br />
valori presenti nel <strong>file</strong>.<br />
2) Scrivere con un e<strong>di</strong>tor un <strong>file</strong> contenente una per riga delle str<strong>in</strong>ghe.<br />
Scrivere ora un programma che chieda all’utente il nome <strong>di</strong> questo<br />
<strong>file</strong>, lo apra e calcoli e stampi a video quante sono le righe, la str<strong>in</strong>ga<br />
maggiore e quella m<strong>in</strong>ore tra tutte quelle presenti nel <strong>file</strong>.<br />
3) Scrivere un programma che legge le righe <strong>di</strong> un <strong>file</strong> e le stampa<br />
dall’ultima alla prima (vettore <strong>di</strong> str<strong>in</strong>ghe).<br />
4) Come sopra, ma le righe vanno messe <strong>in</strong> un altro <strong>file</strong> e il programma<br />
deve poi scrivere a video quante righe sono state trascritte.<br />
5) Scrivere un programma che apra un <strong>file</strong> e calcoli <strong>in</strong> totale quante<br />
sono le cifre, le lettere maiuscole, le lettere m<strong>in</strong>uscole e gli altri<br />
caratteri presenti. (Suggerimento: leggere ciascuna delle righe con<br />
LINE INPUT e trattarle con FOR e MID$).<br />
6) Scrivere un programma che legge da un <strong>file</strong> un testo e spezza su più<br />
righe quelle più lunghe <strong>di</strong> N caratteri (N chiesto all’utente). Una<br />
parola può anche essere spezzata, se necessario. L’output deve essere<br />
salvato <strong>in</strong> un altro <strong>file</strong>.<br />
7) Come il precedente, ma le righe si possono spezzare solo dove c’è<br />
uno spazio (se lo spazio non c’è si ricade nel caso dell’esercizio<br />
precedente).<br />
8) Si vuole un programma che cifri/decifri un <strong>file</strong> <strong>di</strong> testo <strong>in</strong> base ad un<br />
co<strong>di</strong>ce segreto. Il programma deve chiedere il <strong>file</strong> <strong>di</strong> <strong>in</strong>put, il <strong>file</strong> <strong>di</strong><br />
output, il co<strong>di</strong>ce (un numero <strong>in</strong>tero). La cifratura avviene sostituendo<br />
le sole lettere (maiuscole e m<strong>in</strong>uscole) con delle altre lettere <strong>in</strong> base<br />
al valore del co<strong>di</strong>ce. Questo <strong>in</strong><strong>di</strong>ca <strong>di</strong> quanti caratteri si deve<br />
<strong>in</strong>crementare ciascuna delle lettere: se ad esempio il co<strong>di</strong>ce è 3,<br />
allora la A <strong>di</strong>venta D, la B <strong>di</strong>venta E, ecc. f<strong>in</strong>o a X che <strong>di</strong>venta A, Y<br />
che <strong>di</strong>venta B e Z che <strong>di</strong>venta C. Lo stesso per le m<strong>in</strong>uscole. Inoltre<br />
per decifrare un testo basta immettere un co<strong>di</strong>ce negativo (ad es. –3).<br />
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z<br />
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
8<br />
I <strong>file</strong><br />
9) (Non semplice). Si vuole un programma che cifri/decifri un <strong>file</strong> <strong>di</strong><br />
testo <strong>in</strong> base ad un co<strong>di</strong>ce segreto. Il programma deve chiedere il <strong>file</strong><br />
<strong>di</strong> <strong>in</strong>put, il <strong>file</strong> <strong>di</strong> output, il co<strong>di</strong>ce (una str<strong>in</strong>ga) e se si vuole cifrare o<br />
decifrare il testo. La cifratura avviene sostituendo le sole lettere<br />
(maiuscole e m<strong>in</strong>uscole) con delle altre lettere secondo questo<br />
algoritmo: il co<strong>di</strong>ce <strong>in</strong>trodotto deve essere composto <strong>di</strong> sole lettere<br />
(maiuscole o m<strong>in</strong>uscole non importa) tutte <strong>di</strong>verse (controllare), la<br />
prima lettera del co<strong>di</strong>ce viene fatta corrispondere alla lettera A, la<br />
seconda alla B, e così via f<strong>in</strong>o all’ultima lettera del co<strong>di</strong>ce. Le lettere<br />
non <strong>in</strong><strong>di</strong>cate nel co<strong>di</strong>ce vengono riord<strong>in</strong>ate alfabeticamente al<br />
contrario (dalla Z alla A) e fatte corrispondere alle restanti lettere.<br />
Esempio, dato il co<strong>di</strong>ce segreto FRAGOLE la corrispondenza delle<br />
lettere sarà:<br />
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z<br />
F R A G O L E Z Y X W V U T S Q P N M K J I H D C B<br />
Si vede che dopo la E <strong>di</strong> FRAGOLE ci sono le restanti lettere<br />
dell’alfabeto dalla Z alla A. Qu<strong>in</strong><strong>di</strong> la parola Ciao viene cifrata <strong>in</strong><br />
Ayfs.
I <strong>file</strong> 9<br />
1.5 Soluzione degli esercizi<br />
Esercizio 1<br />
DIM cont AS INTEGER<br />
DIM v AS INTEGER<br />
DIM somma AS INTEGER, me<strong>di</strong>a AS INTEGER<br />
DIM max AS INTEGER, m<strong>in</strong> AS INTEGER<br />
DIM <strong>file</strong> AS STRING<br />
INPUT "nome del <strong>file</strong>"; <strong>file</strong><br />
OPEN <strong>file</strong> FOR INPUT AS #1<br />
IF NOT EOF(1) THEN 'controlla se esiste almeno 1 riga<br />
INPUT #1, v<br />
max = v<br />
m<strong>in</strong> = v<br />
cont = 1<br />
ELSE<br />
PRINT "il <strong>file</strong> è vuoto"<br />
END 'term<strong>in</strong>a il programma<br />
END IF<br />
DO WHILE NOT EOF(1)<br />
INPUT #1, v<br />
cont = cont + 1<br />
somma = somma + v<br />
IF v > max THEN<br />
max = v<br />
ELSEIF v < m<strong>in</strong> THEN<br />
m<strong>in</strong> = v<br />
END IF<br />
LOOP<br />
CLOSE (1)<br />
PRINT "Numero valori = "; cont<br />
PRINT "Me<strong>di</strong>a = "; somma / cont<br />
PRINT "Somma = "; somma<br />
PRINT "M<strong>in</strong> = "; m<strong>in</strong><br />
PRINT "Max = "; max<br />
END<br />
Nota: si noti l’istruzione END collocata <strong>in</strong> mezzo al co<strong>di</strong>ce e non<br />
solo <strong>in</strong> fondo al programma.
10<br />
Esercizio 2<br />
DIM cont AS INTEGER<br />
DIM riga AS STRING<br />
DIM max AS STRING<br />
DIM m<strong>in</strong> AS STRING<br />
DIM <strong>file</strong> AS STRING<br />
INPUT "nome del <strong>file</strong>"; <strong>file</strong><br />
OPEN <strong>file</strong> FOR INPUT AS #1<br />
cont = 0<br />
I <strong>file</strong><br />
IF NOT EOF(1) THEN 'controlla se esiste almeno 1<br />
riga<br />
INPUT #1, riga<br />
max = riga<br />
m<strong>in</strong> = riga<br />
ELSE<br />
PRINT "il <strong>file</strong> è vuoto"<br />
END 'term<strong>in</strong>a il programma<br />
END IF<br />
DO WHILE NOT EOF(1)<br />
INPUT #1, riga<br />
cont = cont + 1<br />
IF riga > max THEN<br />
max = riga<br />
ELSEIF riga < m<strong>in</strong> THEN<br />
m<strong>in</strong> = riga<br />
END IF<br />
LOOP<br />
CLOSE (1)<br />
PRINT "Numero righe = "; cont<br />
PRINT "Riga m<strong>in</strong>ore = "; m<strong>in</strong><br />
PRINT "Riga maggiore = "; max<br />
END<br />
Nota: maggiore secondo il co<strong>di</strong>ce ASCII, non più lunga; idem<br />
per m<strong>in</strong>ore.
I <strong>file</strong> 11<br />
Esercizio 3<br />
DIM <strong>file</strong> AS STRING<br />
DIM riga AS STRING<br />
DIM cont AS INTEGER<br />
DIM i AS INTEGER<br />
INPUT "<strong>file</strong>"; <strong>file</strong><br />
OPEN <strong>file</strong> FOR INPUT AS #1<br />
cont = 0<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
cont = cont + 1<br />
LOOP<br />
CLOSE (1)<br />
REDIM str<strong>in</strong>ghe(1 TO cont) AS STRING<br />
OPEN <strong>file</strong> FOR INPUT AS #1<br />
FOR i = 1 TO cont<br />
LINE INPUT #1, str<strong>in</strong>ghe(i)<br />
NEXT<br />
CLOSE (1)<br />
FOR i = cont TO 1 STEP -1<br />
PRINT str<strong>in</strong>ghe(i)<br />
NEXT<br />
Nota: il primo ciclo è <strong>di</strong> tipo WHILE <strong>in</strong> quanto non si sa quante<br />
siano le righe del <strong>file</strong>, le righe vengono lette e scartate: lo scopo<br />
<strong>di</strong> questo ciclo è solo quello <strong>di</strong> contare quante righe ci sono per<br />
poter <strong>di</strong>mensionare il vettore d<strong>in</strong>amico str<strong>in</strong>ghe <strong>di</strong> <strong>di</strong>mensione<br />
opportuna (cont). Il secondo ciclo è un FOR <strong>in</strong> quanto ora il<br />
numero <strong>di</strong> letture da fare è noto (cont), si sarebbe potuto<br />
comunque utilizzare un altro ciclo WHILE. Lo scopo <strong>di</strong> questo<br />
secondo ciclo è leggere tutte le righe del <strong>file</strong>. Il terzo ciclo<br />
percorre il vettore a ritroso.
12<br />
Esercizio 4<br />
DIM <strong>file</strong>IN AS STRING<br />
DIM <strong>file</strong>OUT AS STRING<br />
DIM riga AS STRING<br />
DIM cont AS INTEGER<br />
DIM i AS INTEGER<br />
INPUT "<strong>file</strong> <strong>in</strong> <strong>in</strong>put"; <strong>file</strong>IN<br />
INPUT "<strong>file</strong> <strong>in</strong> output"; <strong>file</strong>OUT<br />
OPEN <strong>file</strong>IN FOR INPUT AS #1<br />
cont = 0<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
cont = cont + 1<br />
LOOP<br />
CLOSE (1)<br />
REDIM str<strong>in</strong>ghe(1 TO cont) AS STRING<br />
OPEN <strong>file</strong>IN FOR INPUT AS #1<br />
FOR i = 1 TO cont<br />
LINE INPUT #1, str<strong>in</strong>ghe(i)<br />
NEXT<br />
CLOSE (1)<br />
OPEN <strong>file</strong>OUT FOR OUTPUT AS #2<br />
FOR i = cont TO 1 STEP -1<br />
PRINT #2, str<strong>in</strong>ghe(i)<br />
NEXT<br />
CLOSE (2)<br />
PRINT "Sono state trascritte"; cont; "righe"<br />
I <strong>file</strong>
I <strong>file</strong> 13<br />
Esercizio 5<br />
DIM i AS INTEGER<br />
DIM Riga AS STRING<br />
DIM Maius AS INTEGER<br />
DIM M<strong>in</strong>us AS INTEGER<br />
DIM Cifre AS INTEGER<br />
DIM Altri AS INTEGER<br />
DIM c AS STRING<br />
DIM <strong>file</strong> AS STRING<br />
Maius = 0<br />
M<strong>in</strong>us = 0<br />
Cifre = 0<br />
Altri = 0<br />
INPUT "<strong>file</strong>"; <strong>file</strong><br />
OPEN <strong>file</strong> FOR INPUT AS #1<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, Riga<br />
FOR i = 1 TO LEN(Riga)<br />
SELECT CASE MID$(Riga, i, 1)<br />
CASE "0" TO "9"<br />
Cifre = Cifre + 1<br />
CASE "A" TO "Z"<br />
Maius = Maius + 1<br />
CASE "a" TO "z"<br />
M<strong>in</strong>us = M<strong>in</strong>us + 1<br />
CASE ELSE<br />
Altri = Altri + 1<br />
END SELECT<br />
NEXT<br />
LOOP<br />
PRINT "cifre "; Cifre<br />
PRINT "maiuscole "; Maius<br />
PRINT "m<strong>in</strong>uscole "; M<strong>in</strong>us<br />
PRINT "altri "; Altri<br />
CLOSE (1)
14<br />
Esercizio 6<br />
DIM <strong>file</strong>IN AS STRING<br />
DIM <strong>file</strong>OUT AS STRING<br />
DIM N AS INTEGER<br />
DIM riga AS STRING<br />
INPUT "<strong>file</strong> <strong>in</strong> <strong>in</strong>put"; <strong>file</strong>IN<br />
INPUT "<strong>file</strong> <strong>in</strong> output"; <strong>file</strong>OUT<br />
INPUT "larghezza massima"; N<br />
OPEN <strong>file</strong>IN FOR INPUT AS #1<br />
OPEN <strong>file</strong>OUT FOR OUTPUT AS #2<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
IF LEN(riga) N<br />
PRINT #2, LEFT$(riga, N)<br />
riga = RIGHT$(riga, LEN(riga) - N)<br />
LOOP<br />
PRINT #2, riga<br />
END IF<br />
LOOP<br />
CLOSE (1)<br />
CLOSE (2)<br />
I <strong>file</strong>
I <strong>file</strong> 15<br />
Esercizio 7<br />
DIM <strong>file</strong>IN AS STRING<br />
DIM <strong>file</strong>OUT AS STRING<br />
DIM N AS INTEGER<br />
DIM riga AS STRING<br />
DIM rigatmp AS STRING<br />
DIM spazio AS INTEGER<br />
DIM i AS INTEGER<br />
INPUT "<strong>file</strong> <strong>in</strong> <strong>in</strong>put"; <strong>file</strong>IN<br />
INPUT "<strong>file</strong> <strong>in</strong> output"; <strong>file</strong>OUT<br />
INPUT "larghezza massima"; N<br />
OPEN <strong>file</strong>IN FOR INPUT AS #1<br />
OPEN <strong>file</strong>OUT FOR OUTPUT AS #2<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
IF LEN(riga) N<br />
rigatmp = LEFT$(riga, N)<br />
'cerca l'ultimo spazio, se c'è<br />
spazio = 0 ' 0 se non c'è<br />
FOR i = N TO 1 STEP -1<br />
IF MID$(rigatmp, i, 1) = " " THEN<br />
spazio = i<br />
EXIT FOR<br />
END IF<br />
NEXT<br />
IF spazio = 0 THEN 'non trovato spazio<br />
spazio = N<br />
END IF<br />
PRINT #2, LEFT$(riga, spazio)<br />
riga = RIGHT$(riga, LEN(riga) - spazio)<br />
LOOP<br />
PRINT #2, riga<br />
END IF<br />
LOOP<br />
CLOSE (1)<br />
CLOSE (2)
16<br />
Esercizio 8<br />
Prima versione<br />
DIM Co<strong>di</strong>ce AS INTEGER<br />
DIM c AS STRING<br />
DIM cc AS INTEGER<br />
DIM riga AS STRING 'riga da cifrare<br />
DIM FileIN AS STRING<br />
DIM FileOUT AS STRING<br />
I <strong>file</strong><br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> <strong>in</strong>put"; FileIN<br />
OPEN FileIN FOR INPUT AS #1 'se non lo trova si ferma subito<br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> output"; FileOUT<br />
OPEN FileOUT FOR OUTPUT AS #2<br />
INPUT "Co<strong>di</strong>ce"; Co<strong>di</strong>ce<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
FOR I = 1 TO LEN(riga)<br />
c = MID$(riga, I, 1)<br />
IF c >= "A" AND c ASC("Z") THEN<br />
cc = cc - 26<br />
ELSEIF cc < ASC("A") THEN<br />
cc = cc + 26<br />
END IF<br />
MID$(riga, I, 1) = CHR$(cc)<br />
ELSEIF c >= "a" AND c ASC("z") THEN<br />
cc = cc - 26<br />
ELSEIF cc < ASC("a") THEN<br />
cc = cc + 26<br />
END IF<br />
MID$(riga, I, 1) = CHR$(cc)<br />
END IF<br />
NEXT<br />
PRINT #2, riga<br />
LOOP<br />
CLOSE (1)<br />
CLOSE (2)
I <strong>file</strong> 17<br />
Seconda versione<br />
DIM co<strong>di</strong>ce AS INTEGER<br />
DIM c AS STRING<br />
DIM cc AS INTEGER<br />
DIM riga AS STRING 'riga da cifrare<br />
DIM FileIN AS STRING<br />
DIM FileOUT AS STRING<br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> <strong>in</strong>put"; FileIN<br />
OPEN FileIN FOR INPUT AS #1 'se non lo trova si ferma subito<br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> output"; FileOUT<br />
OPEN FileOUT FOR OUTPUT AS #2<br />
INPUT "Co<strong>di</strong>ce"; co<strong>di</strong>ce<br />
co<strong>di</strong>ce = (co<strong>di</strong>ce + 26) MOD 26 'così non è mai negativo<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
FOR I = 1 TO LEN(riga)<br />
c = MID$(riga, I, 1)<br />
IF c >= "A" AND c = 0<br />
cc = (ASC(c) - ASC("A") + co<strong>di</strong>ce) MOD 26 + ASC("A")<br />
MID$(riga, I, 1) = CHR$(cc)<br />
ELSEIF c >= "a" AND c
18<br />
Esercizio 9<br />
DIM X AS STRING<br />
DIM Y AS STRING<br />
DIM Co<strong>di</strong>ce AS STRING<br />
DIM op AS STRING<br />
DIM c AS STRING<br />
DIM i AS INTEGER<br />
DIM ripetute AS INTEGER '0=no 1=si`<br />
DIM riga AS STRING 'riga da cifrare<br />
DIM posiz AS INTEGER<br />
DIM FileIN AS STRING<br />
DIM FileOUT AS STRING<br />
I <strong>file</strong><br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> <strong>in</strong>put"; FileIN<br />
OPEN FileIN FOR INPUT AS #1 'se non lo trova si ferma subito<br />
DO<br />
INPUT "Operazione (c=cifra, d=decifra)"; op<br />
op = LCASE$(op)<br />
LOOP UNTIL op = "c" OR op = "d"<br />
DO<br />
INPUT "Co<strong>di</strong>ce"; Co<strong>di</strong>ce<br />
Co<strong>di</strong>ce = UCASE$(Co<strong>di</strong>ce)<br />
'controlla se ci sono lettere ripetute<br />
ripetute = 0 'supponiamo non siano ripetute<br />
FOR i = 1 TO LEN(Co<strong>di</strong>ce)<br />
c = MID$(Co<strong>di</strong>ce, i, 1)<br />
IF INSTR(INSTR(1, Co<strong>di</strong>ce, c) + 1, Co<strong>di</strong>ce, c) 0 THEN<br />
PRINT "Il co<strong>di</strong>ce contiene caratteri ripetuti"<br />
ripetute = 1 'trovata una ripetuta<br />
EXIT FOR<br />
END IF<br />
NEXT<br />
LOOP UNTIL ripetute = 0
I <strong>file</strong> 19<br />
X = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"<br />
Y = Co<strong>di</strong>ce<br />
FOR i = ASC("Z") TO ASC("A") STEP -1<br />
IF INSTR(1, Y, CHR$(i)) = 0 THEN<br />
Y = Y + CHR$(i)<br />
END IF<br />
NEXT<br />
X = X + LCASE$(X) 'cosi` si hanno maiusc e m<strong>in</strong>usc<br />
Y = Y + LCASE$(Y)<br />
INPUT "Nome del <strong>file</strong> <strong>in</strong> output"; FileOUT<br />
OPEN FileOUT FOR OUTPUT AS #2<br />
DO WHILE NOT EOF(1)<br />
LINE INPUT #1, riga<br />
FOR i = 1 TO LEN(riga)<br />
posiz = INSTR(1, X, MID$(riga, i, 1))<br />
IF posiz 0 THEN 'per non tradurre le non lettere<br />
IF op = "c" THEN<br />
'cerca <strong>in</strong> X e mette <strong>in</strong> Y<br />
MID$(riga, i, 1) = MID$(Y, posiz, 1)<br />
ELSE<br />
'cerca <strong>in</strong> Y e mette <strong>in</strong> X<br />
posiz = INSTR(1, Y, MID$(riga, i, 1))<br />
MID$(riga, i, 1) = MID$(X, posiz, 1)<br />
END IF<br />
END IF<br />
NEXT<br />
PRINT #2, riga<br />
LOOP<br />
CLOSE (1)<br />
CLOSE (2)<br />
END