User Tools

Site Tools


appunti3s:oggetti_di_tipo_stream

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
appunti3s:oggetti_di_tipo_stream [2019/07/28 11:27] profproappunti3s:oggetti_di_tipo_stream [2020/06/08 22:19] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +>> per tornare all'indice -> [[appunti3s:linguaggio_c|Linguaggio C++]]
  
 +====== Stream (flusso di dati) ======
 +Si sono già utilizzati gli operatori "extractor" %%>>%% e "insertion" %%<<%% nell pagine della  [[appunti3s:programmazione_imperativa#stdcin_-_stdcout_-_stdcerr|programmazione imperativa]]...
 +>> Nel seguente testo i termini input e output sono sempre riferiti al programma, quindi:
 +
 +  * "in input" significa "in ingresso al programma"
 +  * "in output" significa "in uscita dal programma"
 +
 +
 +===== Operatore Extractor >> =====
 +
 +Solo adesso, giunti a questo livello di studio, si può comprendere che Extractor è un operatore che si applica su due //oggetti//: un oggetto Istream (stream di input, come std%%::%%cin) che rappresenta cioè i caratteri in ingresso al programma (come quelli provenienti dalla tastiera) e un oggetto dove i caratteri sono destinati a finire (come le variabili del programma). 
 +<code>std::cin >> varstring;</code>
 +{{ :appunti3s:extractor.png |}}
 +===== Operatore Insertion << =====
 +
 +Anche questo è un operatore che si applica su due //oggetti//: un oggetto Ostream (stream di output, come std%%::%%cout) che rappresenta i caratteri in uscita dal programma (come quelli diretti verso il monitor) e un oggetto nella memoria, da cui i caratteri provengono (come le variabili del programma o le costanti).
 +<code>std::cout << varstring << "testo";</code>
 +
 +Questi operatori restituiscono a loro volta un oggetto stream
 +<code> ostream& operator<< ( ostream&,...)</code>
 +quindi possono essere usati ricorsivamente, o annidati, eseguendo l'espressione come se si fossero aggiunte le parentesi tonde.
 +<code> (std::cout << "Mario ") << "Rossi" << std::endl;</code>
 +====== fstream ======
 +
 +In modo analogo a std%%::%%cout e cin, il programmatore può definire nuovi oggetti stream di output (o di input) e successivamente applicare l'operatore Insertion %%<<%%(o Extractor %%>>%%) per eseguire operazioni di output (o di input) per il programma.
 +
 +<code>
 +std::ifstream is;  //dichiarazione oggetto input stream (di input per il programma)
 +is >> varstring;   // operazione di lettura con Extractor: è input per il programma!
 +                   // l'input si arresta al primo spazio bianco....</code>
 +<code>
 +std::ofstream os;  //dichiarazione oggetto output stream (di output per il programma)
 +os << "testo";     //operazione di scrittura con Insertion: è output per il programma!</code>
 +
 +Questi sono "oggetti" e devono essere utilizzati nell'ottica della programmazione orientata agli oggetti.
 +Gli oggetti di tipo //ifstream// sono predefiniti per l'input, mentre //ofstream// sono predefiniti per l'output. Gli oggetti //fstream// possono essere usati indifferentemente per Input e Output.
 +
 +===== File =====
 +Un file contiene una sequenza  di numeri memorizzati permanentemente sulla memoria di massa, utilizzando una certa organizzazione interna dei dati. 
 +  * Se ogni Byte rappresenta nella realtà un carattere (char), il file può essere trattato come un //file di caratteri// (metodo predefinito). 
 +  * Se rappresenta altro (es: un float è un valore che occupa diversi Byte) il file deve essere trattato come un //file binario//.  
 +Se non diversamente specificato un file è aperto come file di testo, altrimenti in caso di immagini, file audio, file eseguibili, si devono aprire in formato binario.
 +
 +Un file possiede un nome (di solito con estensione) una data e il formato in cui sono organizzati i dati al suo interno. (vedere problema dei caratteri nei nomi dei file e problema dei {{appunti4s:formati.pdf}} proprietari)
 +Un file può essere aperto in diversi "modi": in lettura, in scrittura o in entrambi i modi.
 +<file c stream.cpp>
 +/* questo programma è stato scritto da Fabio
 + 
 + * esempio di lettura e scrittura su file di testo
 + */
 +#include <string>
 +#include <iostream>
 +#include <fstream>
 +
 +int main()
 +{
 +   std::string nomeFile("nessuno.txt");
 +
 +   std::cout << "Inserire il nome del file \n" ;
 +   std::cin >> nomeFile;
 +   
 +         // definisce un oggetto stream aperto in lettura e scrittura (deve esistere).
 +         // se era aperto solo in scrittura poteva anche non esistere         
 +   std::fstream flussoFile(nomeFile.c_str(),std::ios_base::in|std::ios_base::out);  
 +
 + // ma apertura in lettura puo' dare errore se file inesistente.
 + if (!flussoFile) std::cout << "can't open input file"<<std::endl;
 +
 +   std::string parola("bla");
 +   flussoFile << "testo a piacere...";  // operazione di scrittura con Insertion: è output dal programma!
 +   flussoFile >> parola;   // operazione di lettura con Extractor: è input per il programma! attenzione agli spazi bianchi...
 +
 +   return 0;
 +}
 +</file>
 +
 +Usando i file di testo, oltre a leggere una parola su una variabile (string) si può leggere anche un gruppo di cifre, che rappresentano un numero, su una variabile float (o di altro tipo numerico) 
 +<code>
 +   double d;
 +   flussoFile >> d;  // extractor preleva caratteri dal file e li trasforma in dati dentro d
 +   flussoFile << d;  // insertion deposita caratteri dentro il file a partire dai dati dentro d
 +</code>
 +
 +===== Stato del flusso file =====
 +
 +Gli oggetti stream possiedono degli //stati// che possono essere verificati con delle funzioni:
 +<code>
 +flussoFile.good(); // restituisce true se è tutto ok
 +flussoFile.eof();  // restituisce true se la lettura del file ha raggiunto la fine del file.
 +flussoFile.fail(); // restituisce true se l'ultima operazione sul file è fallita.
 +flussoFile.bad();  // restituisce true se l'errore è più grave.
 +</code>
 +<code>
 +flussoFile.clear();  // pulisce lo stato per riprovare l'operazione
 +flussoFile.unget();  // restituisce indietro il dato letto
 +flussoFile.exceptions(ios_base::badbit);  // lancia un'eccezione
 +</code>
 +
 +
 +====funzione open====
 +
 +<code>#include <fstream></code>
 +
 +<file cpp 61.cpp>
 +#include <string>
 +#include <iostream>
 +#include <fstream>
 +
 +int main()
 +{
 +  std::string parola = "ciao";
 +  const std::string nomeFile = "prova.txt"; // sarebbe errore passare una stringa costante,
 +                                            // bisogna passare una costante stringa...  
 +  std::fstream mioFile; 
 +
 +  mioFile.open("prova.txt", std::ios_base::in|std::ios_base::out); //aperto in lettura e scrittura
 +  std::cout << "Salvo una parola" << std::endl;
 +  mioFile << parola << std::endl;
 +
 +  mioFile.close(); // opzionale. chiudo il collegamento con il file "prova.txt"
 +                   // e posso riutilizzare l'oggetto per altri file...
 +
 +  return 0;
 +}
 +
 +</file>
 +
 +Il buffer serve per non scrivere un carattere alla volta nel file, ma per riempire un vettore e scrivere solo quando il vettore è pieno, oppure quando lo decide il programmatore con flush()
 +
 +
 +===== Posizionamento =====
 +Un file può essere letto sequenzialmente, oppure ci si può spostare su e giù per il file (0.. n-1)
 +<code>
 +   std::ifstream flussoFile(nomeFile.c_str()); //apertura in lettura predefinita
 +   flussoFile.seekg(5);    // posizione 6 (Seek) per lettura (Get).
 +   flussoFile >> varchar;  // lettura di un carattere
 +</code>
 +<code>
 +   std::ofstream flussoFile(nomeFile.c_str()); //apertura in scrittura predefinita
 +   flussoFile.seekp(5);    // posizione 6 (Seek) per scrittura (Put).
 +   flussoFile << "z";  // scrittura di un carattere
 +</code>
 +
 +===== Approfondimento =====
 +
 +Provare a scrivere un programma che legge separatamente nome e cognome e poi mette questi dati all'interno di un'unica variabile usando l'operatore concatenazione (+). 
 +
 +Provare a scrivere l'esempio inverso… (aiutati da std%%::%%stringstream in <sstream>
 +
 +Provare a scrivere un programma che legge dati da un file in un buffer (aiutati da std%%::%%stringstream in <sstream>)
 +
 +<file cpp 63.cpp>
 +#include <iostream>
 +#include <sstream>
 +/* programma che usa un buffer per scrivere in un file */
 +
 +int main() 
 +{   
 +   std::ofstream flussoFile(nomeFile.c_str()); //apertura in scrittura predefinita  
 +                                     // non si inviano direttamente dati al file (mem. massa)
 +                                     // ma si accumulano temporaneamente in uno stream (mem. centrale)
 +   std::ostringstream streambuffer;  // accumula temporaneamente dati
 +
 +   streambuffer << "testo" << std::endl;
 +   streambuffer << "inserito a ripetizione" << std::endl;
 +    
 +   std::string varstring = streambuffer.str();   // trasforma il buffer in una string
 +                                                 // per poterla inviare ad un fstream
 +
 +   flussoFile << varstring;           // effettiva scrittura nel file
 +
 +   return 0;  
 +}
 +</file>
 +
 +
 +>> per tornare all'indice -> [[appunti3s:linguaggio_c|Linguaggio C++]]