02.06.2013 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!