Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria Informatica, Gestionale e dell’Automazione
Lezione 9 Input/output e stream
Caratteri I caratteri vengono rappresentati come valori numerici Una tabella di codifica permette di associare valori numerici a caratteri ASCII (7bit) ISO-8859 256 caratteri sono appena sufficienti per le lingue europee Unicode (31bit) Transcodifica UTF-8 Transcodifica UTF-16
Libreria standard: string La classe string della libreria standard rappresenta sequenze di caratteri di lunghezza arbitraria typedef basic_string<char> string; string s; Costruttore di default, stringa vuota string s(“buongiorno”) Inizializza la stringa con una stringa costante Una “stringa costante” è una stringa stile C, non un oggetto della classe string Array di const char
Dichiarazione di string nella libreria standard template<typename _Alloc> class allocator; template<class _CharT> struct char_traits; template<typename _CharT, typename Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT>> class basic_string; template<> struct char_traits<char>; typedef basic_string<char> string; template<> struct char_traits<wchar_t>; typedef basic_string<wchar_t> wstring;
basic_string template<typename _CharT, typename _Traits, typename _Alloc> class basic_string _CharT è il tipo del carattere char wchar_t (come char ma occupa due o più byte) _Traits è un char_traits, specializzazione del template template<typename _CharT> struct char_traits Definisce le operazioni elementari tra caratteri: assegnamenti, conversioni, confronti, copie, spostamenti, … Nella libreria standard sono già definite le specializzazioni per char e wchar_t _Alloc è un allocatore
Membri di string string s; // … s.empty() s.size() operator[] true se s è vuota s.size() Dimensione (numero di caratteri) Restituisce un size_type (unsigned) operator[] Il carattere in una data posizione (partendo da 0) Non viene controllata la validità dell’indice L’argomento è un size_type Restituisce un Lvalue operator+ Concatenazione tra stringhe operator= Copia carattere per carattere operator== != < <= > >= Operatori di confronto
Membri di string Ricerca di sottostringhe Ricerca di un carattere find rfind Ricerca di un carattere find_first_of find_last_of find_first_not_of find_last_not_of Sostituzione replace Sottostringa substr
Stringhe stile C Il C++ eredita dal C la nozione di stringa come array di char, in cui l’ultimo carattere è null char s[] = {‘C’, ‘i’, ‘a’, ‘o’, ‘\0’}; char *s = “Ciao”; Il null è aggiunto in automatico while(*s) { // fai qualcosa con *s s++; } Per un oggetto string è definito il metodo c_str() che restituisce la stringa stile C corrispondente
Input di stringhe string s; cin >> s; getline(cin, s) Legge e scarta spazi bianchi iniziali Legge tutti i caratteri fino al successivo spazio bianco getline(cin, s) Legge una riga intera, fino al newline (che viene scartato)
Input/output #include <iostream> definisce oggetti usati per l’input/output usando la console, basati su flussi (stream) istream (input stream), flusso di input L’input da un istream si effettua con l’operatore >> cin, istream che funge da input standard Funzione getline, legge una string da un istream ostream (output stream), flusso di output L’output su un ostream si effettua con l’operatore << cout, ostream che funge da standard output cerr, ostream destinato all’output dei messaggi di errore iostream legge e scrive su un flusso Deriva da istream e ostream
IO di caratteri get(c) mette un char in c put(char) scrive un char putback(char) rimette nel flusso put(char) scrive un char get() restituisce il prossimo byte (come int) unget torna indietro di un byte peek() “spia” il prossimo byte senza leggerlo
IO di più caratteri get(sink, size, delim) legge size caratteri o finche fino a delim escluso, e li mette nel vettore sink getline(sink, size, delim) idem ma legge e scarta delim read(sink, size) legge size byte e li mette in sink gcount() restituisce il numero di byte letti dall’ultima lettura ignore(size, delim) ignora size caratteri o fino a delim incluso
Classi stream I flussi non permettono copia o assegnamento Non si possono usare direttamente come parametri o tipi di ritorno, ma solo tramite puntatori o riferimenti
Input/output object oriented Il meccanismo di IO è indipendente Dal dispositivo Console File Stringa Dimensione del carattere
Input/output su file #include <fstream> ifstream ofstream stream Deriva da istream ofstream Deriva da ostream stream Deriva da iostream
Input/output su string #include <sstream> istringstream Deriva da istream ostringstream Deriva da ostream stringstream Deriva da iostream
Stato di uno stream Per ogni oggetto di tipo di stream, es. istream istream::iostate è un tipo intero che è usato per rappresentare lo stato dello stream istream::badbit indica flusso corrotto (non recuperabile) istream::failbit indica fallimento dell’operazione di IO (è possibile riprovare) istream::eofbit indica fine del flusso (carattere end-of-file) bad() true se il bit badbit è settato fail() true se il bit failbit è settato eof() true se il bit badbit è settato good() se lo stream è in uno stato valido clear() resetta le condizioni allo stato valido clear(istream::iostate) resetta un flag setstate(istream::iostate) setta un flag rdstate() restituisce lo stato come iostate Si può testare direttamente la validità del flusso, es. while (cin >> a) { //… } Stati indicati come bit si possono combinare tramite |
Buffer Tutti gli IO su stream usano un buffer, svuotato Al termine del programma …ma non se c’è un crash Quando è pieno Forzandolo, immettendo endl(scrive un newline e svuota il buffer), ends (inserisce un null e svuota il buffer), flush (svuota il buffer e basta) endl e \n sono diversi Immettere unitbuf forza lo svuotamento del buffer ad ogni operazione nounitbuf tie lega l’output di un flusso all’input di un altro flusso, il buffer del primo si svuota quando il secondo legge cin.tie(&cout) lo fa il sistema per noi cin.tie() restiuisce un puntatore al flusso collegato cin.tie(0) annulla il collegamento
IO su file ifstream, ofstream, fstream Costruttore che prende nome di un file ifstream infile(“prova.txt”); string s(“prova2.txt”); ifstream infile2(s.c_str()); f.open(“nomefile”); if (f) { //… } f.close(); Serve anche f.clear();
File Mode Si può specificare la modalità di apertura di un file Solo per ofstream e fstream: out modalità di output, svuota il file all’apertura app output, posizionamento alla fine del file prima di ogni scrittura (preserva il contenuto del file) trunc svuota il file (senza aprirlo) in (modalità di input) solo per ifstream e fstream ate modalità che di apertura che porta immediatamente all’end-of-file binary modalità per cui il contenuto è considerato come sequenza di bytes (non si tenta di interpretarli) Es. f.open(“file.dat”, ofstream::out | ofstream::app)
Accesso casuale seek tell c’è un solo cursore! seekg, seekp seekg(position) seekg(offset, dir) dove dir è beg, cur, end tell tellg, tellp c’è un solo cursore!
Flussi su string I flussi su string servono ad effettuare IO in memoria istringstream, ostringstream, srtingstream string s(“pippo”); stringstream ss(s); ss.str() restituisce la stringa ss.str(s) copia la stringa su s Tramite flussi su string posso ottenere IO formattato Operatori << e >> ridefiniti
Stato della formattazione Oltre allo stato (del flusso), i flussi mantengono uno stato della formattazione usata La formattazione viene variata inserendo nel flusso dei manipolatori flags() restituisce lo stato corrente flags(fmtflags) setta lo stato Es. ostream::fmtflags è il tipo intero unsigned che serve a contenere i flag Alcuni manipolatori sono definiti in iomanip
Formattazione dei numeri interi boolalpha stampa i valori booleani come true e false (invece di 1 e 0) noboolalpha hex, oct, dec specificano la base numerica showbase causa la visualizzazione della base 0xnnnn indica un esadecimale 0nnnn indica un ottale nnnn indica un decimale uppercase visualizza esadecimali con lettere maiuscole setbase(int), accetta 8, 10 o 16
Formattazione dei numeri in virgola mobile Precisione (numero di cifre) Default 6 Arrotondamento (non troncamento) al numero di cifre desiderato precision() restituisce la precisione corrente precision(int) imposta la precisione Oppure manipolatore setprecision(int) Notazione (decimale o scientifica) Di default dipende dalla dimensione fixed, scientific cout.unsetf(ostream::floatfield) ritorna al default Posizione del punto decimale Di default omesso se non c’è parte frazionale showpoint Segno + Di default il + per i numeri positivi è omesso showpos
Posizionamento e riempitivi setw(int) imposta la dimensione minima del prossimo output left allinea a sinistra (aggiunge riempitivi a destra) right allinea a destra (aggiunge riempitivi a sinistra) internal aggiunge riempiti tra segno e valore skipws salta gli spazi bianchi dall’input setfill(char) permette di specificare il carattere usato come riempitivo