OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono:...

23
OPERAZIONI CON STRINGHE ioni più interessanti da fare, per ora, con le stri re la lunghezza della stringa, cioè quanti caratter re insieme più stringhe. one length(Stringa) restituisce la lunghezza della amo di avere uno spazio di 80 caratteri e vogliamo to spazio la scritta ‘SONO AL CENTRO’ tringaDaMostrare:= ‘SONO AL CENTRO’; pazi:=(80-length(StringaDaMostrare)) DIV 2; riteln(‘ ‘:Spazi, StringaDaMostrare); |………………………SONO AL CENTRO………………………| length

Transcript of OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono:...

Page 1: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

OPERAZIONI CON STRINGHE

Le operazioni più interessanti da fare, per ora, con le stringhe sono:determinare la lunghezza della stringa, cioè quanti caratteri contiene,concatenare insieme più stringhe.

La funzione length(Stringa) restituisce la lunghezza della stringa.

EsempioSupponiamo di avere uno spazio di 80 caratteri e vogliamo centrarein questo spazio la scritta ‘SONO AL CENTRO’

StringaDaMostrare:= ‘SONO AL CENTRO’;Spazi:=(80-length(StringaDaMostrare)) DIV 2;writeln(‘ ‘:Spazi, StringaDaMostrare);

|………………………SONO AL CENTRO………………………|

length

Page 2: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

CONCATENAZIONE

+concat

Esempio‘Teresa’ ‘ e ’ ‘Giacomo’

‘Teresa’ + ‘ e ’ + ‘Giacomo’

Teresa e Giacomo

Page 3: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

La stringa può essere vista come un ARRAY.

TYPE Stringa=STRING[Lunghezza]

UnaStringa:Stringa

Allora SONO QUI si presenta così

UnaStringa[3] = NUnaStringa[7] = U

S O N O Q U I1 2 3 4 5 6 7 8

Page 4: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

ESEMPIO

Trasformare una stringa qualunque in una stringa tutta maiuscolo.

PROCEDURE MinMaius(VAR UnaStringa: Stringa);{trasforma una stringa tutta in maiuscolo }VAR Posizione: integer; {posizione del carattere nella stringa}BEGIN FOR Posizione:=1 TO length(UnaStringa) DO

UnaStringa[Posizione]:=Maiuscolo(UnaStringa[Posizione])END;

FUNCTION Maiuscolo(Carattere:char):char;

BEGINIF Carattere IN [‘a’..’z’] THEN

Maiuscolo:=chr(ord(Carattere) + ord(’A’) - ord(‘a’))ELSE

Maiuscolo:=CarattereEND;

Page 5: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

Algoritmo per leggere stringhe e numeri da un file testo

Problema:Dato un file testo in cui ci sono una stringa di caratteri e numeri si vuole separare la stringa dai numeri e fare delle operazioni suquesti ultimi.

In fase di scrittura del file non imponiamo una lunghezza fissa allestringhe in lettura ma conveniamo di indicare la fine della stringa con un carattere sentinella ad esempio ‘^’.Imponiamo invece la lunghezza massima del rigo.

EsempioVerdi Carlo^ 30 29 28 30Esposito Franco^ 25 27 29 30Verdi Carlo^ 30 29 28 30Esposito Franco^ 25 27 29 30

1 40

Page 6: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

Pseudocodice

{leggi i caratteri finchè non incontri la sentinella e concatenali in una stringa}•Sentinella ‘^’ {Inizializza il carattere sentinella}•UnaStringa ‘’ {Inizializza la stringa con la stringa nulla ‘’}•read(InFile,Carattere)•WHILE Carattere <> Sentinella DO

•UnaStringa UnaStringa + Carattere•read(InFile,Carattere)

In generale bisogna controllare:• se il carattere è la sentinella• se il numero di caratteri letti e accumulati nella stringa sono <= della lunghezza massima permessa alla stringa• se siamo a fine rigo, cioè se il prossimo carattere è eoln

Pseudocodice

IF NOT eoln(UnFile) AND NOT (lenght(Stringa)=MaxLung) THEN

ELSECarattere Sentinella

WHILE Carattere <> Sentinella DOBEGIN

read(UnFile,Carattere) UnaStringa UnaStringa + Carattere

END;

Page 7: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE LeggiUnRigo(Sentinella: char; VAR UnaStringa: StringaNome; VAR InFile:text);VAR Carattere: char;BEGIN UnaStringa:=''; {inizializza con stringa nulla}

IF NOT eoln(InFile) THENBEGINread(InFile,Carattere)END

ELSECarattere:=Sentinella;

WHILE (Carattere<>Sentinella) DO BEGIN UnaStringa:=UnaStringa+Carattere; IF NOT eoln(InFile) AND (length(UnaStringa)<>

LunMassima) THEN BEGIN

read(InFile,Carattere) END

ELSECarattere:=Sentinella

ENDEND;

Page 8: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

ESEMPIO 9.2

Problema:Si hanno i dati relativi a M esami fatti da N studenti.Vogliamo leggere questi dati e per ogni studente fare la media.Il file di dati si presente così:

5 4Rossi Carlo^ 30 28 18 25Rossi Lucio^ 18 25 22 21Bianchi Ugo^ 18 18 18 18Verdi Carlo^ 30 29 28 30Esposito Franco^ 25 27 29 30

Al primo rigo sono segnati il numero N degli studenti e il numero Mdi esami.Nei righi successivi ci sono i dati. Ogni stringa che identifica lo studenteè terminata con il carattere ‘^’.

Output atteso

Rossi Carlo ha una media di 24.5 su 4 test. Rossi Lucio ha una media di 28.25 su 4 test. Bianchi Ugo ha una media di 22.3 su 4 test. Verdi Carlo ha una media di 21.5 su 4 test. Esposito Franco ha una media di 26.2 su 4 test.

Page 9: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROGRAM EsamiTest(output,Risultati);CONSTSentinella='^';LunMassima=40;TYPEStringaNome=STRING[LunMassima];VARRisultati: text;NumeroStudenti,TotaleStudenti,TotaleTest: integer;PROCEDURE Inizializza(VAR Risultati: text; VAR TotaleStudenti,TotaleTest: integer);BEGIN ………….. END;PROCEDURE LeggiRigo(Sentinella: char; VAR Nome:StringaNome; VAR

Risultati:text);BEGIN ……………………….END;

PROCEDURE MostraStudente(TotaleTest:integer;VAR Risultati:text);BEGIN ……………………………… END;{************************** }BEGINInizializza(Risultati,TotaleStudenti,TotaleTest);FOR NumeroStudenti:=1 TO TotaleStudenti DO BEGIN MostraStudente(TotaleTest,Risultati) END; readlnEND.

Page 10: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE Inizializza(VAR Risultati: text;

VAR TotaleStudenti,TotaleTest: integer);

BEGIN

assign(Risultati,'C:\TP\ESEMPI\STUDENT1.TXT');

reset(Risultati);

readln(Risultati,TotaleStudenti,TotaleTest)

END;

PROCEDURE LeggiRigo(Sentinella: char; VAR Nome:StringaNome; VAR

Risultati:text);

VAR

Carattere: char;

BEGIN

Nome:=''; {inizializza con stringa nulla}

read(Risultati,Carattere);

WHILE (Carattere<>Sentinella) DO

BEGIN

Nome:=Nome+Carattere;

read(Risultati,Carattere);

ENDEND;

Page 11: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE MostraStudente(TotaleTest:integer;VAR Risultati:text);

VAR

Somma,ContoTest,Punteggio: integer;

Nome: StringaNome;

BEGIN

LeggiRigo(Sentinella,Nome,Risultati);

Somma:=0;

FOR ContoTest:=1 TO TotaleTest DO

BEGIN

read(Risultati,Punteggio);

Somma:=Somma+Punteggio

END;

readln(Risultati); {non ci sono altri risultati sul rigo}

write(Nome, ' ha una media di ');

writeln(Somma/TotaleTest:4:2, ' su ',TotaleTest:1,' test')

END;

Page 12: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

ESEMPIO 9.3

Supponiamo di dover introdurre delle scritte di controllo in un programma che non funziona. Dopo aver trovato l’errore vogliamo eliminare le scritte di controllo rapidamente.Mettiamo davanti ad ogni scritta di controllo una sentinella uguale per tutte le scritte.

{D} writeln(Variabile1,’Testo’,…);WHILE ….. DO ………………….

{D} writeln(Variabile1,’Testo’,…);FOR ….. TO

………………….{D} writeln(Variabile1,’Testo’,…);

Problema:

Scrivere un programma tale che

permette di eliminare da un file indicato

dall’utente tutti i righi preceduti dalla

stringa {D} riscrivendo su un nuovo file

solo i righi non preceduti da {D}.Pseudo-codice

ApriFile(InFile,OutFile),

WHILE NOT eof(InFile) DO

CreaRigo(InFile,OutFile)

close(InFile)

close(OutFile) ApriFile: apre i file

CreaRigo :decide se copiare o meno il rigo

letto a seconda che sia o meno preceduto da

{D}

Page 13: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROGRAM Diagnostico(input, output, InFile, OutFile);{elimina dal file InFile tutti i righi preceduti da {D} e lo riscrive

cosi’ corretto in OutFile }CONST Sentinella='{D}'; LunMass=80;TYPETipoStringa=STRING[LunMass];VAR InFile, OutFile: text;{ --------------------------- }PROCEDURE LeggiNomeFile(VAR NomeFile:TipoStringa;VAR UnFile:text);BEGIN …………………….. END;PROCEDURE ApriFile(VAR InFile,OutFile:text);BEGIN …………………. END;PROCEDURE PrendiRigo(Spazio: char; VAR StringaRisultante: TipoStringa; VAR Infile:text);BEGIN …………………………. END;PROCEDURE CreaRigo(VAR InFile,OutFile: text);BEGIN ………………………………………………. END;{ ********* BODY ********* }BEGIN

ApriFile(InFile,OutFile);writeln(' Sto copiando il file .........');WHILE NOT eof(InFile) DO CreaRigo(InFile,OutFile);

close(InFile); close(OutFile); writeln(' FINE LAVORO');readlnEND.

Page 14: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE LeggiNomeFile(VAR NomeFile:TipoStringa;VAR UnFile:text);

{ legge i nomi dei file }

BEGIN

writeln;

readln(NomeFile);

assign(UnFile,NomeFile)

END;

PROCEDURE ApriFile(VAR InFile,OutFile:text);

{ apre i file }

VAR

NomeFile: TipoStringa;

BEGIN

write('Elimina i righi preceduti da {D}, dal file: ');

LeggiNomeFile(NomeFile,InFile);

write('Dammi il nome che vuoi attribuire al file corretto: ');

LeggiNomeFile(NomeFile,OutFile);

reset(InFile);

rewrite(OutFile)

END;

Page 15: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE PrendiRigo(Spazio: char; VAR StringaRisultante: TipoStringa;

VAR Infile:text);

{ prende la prima stringa presente sul rigo - si suppone che la

sentinella {D} si trovi a inizio rigo}

VAR

Carattere:char;

BEGIN

StringaRisultante:='';

IF NOT eoln(InFile) THEN

Read(InFile,Carattere)

ELSE

Carattere:=Spazio;

WHILE Carattere<>Spazio DO

BEGIN

StringaRisultante:= StringaRisultante+Carattere;

IF NOT eoln(InFile) THEN

Read(InFile,Carattere)

ELSE

Carattere:=Spazio

END

END;

Page 16: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

PROCEDURE CreaRigo(VAR InFile,OutFile: text);{copia tutti i righi da InFile a OutFile purchè senza sentinrlla}VARPrimo, Resto: TipoStringa;BEGIN

PrendiRigo(' ',Primo,InFile);readln(InFile,Resto);IF Primo<>Sentinella THENwriteln(OutFile,Primo+' '+Resto);

END;

{ ******** BODY ******** }BEGIN

ApriFile(InFile,OutFile);writeln(' Sto copiando il file .........');WHILE NOT eof(InFile) DO CreaRigo(InFile,OutFile);

close(InFile); close(OutFile); writeln(' FINE LAVORO');readlnEND.

Page 17: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

AVVERTENZE E SUGGERIMENTI

• usare sempre dei Nomi di Variabile per accedere al contenuto dei file, mai direttamente il nome reale

• usare sempre close dopo avere utilizzato dei file in letture o scrittura. In scrittura è obbligatorio pena la perdita di dati o danni maggiori.

• nei vari dialetti l’apertura e la chiusura può essere diversa

• quando si legge un file assicurarsi sempre di controllare l’eof altrimenti il programma va in errore

Page 18: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

• non usare mai REPEAT ………… UNTIL per controllare eof o eoln.

eof ?

elabora

SI

NO

REPEAT

UNTIL

eof ?

elabora

NO

SI

WHILE NOT eoln DO

REPEATREPEATread(UnFile, Qualcosa)elabora(Qualcosa)UNTIL eoln(UnFile)readln(UnFile)

UNTIL eof(UnFIle)VA IN CRASH SE IL FILE E’ VUOTO

Page 19: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

eolns p a

eolna

eolns p a

ap

eolns p a

psread

WHILE NOT eoln DO elabora read(Carattere)ENDreadln:

L’ultimo carattere non viene elaboratoperché si esce prima dal loop.

Page 20: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

WHILE NOT eoln DO read elabora

eolns p a

eolns p a

ps

eolns p a

eolna

Page 21: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

Supponiamo di avere un ciclo per elaborare o una linea di dati oppure che esca sulla base di un carattere sentinella.

read(unFile, UnValore)WHILE NOT eoln(UnFile) AND NOT (UnValore è una sentinella) DO elabora read(unFile, UnValore)

Funziona bene se esce per la presenza della sentinella

Funziona male se esce per la presenza del eoln

Supponiamo di avere sempre un ciclo per elaborare o una linea di dati oppure che esca sulla base di un carattere sentinella.

WHILE NOT eoln(UnFile) AND NOT (UnValore è una sentinella) DO read(unFile, UnValore) elabora

Funziona male se esce per la presenza della sentinella

Funziona bene se esce per la presenza del eoln

Page 22: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

IF NOT eoln(UnFile) THEN read(unFile, UnValore)

ELSEUnValore sentinella

WHILE NOT (UnValore è una sentinella) DOelabora

IF NOT eoln(UnFile) THEN read(unFile, UnValore)

ELSEUnValore sentinella

CODICE CORRETTO

Page 23: OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.

Quando in un file ci sono numeri che devono essere letti, fareattenzione che gli eoln siano messi accanto alla fine del numeroe non preceduti da uno spazio.

Esempio:44 55 69 <eoln>

33 68 98 45 87<eoln)

In questo caso non vengono letti due righi di 3 e 5 numeri ma un solo rigo di 8 numeri, perché dopo avere letto 69 poiché c’è uno spazionon legge <eoln> ma va a leggere direttamente il numero successivo

WHILE NOT eoln(InFile) DO BEGIN

read(InFile, Numero);elabora(Numero)

END;readln(InFile)

SBAGLIATO!!!