Archivi sequenziali in C++. Esercizi con il formato CSV.

In un altro articolo abbiamo già parlato dei file sequenziali nel formato CSV (link articolo). Con questo articolo vediamo com’è possibile manipolare in C++ i file di questo formato. Supponiamo di avere il file anagrafica.csv della fig. [1] seguente, ottenuto dall’esportazione nel formato CSV della tabella del foglio di lavoro di Excel della fig. [2], seguendo il procedimento descritto nell’articolo precedente.

csv-c

Esempio 1

Con questo semplice esempio vogliamo estrarre i record del file anagrafica.csv e visualizzarli a video nel modo seguente:

Nel file anagrafica.csv ciascuna riga rappresenta un record e in essa ciascun campo termina con un punto e virgola. Per estrarre i record, quindi, si può procedere con una lettura sequenziale di una riga per volta, utilizzando la funzione getline(), fino ad arrivare alla fine del file. In ciascuna riga letta, per estrarre i campi si può procedere con l’estrazione sequenziale delle sottostringhe chiuse dal carattere separatore ‘;’, fino ad arrivare alla fine della riga. Ciò può essere ottenuto in C++ nel modo seguente. Scelgo di lavorare con le stringhe in stile C++ e per l’estrazione delle sottostringhe dei campi sfrutto i metodi degli oggetti di classe string che abbiamo trattato in un altro articolo (link articolo).

Esempio 2-A

In questo secondo esempio si vogliono estrarre i record del file anagrafica.csv e scriverli in un file di testo di nome tabella_clienti.txt in un formato tabellare più adatto per la visualizzazione e la stampa, come quello mostrato nella figura di sotto.

tabella-clienti

La logica di questo secondo programma è identica a quella del programma del primo esempio. Questa volta però i record estratti dal file anagrafica.txt non devono essere stampati a video ma scritti in un file, ossia lo stream dell’output non deve riguardare la periferica di output standard  (il monitor), come nel primo esempio, ma un file di testo di nome tabella_clienti.txt.

Nella funzione stampaRigaSuFile() sono state evidenziate in giallo due righe.

  • La prima per porre l’attenzione sulla sintassi di un parametro formale rappresentato da un oggetto associato ad uno stream su file: fstream& nomeFile. Si ricorda, infatti, che il nome di un oggetto è una variabile di tipo riferimento che, quindi, contiene l’indirizzo dell’oggetto a cui fa riferimento.
  • La seconda per evidenziare che per formattare le righe in modo che i campi siano visualizzati perfettamente incolonnati nella tabella del file tabella_clienti.txt, sono state utilizzate due funzioni definite nel file di libreria iomanip:
  1. la funzione setiosflags() con la costante di manipolazione ios:left, per impostare l’allineamento a sinistra;
  2. la funzione setw(n) per impostare la larghezza di visualizzazione di ciascun campo espressa in numero di caratteri (n) .

Esempio 2-B

Il programma dell’esempio 2-A opera sul file in formato CSV estraendo ciascuna riga, che manipola separatamente per l’estrazione dei rispettivi campi. Quest’ultima cosa viene fatta dalla funzione stampRigaSulFile() che sfutta i metodi dell’oggetto stringa C++. L’approccio utilizzato in questa funzione è generale ed è indispensabile quando non si conosce a priori il numero di campi che compongono ciascuna riga.

Se invece il numero di campi delle righe è noto a priori, lo stesso problema può essere risolto operando in modo più semplice utilizzando la funzione getline() come mostrato di seguito: