Programmazione Mod A - Cap 5 - prof. Burattini 1.

39
Programmazione Mod A - Ca p 5 - prof. Burattini 1

Transcript of Programmazione Mod A - Cap 5 - prof. Burattini 1.

Page 1: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

1

Page 2: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

2

La classe stream

Nel prossimo semestre introdurremo in modo più specifico i concetti di classe e oggetto; per il momento possiamo semplicemente affermare che

una classe è la definizione di un nuovo tipo, che include sia gli elementi che lo caratterizzano sia le operazioni eseguibili sugli elementi di quel tipo.

Supponiamo di dover lavorare con stringhe molto grandi; potremmo definire una nuova classe (cioè un nuovo tipo) che chiamiamo string1. I nostri programmi potranno contenere questo nuovo tipo, per cui possiamo dichiarare una variabile string chiamata grande scrivendo semplicemente

string grande;naturalmente dovremo definire su queste variabili tutte le operazioni già

definite per le stringhe.

La classe string avrà delle sue proprietà ( come inizializzazione, assegnazione, ….) e delle funzioni (dette metodi) che consentono di gestirla ( pensiamo, ad esempio, alle operazioni di confronto, concatenazione, sottostringa, …….).

Page 3: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

3

Il C++ contiene diverse librerie che permettono di utilizzare tipi che vanno al di là di quelli elementari (int, float, char, bool): tra queste le classi string ( di cui ci occuperemo in seguito) e stream.

La classe stream ( flusso ) è la base per l’I/O in C++.

Essa è formata da una sequenza di byte che fluiscono da un dispositivo all’altro, da cui il termine stream.

La sequenza di byte può fluire dalla tastiera alla memoria centrale del computer: abbiamo così l’input standard, l’oggetto cin, che è un oggetto stream.

Analogamente, l’oggetto cout rappresenta l’output standard, il flusso di dati dalla memoria centrale al monitor.

Agli oggetti cout e cin abbiamo applicato, rispettivamente, gli operatori di inserimento << e di estrazione >>, un po’ come accade ai numeri interi di tipo int a cui applichiamo gli operatori di incremento (++) e decremento (--).

Page 4: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

4

Questi oggetti possono essere gestiti da altri metodi (procedure e funzioni) cui si accede mediante il punto (.), che rappresenta la selezione di un metodo dell’oggetto; per esempio, per leggere una stringa s dalla tastiera scriviamo

cin.getline(s,100);

dove cin è l’oggetto, getline il metodo, s la variabile stringa letta dalla tastiera; il punto che separa cin da getline indica che quel metodo appartiene a

quell’oggetto.

Oltre agli oggetti cin e cout, il file <iostream> contiene anche l’ oggetto cerr ;

cerr è associato al dispositivo di errore standard per cui, se si verifica un errore di I/O, esso viene immediatamente notificato all’output standard (vedi esempio nel paragrafo successivo).

Anche i file sono dei flussi e quindi appartengono alla classe stream; la libreria

per la loro gestione è contenuta in <istream>, per quanto concerne l’input ed in <ostream> per l’output;

se si ha la necessità di eseguire funzioni di lettura e scrittura si può includere il file <fstream> che le contiene entrambe.

Page 5: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

5

I file di testo

File esterni : file immagazzinato in una memoria secondaria che possono essere utilizzati da più di un programma.

File di tipo testo: file che contengono un testo, cioè caratteri ASCII.

Nome del file fisico: il nome con cui il file è noto nell’ambiente del sistema operativo; di solito un file di testo ha estensione txt

Nome del file logico: il nome con cui il file è conosciuto dal programma; esso viene gestito come una zona di memoria temporanea ( un buffer ) su cui scrivere o leggere.

Un file di testo deve essere immaginato come una successione di caratteri leggibili, inframezzati dal carattere speciale <eoln> ( end of line ) che indica la fine di una linea di testo e terminante col carattere speciale <eof> ( end of file ) che indica la fine del file

Page 6: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

6

Supponiamo che il contenuto di un file di nome fisico prova.txt, che si trova sul disco rigido sia:

Nel mezzo del cammin di nostra vita<eoln>mi ritrovai in una selva oscura<eoln><eof>

Per scrivere questo testo è sufficiente utilizzare un qualsiasi editor (come lo stesso sistema di sviluppo DevCpp oppure Blocco Note sotto Windows: attenzione!! In quest’ultimo caso non aggiungere il suffisso txt, il programma lo aggiunge di default ).

Per gestire un file in un programma C++ occorre:

1) dichiarare una variabile di tipo ifstream per la lettura del file o di tipo ofstream per la scrittura del file ( tale variabile corrisponderà al nome logico del file)

2) aprire il file creando una corrispondenza tra nome fisico e nome logico del file

3) leggere o scrivere i dati nel file.

Page 7: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

7

Una volta creata la corrispondenza tra file fisico e file logico, il sistema operativo si occuperà di travasare i dati dall’uno all’altro.

Quando ordiniamo di scrivere sul file logico, i dati inviati vengono memorizzati temporaneamente in una zona di memoria temporanea connessa al file stesso. Nel momento in cui tale zona di memoria viene riempita oppure il file viene chiuso, allora il computer provvederà ad inviare tutti i dati al file fisico.

Analogamente, nella fase di lettura, il computer legge dal file fisico una quantità di dati tale da riempire il buffer (oppure legge tutti i dati del file se questi sono in quantità inferiore alla lunghezza del buffer); ogni istruzione di lettura successiva continuerà a leggere dati dal buffer finché esso non si svuota; a quel punto nuovi dati vengono prelevati dal file ed inseriti nel buffer per essere letti successivamente.

Page 8: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

8

Introduciamo, ora, le prime istruzioni necessarie alla gestione dei file.Cominciamo con le dichiarazioni: ifstream file1 ( per la lettura ) o ofstream file2 ( per la scrittura )

dove file1 e file2 sono identificatori, cioè nomi logici di due file, file1 è un oggetto della classe ifstream (stream di input), file2 un oggetto della classe ofstream (stream di output).

Queste classi hanno i seguenti metodi (procedure o funzioni):

nome-variabile.open (nome file fisico) ESEMPIO: file1.open(“prova1.txt”) (questa procedura crea un collegamento tra il nome logico file1 ed il file fisico

prova1.txt presente nella memoria secondaria del computer in uso);

si può dichiarare ed aprire direttamente con la seguente istruzione

ifstream file1(“prova1.txt”)

Page 9: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

9

La procedura close chiude il collegamento aperto con open tra il nome logico file1 ed il file fisico prova1.txt presente nella memoria secondaria del computer in uso:

nome-variabile.close () ESEMPIO: file1.close()

Due funzioni molto utili.

nome-variabile.eof() ESEMPIO: file1.eof()

restituisce true se tentiamo di leggere la fine del file, false altrimenti;

!(nome-variabile) ESEMPIO: if (!file1) ….

controlla se il file nome-variabile esiste, oppure è stato aperto correttamente.

Gli ultimi due metodi introdotti hanno senso sia per la lettura che per la scrittura di file.

Page 10: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

10

Per poter leggere una stringa da file basta scrivere

file1 >> stringa

Si utilizza l’operatore di estrazione per “estrarre” dati dal file;

ricordiamo, comunque, che tale operatore legge una stringa fin quando trova uno spazio o un carattere di fine linea o una tabulazione.

Il programma seguente utilizza diversi metodi applicati ai file. Esso legge i dati da un file di testo e li scrive sul monitor ( ci si può servire del testo scritto in prova.txt ).

Page 11: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

11

#include <iostream> // PROGRAMMA 5.1#include <cstdlib>#include <fstream>using namespace std;int main () { char Nomefile[20], parola1[10]; ifstream file; cout << "Nome File="; cin >> Nomefile; // nome file esterno conservato nella memoria secondaria file.open (Nomefile); // collegamento tra file (logico) e Nomefile(fisico) if (!file) //collegamento impossibile (file fisico inesistente) { cerr<<"Non si puo’ aprire il file"<<endl; system(“pause”); return -1;// esce dal main con errore ( restituisce un numero diverso da 0) } while (!file.eof()) // finché non si raggiunge la fine del file { file >>parola1; // leggi una parola dal file cout<< parola1<< " ";// scrivi la parola ed uno spazio sul monitor } file.close(); // chiudi il file system(“pause”); }

Page 12: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

12

Invece di verificare se si è giunti alla fine del file, si può controllare direttamente se esistono ancora parole da leggere con l’istruzione

file>>parola1In tal caso le istruzioni evidenziate in grassetto possono essere sostituite dalle

seguentiwhile (file>>parola1)cout<<parola1<<” “;

e vanno lette come

fin quando è possibile estrai dal file tutte le parole.

Questa modalità è quella più utilizzata nella lettura dei dati in C++.

Il file prova.txt contenente il testo

Nel mezzo del cammin di nostra vita<eoln>mi ritrovai in una selva oscura<eoln><eof>

ha sullo schermo il formato seguente

Nel mezzo del cammin di nostra vita mi ritrovai in una selva oscura

Page 13: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

13

Il programma legge parola per parola ( in quanto si ferma ad ogni spazio o fine riga );

l’istruzione cout << parola1 << “ “ pone uno spazio dopo ogni lettura della variabile parola1.

Ci proponiamo di scrivere due programmi, abbastanza simili a quello appena discusso, che leggono e stampano il file d’esempio prova.txt. Il primo legge e stampa sul video ogni singolo rigo, mentre il secondo esegue le stesse operazioni utilizzando il singolo carattere. Dal punto di vista dell’utente che guarda il risultato sul monitor del computer non cambia nulla: il secondo programma, infatti, invierà al video anche i caratteri non stampabili, come il ritorno a capo.

Il primo programma usa la procedura

Nome-variabile.getline(stringa,numero,carattere)

dove stringa è la stringa letta dal file, numero è il numero massimo dei caratteri letti, carattere è il carattere di terminazione; se quest’ultimo è omesso, allora s’intende per default il carattere di fine riga.

Page 14: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

14

ESEMPIO 1: file1.getline(rigo,100);

attende di leggere da file1 la variabile stringa rigo contenente al massimo 100 caratteri; la lettura termina alla fine del rigo ( fino a <eoln> ) o quando ha letto tutti i caratteri;

file1.getline(rigo,100,’@’);legge ancora la stringa rigo contenente al massimo 100 caratteri, ma la lettura

termina quando incontra il carattere ’@’.

ESEMPIO 2:while (file.get(ch))

cout.put(ch);utilizza i metodi get e put che rappresentano rispettivamente i puntatori di

lettura e di scrittura da file di un singolo carattere. Si esegue la stessa operazione di lettura e stampa precedente utilizzando, però,

il singolo carattere.

Page 15: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

15

#include <iostream> // PROGRAMMA 5.2

#include <cstdlib>#include <fstream>using namespace std;

int main () { char Nomefile[50], riga[100]; ifstream file; cout << "Nome File="; cin >>Nomefile; file.open (Nomefile); if (!file) { cerr<<"Non si puo’ aprire il file"<<endl; return -1; } while (!file.eof()) { file.getline(riga,100); cout<<riga<<endl; } file.close(); system(“pause”);}

PROGRAMMA 5.3

Il programma ha la stessa identica struttura di quello a lato; si differenzia semplicemente per il fatto che legge ogni singolo carattere ( compreso l’end-of-line ) invece della riga.L’unica differenza è nel riquadro che comprende il ciclo while.Una prima istruzione dichiara ch come carattere, mentre la successiva legge un carattere finché è possibile e poi lo scrive su cout.……………………………………………………

char ch;while (file.get(ch)) cout.put(ch);

………………………………………………………………………………

Page 16: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

16

In generale, un file di testo può essere letto con varie modalità. Supponiamo di aprire il file prova.txt il cui primo rigo è il seguente

N e l m e z z o d e l c a m m i n d i n o s t r a v i t a

Quando il file si apre per la lettura il puntatore si pone sotto il primo carattere; abbiamo la possibilità di eseguire tre tipologie di lettura:

leggiamo per parola (programma 5.1); in tal caso la parola letta conterrà “Nel” ed il puntatore di lettura si sposterà sulla parola successiva;

leggiamo per rigo (programma 5.2); in questo caso viene letto tutto il testo “Nel mezzo del cammin di nostra vita” contenuto nel primo rigo ed il puntatore di lettura si sposta sulla riga successiva;

leggiamo per carattere (programma 5.3); viene letto il carattere “N” ed il puntatore di lettura si sposta per leggere il carattere successivo.

eser5.1

eser5.1b

eser5.1c

Page 17: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

17

Esempio

Si abbia un file di tipo testo, prova01.txt, contenente le seguenti informazioni rispetto agli studenti di una certa università:

cognome e nome dello studente seguito dal simbolo di punto e virgola (;), numero di matricola, 4 numeri interi che rappresentano il voto dei primi 4 esami

(lo zero indica che l’esame non è stato superato )

Scrivere un programma che, assegnata una media M in input, stampi il cognome, nome e numero di matricola di tutti gli studenti che hanno una media maggiore o uguale ad M.

Supponiamo, ad esempio, che i dati inseriti nel file prova01.txt siano i seguentide Rossi Mario;13240 28 25 0 24<eoln>Caio Mario;15340 28 0 26 24Bianchi Antonio;12540 26 20 30 25Ferrara Ciro;13124 30 28 0 27

e che il valore di M in input sia 26, allora il programma deve stampare su videoCaio Mario 15340Ferrara Giulio 13124

Page 18: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

18

Per la risoluzione del problema iniziamo con un primo raffinamento:

Leggi(media int)Apri file prova01.txtwhile non arriva la fine del file

Leggi da file il nome e cognome fino al simbolo ‘;’Leggi da file la matricolaLeggi da file i 4 voti degli esami e calcola la loro media

Se la media calcolata è > di quella in input stampa cognome, nome e matricolaChiudi il file

Il raffinamento è già una soluzione, se si eccettua il passo

Leggi da file i 4 voti degli esami e calcola la loro media

Page 19: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

19

Secondo raffinamento:

media=0; Numero_voti=0;for (i=0; i<4; i++)

Leggi(file,voto) if (voto >0) media=media+ voto Numero_votiNumero_voti +1 If Numero_voti0 Media=media/Numero_voti

Il programma completo è riportato di seguito.

Page 20: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

20

#include <iostream>#include <fstream>#include <string>#include <cstdlib>using namespace std;int main () { char nome[30]; int matr, voto, Nvoti; float somma, InpMedia; ifstream file; cout << "Input Media="; cin >>InpMedia; file.open ("prova01.txt"); if (!file) { cerr<<"Non si può aprire il file"<<endl; system("pause"); return -1; } while (!file.eof()) { file.getline(nome,30,';'); file>>matr; somma=0; Nvoti=0; for (int i=0; i<4; i++) { file>>voto; if (voto>0) { somma+=voto; Nvoti++; } if (somma >0)&& (somma/Nvoti> InpMedia) cout<<nome<<" "<<matr<<endl; } file.close(); system("pause"); }

eser5.4

Page 21: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

21

Esercizi sui file di testo

1) Sia dato un file testo di nome fisico “studenti.txt“ contenente informazioni sugli studenti di un corso.

Il primo rigo contiene il nome dello studente seguito dal carattere ‘|’ da uno spazio e da un intero N indicante il numero di esami sostenuti.

Le N righe successive contengono le informazioni sugli esami sostenuti. Ognuna di queste righe è composta da un intero rappresentante il codice dell’esame sostenuto, un intero rappresentante il voto, e un intero rappresentante l'anno in cui l’esame è stato superato.

Dati un intero C rappresentante un codice d’esame, un intero M rappresentante un voto ed un intero N rappresentante un anno, scrivere un algoritmo che dia in output il nome degli studenti che hanno sostenuto l’esame di codice C prima dell'anno N con un voto>=M.

Esempio Studenti.txtMarco Rossi| 3<eoln>3070 26 2001<eoln>3080 24 2002<eoln>3090 25 2000<eoln>Antonio Sassi| 1<eoln>3070 27 2002<eoln>Input Output3070 24 2002 Marco Rossi

Page 22: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

22

2) Un file testo “parole.txt” contiene, per ogni riga, una serie di parole, ognuna delle quali è seguita da uno spazio o dal carattere <eoln>. Ogni parola è costituita da caratteri alfabetici e può essere composta da sole lettere maiuscole, sole lettere minuscole o da entrambe.

Scrivere una procedura che legga il file “parole.txt” e costruisca due file. Nel primo file andranno inserite, una per riga, le parole contenenti solo lettere

maiuscole; nel secondo andranno inserite, sempre una per riga, le parole contenenti solo lettere minuscole. Le parole contenenti sia lettere maiuscole che lettere minuscole non andranno memorizzate.

Esempio del file “parole.txt”CASA libro DADO trENo <eoln>mattone penna AUTO <eoln>ROSA acqua raDIo <eoln><eof>Il primo file sarà: Il secondo file sarà:CASA<eoln> libro<eoln>DADO<eoln> mattone<eoln>AUTO<eoln> penna<eoln>ROSA<eoln><eof> acqua<eoln><eof>

Page 23: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

23

3) Sia dato un file testo “parole.txt” composto da sole lettere maiuscole. Ogni linea di testo è costituita da un carattere seguito da uno spazio e da una serie di parole tutte separate da uno spazio (compreso l’ultima).

Tutte le parole di un rigo dovrebbero iniziare o terminare con il carattere di inizio riga.

Scrivere una procedura che legga il file “parole.txt” e stampi a video tutte le parole che non verificano la condizione suddetta.

Esempio del file “parole.txt”M MONDO MARE <eoln>O AGO NERO OTTOBRE <eoln>P PANE PERA <eoln>A CASA <eoln><eof>In questo caso non deve essere stampata alcuna parola.Esempio del file “parole.txt”M MONDO GARE <eoln>O OCA POLLO <eoln>P PANE SERA <eoln>F GATTO <eoln><eof>In questo caso devono essere stampate le parole: GARE, SERA, GATTO

Page 24: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

24

4) Siano dati due file testo: studenti.txt e tesi.txt. Il primo contiene informazioni riguardanti tutti gli studenti di un corso di laurea; il secondo contiene informazioni riguardanti i soli studenti del medesimo corso di laurea che hanno già fatto richiesta della tesi.

Le informazioni per ogni studente sono così strutturate:Studenti.txt

Entrambi i file sono ordinati per numero di matricola crescente.Scrivere una procedura che mostri a video la matricola e la media di tutti gli

studenti che hanno richiesto la tesi e che hanno svolto tutti gli esami.

Studenti.txt

Matricola (intero)<eoln>Cognome e nome<eoln>Esami sostenuti (intero) Esami da sostenere (intero)<eoln>Nome esame sostenuto^ voto (intero)<eoln>…Nome esame sostenuto^ voto (intero)<eoln>

Tesi.txt

Matricola (intero)<eoln>Cognome e nome<eoln>

Page 25: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

25

ESEMPIO

Studenti.txt

4010<eoln>Rossi Marco<eoln>18 0<eoln>…Nome esame sostenuto^ 26<eoln>4050<eoln>Antonio Neri<eoln>10 8<eoln>…Nome esame sostenuto^ 22<eoln>4060<eoln>Bianchi Matteo<eoln>16 2<eoln>…Nome esame sostenuto^ 23<eoln><eof>

Tesi.txt

4010<eoln>Rossi Marco<eoln>4060<eoln>Bianchi Matteo<eoln><eof>

L’output sarà: 4010 seguito dalla media

Page 26: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

26

La classe string: operazioni e proprietà

Ricordiamo che il tipo stringa, introdotto insieme agli array, non è altro che un array di caratteri.

Abbiamo notato come questo tipo sia poco maneggevole.

Infatti, abbiamo dovuto introdurre delle procedure ad hoc per il confronto tra stringhe e per il calcolo della loro lunghezza (ricordiamo che le stringhe viste come array di carattere terminano con il carattere nullo’\0.

La classe string, contenuta nella libreria standard, consente una gestione molto più semplice delle stringhe.

Page 27: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

27

Per poter utilizzare il tipo string è necessario includere il file string:

#include <string> Si può definire ed iniziare a leggere una stringa in vari modi:

string S1 ; // S1 è una variabile stringa

string S2= “ciao mamma”; // S2 è una variabile stringa inizializzata con il valore “ciao mamma”

string S3 =””; // S3 è una stringa vuota

string S4 (“saluti”); // S4 è una stringa inizializzata con il valore “saluti”

string S5 (S4); // S5 è una stringa inizializzata con il valore di S4 (ancora”saluti”)

Page 28: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

28

Si può leggere la stringa S1 da tastiera con le istruzioni

cin >> S1; //l’inserimento termina con lo spazio, il tasto Tab o Invio

cin.getline (S1,N) ; // l’inserimento termina soltanto con il tasto Invio (è possibile inserire spazi tra le parole); si leggono

al massimo N caratteri.

cin.getline (S1,N, car); // l’inserimento termina quando si inserisce il carattere car (se l’ultimo parametro car non

viene inserito, usa il tasto Invio come default)

Le stringhe definite col tipo string sono generate dinamicamente (non è necessario definire una lunghezza massima), a differenza delle stringhe che vengono definite come array di caratteri; esse, inoltre, possono essere confrontate e concatenate:

String S1 = “ciao”, String S2 “mamma” possiamo scrivere S1=S1+S2 o S1+=S2 ottenendo in tutti i casi la stringa

“ciao mamma “ contenuta in S1

Page 29: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

29

s [i] Restituisce il carattere di indice i ( se i>= della lunghezza della stringa, il risultato è indefinito

s.size ( ) Restituisce la lunghezza di ss.empty ( ) Restituisce true se s è vuota, false altrimentis.find( c ) Restituisce l’indice della prima occorrenza di cs.find (str) Restituisce l’indice del primo carattere della prima

occorrenza di strs.rfind ( c ) Come s.find( c ), solo che la ricerca ha inizio dalla fines.rfind (str) Come s.find(str), solo che la ricerca ha inizio dalla fines.replace (i, n, str) Sostituisce n caratteri, a partire dalla posizione i, con la

stringa str.s.insert (i, str) Inserisce la stringa str a partire dalla posizione is.erase (i, n) Elimina n caratteri a partire dalla posizione is.resize (n,car) Fissa a n la lunghezza di s; gli altri caratteri fino alla

lunghezza della stringa sono riempiti con il carattere cars.c_str ( ) Restituisce la stringa corrispondente in stile Cs.substr (i,n) Restituisce una stringa che parte dalla posizione i ed ha

lunghezza n; per esempio se s=”ciao mamma”, s.substr(5,5) restituisce la stringa “mamma”

Page 30: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

30

Scriviamo un programma che ci aiuti a comprendere l’uso dei metodi del tipo string nella pratica.

Sia assegnato un file contenente un testo in cui alcune parole sono poste tra parentesi quadre [ ].

Si richiede di generare altri due file: il primo conterrà 4 puntini al posto di ogni parola tra parentesi quadre, il secondo conterrà tutte le parole eliminate inserite nello stesso ordine in cui compaiono nel file iniziale.

I due file generati devono avere un nome fisico dato dal nome del file iniziale a cui va aggiunto rispettivamente “01” e “02”.

Page 31: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

31

Esempio.Supponiamo che il file di nome testo, senza estensione, abbia il seguente

contenuto:

Il programma deve creare due file, il primo di nome testo01 ed il secondo testo02:

testo01 testo02

Anche i file sono dei flussi e quindi appartengono alla classe ....; la libreria per la loro gestione é contenuta in <....>, per quanto concerne l'input ed in <....> per l'output; se si ha la necessità di eseguire funzioni di lettura e scrittura si puo' includere il file <....> che le contiene entrambe.

streamistreamostreamfstream

Anche i file sono dei flussi e quindi appartengono alla classe [stream]; la libreria per la loro gestione é contenuta in <[istream]>, per quanto concerne l'input, ed in <[ostream]> per l'output; se si ha la necessità di eseguire funzioni di lettura e scrittura si puo' includere il file <[fstream]> che le contiene entrambe.

Page 32: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

32

Il primo raffinamento dell’algoritmo risolutivo è il seguente:

Leggi(NomeFile)

Apri Nomefile in lettura

Apri NomeFile1 e NomeFile2 in scrittura

while non si raggiunge la fine del file

Leggi( rigo dal file)

S3 rigo

while non si raggiunge la fine di S3

J posizione della parentesi quadra aperta

K posizione di lettura sul rigo

If J>0

I posizione della parentesi quadra chiusa

If I>0

S2 tutto il contenuto incluso tra le due parentesi

quadre

Scrivi S2 su NomeFile2

Rimpiazza nella stringa S3 tutto il contenuto incluso

tra

le due parentesi quadre con 4 punti

Scrivi S3 su NomeFile1

Page 33: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

33

L’algoritmo può essere facilmente tradotto in C++ utilizzando diversi metodi della classe string senza la necessità di ulteriori raffinamenti.

Prima di scrivere il programma osserviamo che:

• il nome del file fisico deve essere del tipo array di char;

• la funzione c_str() applicata ad una stringa di tipo string restituisce una stringa come array;

• la stringa letta dal file deve essere una stringa di tipo array;

• vengono utilizzati diversi metodi.

Page 34: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

34

#include <iostream>#include <fstream>#include <cstdlib>using namespace std;int main () { string Nome1,Nome2, s01, s02, s2, s3; char rigo[120]; int i,j,k; ifstream fil1; ofstream fil01, fil02; cout << "Nome File="; cin >> Nome1; Nome2=Nome1+".txt"; fil1.open(Nome2.c_str()); s01=Nome1+"01"; s02=Nome1+"02";// creazione dei nomi dei file di output fil01.open(s01.c_str()); fil02.open(s02.c_str()); if (!fil1) { //controlla se il file esiste cerr<<"Non si può aprire il file"<<endl; system("pause"); return -1; }

fil02

fil1

fil01

Anche i file sono dei flussi e quindi appartengono alla classe [stream]; la libreria per la loro gestione é contenuta in <[istream]>,…..

Anche i file sono dei flussi e quindi appartengono alla classe […….. ]; la libreria per la loro gestione é contenuta in <[……..]>,…..

streamistream…………

Page 35: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

35

//l'algoritmo presentato nel primo raffinamento a partire da:// Finché non si raggiunge la fine del file while (!fil1.eof()) { fil1.getline(rigo,100); s3=rigo; k=0;// Finché non si raggiunge la fine del rigo while (k!=s3.size()) { j=s3.find('['); k=j+1; if (j>=0) { i=s3.find(']'); k=i+1; if (i>0) { s2=s3.substr(j+1,i-j-1);

fil02<<s2<<endl; s3.replace(j, i-j+1,"...."); }

} else k=s3.size(); } fil01<<s3<<endl; // scrivo s3 su fil01 }

fil02

fil1

fil01

Anche i file sono dei flussi e quindi appartengono alla classe [stream]; la libreria per la loro gestione é contenuta in <[istream]>,…..

Anche i file sono dei flussi e quindi appartengono alla classe […….. ]; la libreria per la loro gestione é contenuta in <[……..]>,…..

streamistream…………

// termine algoritmo fil1.close(); // chiusura dei file fil01.close(); fil02.close(); system("pause");}

Page 36: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

36

…………………………………………………………………………………………………………………………………… in <[istream]>, per quanto concerne l'input, ed in <[ostream]> ……………………………………………………………………………………………………………………………………

j

k

i

k

j

i

k k

eser5.5

Page 37: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

37

Template di funzioni.

Durante questo corso abbiamo sottolineato l’aspetto astratto della programmazione; spesso abbiamo introdotto delle procedure, scritte nel linguaggio di progetto, che consentono di risolvere problemi generali che si riferiscono a tipi generici.

Assegnato un certo vettore v è semplice scrivere delle funzioni che lo leggono da tastiera, lo stampano sul video, ne calcolano il minimo ed il massimo, lo moltiplicano per uno scalare, e così via.

Ebbene, poiché possiamo avere vettori di interi, reali, caratteri, stringhe, ecc. per ognuno di essi dobbiamo introdurre una function distinta: avremo una function che legge da tastiera un vettore di interi, un’altra che legge un vettore di reali, e così via.

Invece di scrivere tre funzioni distinte il C++ ci permette in questi casi di dichiarare e definire una sola funzione abbastanza generale da accettare tipi di dato diversi (ma sui quali opera allo stesso modo) .

Una tale dichiarazione sarà detta un template di function.

Page 38: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

38

La sintassi da utilizzare richiede la parola chiave template seguita dalla parola class, posta tra i tag < class tipo> dove la variabile tipo rappresenta il tipo; subito dopo segue la definizione della funzione:

template <class Tipo>Tipo minimo (Tipo v[], int n) { int i,h=0; for (i=1; i<n; i++) { if (v[i]<v[h]) h=i; } return v[h]; }

Supponiamo di richiamare la funzione con S1:=minimo(S, 10)dove S è un vettore che contiene al massimo 10 stringhe; ebbene, la funzione restituirà il valore minimo del tipo adatto, una stringa. La funzione controllerà soltanto la coerenza tra il Tipo restituito ed il Tipo di cui è composto l’array.Ovviamente, se x è un numero reale double e D è un array di double, la chiamata di funzione x:=minimo(D, 10)restituisce in x il minimo dell’array D di double.

Page 39: Programmazione Mod A - Cap 5 - prof. Burattini 1.

Programmazione Mod A - Cap 5 - prof. Burattini

39

Il programma seguente mostra l’utilizzo dei Template con funzioni e procedure.

#include <iostream>#include <cstdlib>#include <string.h>using namespace std;template <class Tipo>void leggi (Tipo[], int);template <class Tipo>Tipo minimo (Tipo[], int);int main () { int a[5], n; string s[5]; cout<<" Lunghezza vettore intero ="; cin>>n; leggi(a, n); cout<<"Il minimo del vettore intero è "<<minimo(a, n)<<endl; cout<<" Lunghezza vettore stringa ="; cin>>n; leggi(s, n); cout<<"Il minimo del vettore stringa è "<<minimo(s, n)<<endl; system("pause"); }// continua a lato

template <class Tipo>void leggi (Tipo v[], int n) { int i; for (i=0; i<n; i++) { cout<<"vettore["<<i<<"]="; cin>>v[i]; } }template <class Tipo>Tipo minimo (Tipo v[], int n) { int i,h=0; for (i=1; i<n; i++) { if (v[i]<v[h]) h=i; } return v[h]; }

eser5.6