Stream

Gli stream sono un modo di accedere all'input/output standard, sia alla consolle che ai files. Il meccanismo uniforme è tutto basato sull'overloading degli operatori << e >>. Occorre includere il file iostream.h per poter utilizzare gli stream.

Stream di Output

Uno stream di output è del tipo classe ostream. Per i tipi standard, questa classe ridefinisce l'operatore <<:
ostream & operator << (base_type);
Notare che l'operatore restituisce ancora uno stream (anzi per risparmiare tempo e memoria un riferimento ad uno stream), e questo fatto permette di concatenare l'output usando appunto più operatori << concatenati (come si fa quando si scrive 1+2+3, ecc..!):
stream << "Time is" << hour << ":" << minute << ":" << second;
Ndt: la restituzione di un riferimento non è comunque solo una questione di ottimizzazione; è necessaria affinchè quando più operatori << son concatenati come nell'esempio precedente, le modifiche fatte all'oggetto stream dal secondo operatore in poi siano conservate, cioè non agiscano solo una copia temporanea, ma sull'oggetto stream stesso specificato all'inizio della espressione.

Gli stream standard (potete pensarli come istanze dei tipi classe ostream, istream o di alcuni loro derivati) sono cout per lo standard output, cerr per lo standard error bufferizzato, e clog per lo standard error senza buffer. Per esempio per far scrivere l'ora, basta digitare:

cout << "Time is" << hour << ":" << minute << ":" << second;
Un'altro modo di scrivere negli stream è di usare la funzione membro put. Essa è dichiarata come segue:
ostream & put (char);
ed è una funzione membro della classe ofstream. Si usa in modo molto semplice:
#include <iostream.h>

char Message[] = "This is a message.\n";
//...

int main()
{
  int i=0;
  while (Message[i])
    cout.put (Message[i++]);

  return(0);
}

Stream di Input

L'operatore >> è così sovrapposto:
istream & operator >> (& base_type);
Lo Standard Input è l'oggetto cin, perciò si usa in questo modo:
{
  int hh;
  int mm;

  cin >> hh >> mm;   // legge due interi da standard input
}
Puoi anche usare la funzione membro get se vuoi leggere un solo carattere o un insieme di caratteri:
istream & get (char &c);
istream & get (char *p, int max, char separator);

Overloading degli operatori << e >>

Puoi ridefinire gli operatori << e >> per permettere ai tuoi oggetti di uniformarsi all'architettura standard per l'i/o descritta in questa pagina. In questo modo aggiungi il supporto per l'input e/o l'output dei tuoi oggetti al sistema standard per l'i/o! Basta dichiararli così:
#include <iostream.h>
...
class Example
{
  friend ostream & operator << (ostream &st, Example &ex);
  friend istream & operator >> (istream &st, Example &ex);
};

ostream & operator << (ostream &st, Example &ex)
{
...
}

istream & operator >> (istream &st, Example &ex)
{
...
}
Per esempio consideriamo la classe Complex:
#include <iostream.h>
class Complex
{
  float r, i;

  friend ostream & operator << (ostream &out, Complex &ex);
  friend istream & operator >> (istream &in, Complex &ex);
};

ostream & operator << (ostream &out, Complex &ex)
{
  out << '(' << ex.r << ',' << ex.i << ')';
  return out;
}

istream & operator >> (istream &in, Complex &ex)
{
  in >> ex.r >> ex.i;
  return in;
}

int main()
{
  Complex c;
  cin >> c;
  cout << c << endl;

  return 0;
}

Connettere uno stream con un file

Quando vuoi connettere uno stream ad un file, usa le classi base fstream, ifstream e ofstream. I loro costruttori sono di questo tipo:
fstream (char *filename, open_mode mode);
ifstream (char *filename, open_mode mode = 0);
ofstream (char *filename, open_mode mode = 0);
dove filename è il nome del file e mode è un tipo enumerato. Questo enum è dichiarato nella classe ios, e può assumere uno o più di questi valori:
in         apri per l'input
out        apri in modalità di output
ate        apri e posizionati (seek) alla fine
app        apri in modo append
trunc      cancella prima di scrivere (cioè sovrascrivi)
nocreate   esci se il file non esiste
noreplace  esci se il file esiste
Ma vediamo un esempio:
// Copia un file in un altro

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

void Fatal (const char *message1, const char *message2 = "")
{
  cerr << message1 << ' ' << message2 << '\n';
  exit (-1);
}

int main (int argc, char *argv[])
{
  if (argc != 3)
    Fatal ("Not enough parameters.");

  ifstream source (argv[1]);
  if (!source) Fatal ("Cannot open file : ", argv[1]);

  ofstream dest (argv[2]);
  if (!dest) Fatal ("Cannot open file : ", argv[2]);

  char c;
  while (source.get(c))
    dest.put (c);

  if (!source.eof() || dest.bad())
    Fatal ("Reading or writing error.");

  exit (0);
}

C++