ios
è una classe base per istream
e ostream
; essa fornisce l'interfacciamento tra di esse e gli streambuf
a essi soggiacenti (non ci occuperemo di tale questione12.4) e una serie di funzioni membro utili durante l'utilizzazione delle classi istream
e ostream
. Possiamo dividere in tre classi questi metodi: stati, formati, manipolatori.
Gli stati (states) sono funzioni le quali ci danno delle informazioni utili sui possibili ``stati'' appunto di uno stream12.5:
ios::operator bool () const
ios::operator ! () const iostate ios::rdstate () const void ios::setstate (iostate state) void ios::clear (iostate s) int ios::good () const int ios::fail () const int ios::bad () const int ios::eof () const |
Le prime due funzioni sono solo di convenienza: esse permettono infatti di effettuare dei controlli semplicemente:
if (cout) { /* tutto ok, procedi */ } if (!cin) { /* l'entrata non va, rimedia */ } |
La funzione rdstate()
restituisce lo stato dello stream, sotto forma di insieme di flag nel tipo iostate
, il quale comprende:
ios::goodbit
' segnala che non si sono verificate situazioni straordinarie nello stream;ios::failbit
' segnala che qualche operazione non è andata a buon fine (tipico il caso di formato errato in lettura);ios::badbit
' segnala che lo stream è corrotto;ios::eofbit
' segnala che è stata raggiunta la fine dello stream;setstate()
e clear()
permettono di impostare manualmente gli stati di uno stream; la differenza tra le due è che la prima aggiunge i flag passati come argomento a quelli già impostati, mentre la seconda pulisce lo stato dello stream e successivamente imposta i flag passati come argomento. La funzione good()
restituisce un valore non negativo se nessun indicatore di errore è impostato; la funzione fail()
restituisce un valore non negativo se almeno uno tra ios::failbit
e ios::badbit
è acceso; la funzione bad()
restituisce un valore non negativo se ios::badbit
è acceso; la funzione eof()
, infine, restituisce un valore non negativo se ios::eofbif
è acceso.
Piuttosto che presentare un esempio esaustivo su tutte le possibili combinazioni di stati di uno stream, invitiamo il lettore interessato a provarle autonomamemente.
I formati (format control) sono delle funzioni che consentono di modificare (essenzialmente) la formattazione in uscita del testo; alcuni sono:
int ios::precision () const
int ios::precision (int sign) char ios::fill () const char ios::fill (char padding) int ios::width () const int ios::width (int w) fmtflags ios::flags () const fmtflags ios::flags (fmtflags flags) fmtflags ios::setf (fmtflags flag) fmtflags ios::unsetf (fmtflags flag) |
Il tipo fmtflags
comprende i seguenti flags:
ios::dec
ios::hex
ios::oct
stabilisce in quale base numerica stampare i numeri interi; in entrata, se nessuno dei precedenti è impostato, il numero viene interpretato in base al prefisso: `0' indica che il numero è in base ottale, '0x' indica che esso è in base esadecimale. Il valore default è ios::dec
;ios::fixed
evita che venga utilizzata la notazione scientifica per numeri reali;ios::scientific
impone l'utilizzo della notazione scientifica per numeri reali;ios::right
ios::left
ios::internal
imposta l'allineamento con stampa a ampiezza uniforme; internal
implica che, ad esempio, i caratteri di riempimento compaiano tra un carattere ed un numero;ios::showbase
stampa i prefissi `0' e `0x' per rappresentazioni ottali e esadecimali;ios::showpoint
stampa per i numeri reali il punto decimale e gli zeri di coda, anche quando non sono significativi;ios::showpos
stampa come prefisso il `+' per i numeri positivi;ios::skipws
ignora gli spazi bianchi (default);ios::uppercase
utilizza caratteri maiuscoli per le lettere `a-f' e `x' nella rappresentazione esadecimale, e per la `e' nella notazione esponenziale.
Le due funzioni precision()
servono a controllare il numero di cifre decimali stampate per i numeri reali; le funzioni fill()
servono ad impostare il carattere di padding (``riempimento'') nel caso si utilizzi una spaziatura uniforme, la quale è gestita tramite le funzioni width()
. Si noti che le impostazioni di width()
vengono azzerate ogni volta che viene utilizzato l'operatore `<<
'. Le restanti funzioni servono ad agire su tutti i flag di tipo fmtflags
su illustrati: flags()
senza argomenti restituisce le correnti impostazioni, flags()
con argomento un fmtflags
imposta come corrente l'argomento passatogli, setf()
e unsetf()
abilitano/disabilitano un solo flag alla volta. Vediamo il seguente esempio (non esaustivo):
// ex12_6_6.cpp // l'output e` mostrato nei commenti #include <iostream.h> void main() { const int intero = 1; const double reale = 3.1415926536; // salva le impostazioni default ios::fmtflags defaultFlags = cout.flags(); // imposta una spaziatura uniforme di 15 caratteri // con carattere di padding `.' cout.width(15); cout.fill('.'); cout << intero << '\n'; // ..............1 // imposta l'allineamento a sinistra e interno cout.setf(ios::left); cout.width(15); cout.fill('.'); cout << intero << '\n'; // 1.............. cout.setf(ios::internal); cout.width(15); cout.fill('.'); cout << "int: " << intero << '\n'; // int: ..........1 // ripristina le impostazioni default cout.flags (defaultFlags); // mostra reali con la precisione di 3 cifre cout.precision(3); cout << reale << '\n'; // 3.14 // imposta numero fisso di cifre decimali cout.setf(ios::showpoint); cout << (double)intero << '\n'; // 1.00 // forza l'utilizzo della notazione scientifica cout.setf(ios::scientific); cout << reale << '\n'; // 3.142e+00 // utilizza caratteri maiuscoli cout.setf(ios::uppercase); cout << reale << '\n'; // 3.142E+00 }
I manipolatori (manipulator) sono delle particolari funzioni non membro, le quali hanno lo scopo di influenzare la formattazione o la rappresentazione dei dati in entrata o uscita del flusso; si noterà che molti di essi corrispondono alle funzioni membro appena esaminate e indicate come ``formati''. Alcuni manipolatori sono i seguenti, le cui intestazioni sono contenute in iomanip.h
:
ws
: ignora gli spazi bianchi;flush
: ``scarica'' le code negli stream;endl
: invia un ritorno a capo ed effettua un flush;ends
: invia il carattere di terminazione stringa (`\0'
);setprecision(int n)
: imposta la precisione dei numeri reali a n
cifre;setw(int n)
: imposta la spaziatura a n
caratteri uniforme;setfill(char c)
: imposta a c
il carattere di padding;dec
hex
oct
: sceglie la base per i numeri interiVediamo qualche possibile utilizzo dei manipolatori nel seguente esempio:
// ex12_6_7.cpp #include <iostream.h> #include <iomanip.h> void main() { cout.setf(ios::showbase); cout << oct << 42798 << '\n' << flush; // 0123456 cout.unsetf(ios::showbase); cout.setf(ios::uppercase); cout << hex << 831486 << endl; // CAFFE cout << setfill('_') << setw(20) << setprecision(9) << 10.0/3.0 << endl; // __________3.33333333 }