Archivi sequenziali in C++. Esercizio “Rubrica telefonica”.

VERSIONE A

Realizzare un programma in C++ che utilizza un file di testo per memorizzare una rubrica telefonica. Ogni riga del file deve contenere il cognome, il nome e il numero di telefono di un contatto, separati da uno spazio. (Nota: si adotterà l’ipotesi semplificativa che i cognomi, i nomi e i numeri di telefono, siano composti da una stringa di caratteri senza spazi e/o tabulazioni). All’avvio il programma deve permettere di aggiungere nuovi contatti e dare la possibilità di interrompere gli inserimenti con la digitazione di uno zero in corrispondenza della prima richiesta di input di un nuovo contatto. Successivamente all’interruzione degli inserimenti, deve visualizzare a video il contenuto della rubrica.

(Soluzione proposta)

Il problema può essere scomposto nei seguenti sotto-problemi:

rubrica

e il programma può essere così organizzato:

La funzione void inserisciContatti(string) richiede come parametro la stringa del pathname del file della rubrica telefonica e si occupa degli inserimenti dei nuovi contatti, fintanto che l’utente non li interrompe digitando lo zero al posto del cognome;

La funzione void visualizzaRubrica(string) richiede come parametro la stringa del pathname del file della rubrica telefonica e si occupa di visualizzare a video l’intera rubrica telefonica.

Questo programma non funziona se si tenta di inserire un contatto che abbia il cognome e/o il nome composti da più di una parola. Infatti, l’operatore di lettura (>>) che abbiamo utilizzato per leggere in input i dati dei contatti, nel leggere lo stream di input si ferma quando incontra uno spazio (oltre che, ovviamente, la tabulazione e l’invio).  Questo problema viene risolto nella VERSIONE B dell’esercizio.

VERSIONE B

Migliorare il programma precedente in modo da rendere possibile la registrazione di cognomi, nomi e numeri di telefono composti anche da stringhe di caratteri contenenti spazi e/o tabulazioni.

(Soluzione proposta)

E’ evidente che per risolvere questo problema è necessario cambiare l’organizzazione logica dei dati. In particolare, se vogliamo rendere possibile anche l’inserimento di cognomi, nomi e numeri di telefono contenenti spazi e/o tabulazioni, è necessario utilizzare come separatore di campo un carattere speciale diverso dallo spazio. Spetta al programmatore decidere quale scegliere fra i caratteri non utilizzati nell’input di un nuovo contatto. Potremmo pensare per esempio di utilizzare il punto e virgola, in modo da ottenere un file nel formato CSV che, come spiegato in altri articoli (link articolo1, link articolo2), può essere utilizzato anche per esportare la rubrica in un foglio elettronico come Excel o Calc di OpenOffice. Inoltre, se vogliamo che gli input del cognome e del nome avvengano correttamente, sappiamo, è necessario realizzarlo con una getline() e non con l’operatore di lettura (>>), in modo da includere nell’input anche gli spazi di separazione fra le eventuali più parole che compongono il cognome e/o nome e/o il numero di telefono. La funzione getline() è stata già introdotta in un altro articolo (link articolo).

Pertanto, rispetto al programma della VERSIONE A, la  funzione void inserisciContatti(string) diventa:

e la funzione void visualizzaRubica(string) va così modificata:

Sono state evidenziate in giallo le righe in cui sono state apportate delle modifiche rispetto alla VERSIONE A.