+La prima modalità di input/output non formattato ricalca quella della
+interfaccia dei file descriptor, e provvede semplicemente la scrittura e
+la lettura dei dati da un buffer verso un file e viceversa. In generale
+questa è la modalità che si usa quando si ha a che fare con dati non
+formattati. Le due funzioni che si usano per l'I/O binario sono:
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE
+ *stream)}
+
+ \funcdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t
+ nmemb, FILE *stream)}
+
+ Rispettivamente leggono e scrivono \param{nmemb} elementi di dimensione
+ \param{size} dal buffer \param{ptr} al file \param{stream}.
+
+ \bodydesc{Entrambe le funzioni ritornano il numero di elementi letti o
+ scritti, in caso di errore o fine del file viene restituito un numero di
+ elementi inferiore al richiesto.}
+\end{functions}
+
+In genere si usano queste funzioni quando si devono trasferire su file
+blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
+tipico è quello in cui si salva un vettore (o un certo numero dei suoi
+elementi) con una chiamata del tipo:
+%\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+int WriteVect(FILE *stream, double *vec, size_t nelem)
+{
+ int size, nread;
+ size = sizeof(*vec);
+ if ( (nread = fwrite(vec, size, nelem, stream)) != nelem) {
+ perror("Write error");
+ }
+ return nread;
+}
+\end{lstlisting}
+%\normalsize
+in questo caso devono essere specificate le dimensioni di ciascun
+elemento ed il numero di quelli che si vogliono scrivere. Un secondo
+caso è invece quello in cui si vuole trasferire su file una struttura;
+si avrà allora una chiamata tipo:
+%\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+struct histogram {
+ int nbins;
+ double max, min;
+ double *bin;
+} histo;
+
+int WriteStruct(FILE *stream, struct histogram *histo, size_t nelem)
+{
+ if ( fwrite(vec, sizeof(*histo), 1, stream) !=1) {
+ perror("Write error");
+ }
+ return nread;
+}
+\end{lstlisting}
+%\normalsize
+in cui si specifica la dimensione dell'intera struttura ed un solo
+elemento.
+
+In realtà quello che conta nel trasferimento dei dati sono le dimensioni
+totali, che sono sempre pari al prodotto \code{size * nelem}; la sola
+differenza è che le funzioni non ritornano il numero di byte scritti,
+ma il numero di elementi.
+
+La funzione \func{fread} legge sempre un numero intero di elementi, se
+incontra la fine del file l'oggetto letto parzialmente viene scartato
+(lo stesso avviene in caso di errore). In questo caso la posizione dello
+stream viene settata alla fine del file (e non a quella corrispondente
+alla quantità di dati letti).
+
+In caso di errore (o fine del file per \func{fread}) entrambe le
+funzioni restituiscono il numero di oggetti effettivamente letti o
+scritti, che sarà inferiore a quello richiesto. Contrariamente a quanto
+avviene per i file descriptor, questo segnala una condizione di errore e
+occorrerà usare \func{feof} e \func{ferror} per stabilire la natura del
+problema.
+
+Benché queste funzioni assicurino la massima efficienza per il
+salvataggio dei dati, i dati memorizzati attraverso di esse presentano
+lo svantaggio di dipendere strettamente dalla piattaforma di sviluppo
+usata ed in genere possono essere riletti senza problemi solo dallo
+stesso programma che li ha prodotti.
+
+Infatti diversi compilatori possono eseguire ottimizzazioni diverse
+delle strutture dati e alcuni compilatori (come il \cmd{gcc}) possono
+anche scegliere se ottimizzare l'occupazione di spazio, impacchettando
+più strettamente i dati, o la velocità inserendo opportuni
+\textit{padding} per l'allineamento dei medesimi generando quindi output
+binari diversi. Inoltre altre incompatibilità si possono presentare
+quando entrano in gioco differenze di architettura hardware, come la
+dimensione del bus o la modalità di ordinamento dei bit o il formato
+delle variabili in floating point.
+
+Per questo motivo quando si usa l'input/output binario occorre sempre
+essere prendere le opportune precauzioni (in genere usare un formato di
+più alto livello che permetta di recuperare l'informazione completa),
+per assicurarsi che versioni diverse del programma siano in grado di
+rileggere i dati tenendo conto delle eventuali differenze.
+
+Le \acr{glibc} definiscono altre due funzioni per l'I/O binario, che
+evitano il lock implicito dello stream, usato per dalla librerie per la
+gestione delle applicazioni multi-thread (si veda
+\secref{sec:file_stream_thread} per i dettagli):
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{size\_t fread\_unlocked(void *ptr, size\_t size, size\_t
+ nmemb, FILE *stream)}
+
+ \funcdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size,
+ size\_t nmemb, FILE *stream)}
+
+ \bodydesc{Le funzioni sono identiche alle analoghe \func{fread} e
+ \func{fwrite} ma non acquisiscono il lock implicito sullo stream.}
+\end{functions}
+\noindent entrambe le funzioni sono estensioni GNU previste solo dalle
+\acr{glibc}.
+
+
+\subsection{Input/output a caratteri}
+\label{sec:file_char_io}
+
+La seconda modalità di input/output è quella a caratteri, in cui si
+trasferisce un carattere alla volta. Le funzioni per la lettura a
+caratteri sono tre, \func{fgetc}, \func{getc} e \func{getchar}, i
+rispettivi prototipi sono:
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{int getc(FILE *stream)} Legge un byte da \param{stream} e lo
+ restituisce come intero. In genere è implementata come una macro.
+
+ \funcdecl{int fgetc(FILE *stream)} Legge un byte da \param{stream} e lo
+ restituisce come intero. È una sempre una funzione.
+
+ \funcdecl{int getchar(void)} Equivalente a \code{getc(stdin)}.
+
+ \bodydesc{Tutte queste funzioni leggono un byte alla volta, che viene
+ restituito come intero; in caso di errore o fine del file il valore
+ di ritorno è \macro{EOF}.}
+\end{functions}
+
+A parte \func{getchar}, che si usa in genere per leggere un carattere da
+tastiera, le altre due funzioni sono sostanzialmente equivalenti. La
+differenza è che \func{getc} è ottimizzata al massimo e normalmente
+viene implementata con una macro, per cui occorre stare attenti a cosa
+le si passa come argomento, infatti \param{stream} può essere valutato
+più volte nell'esecuzione, e non viene passato in copia con il
+meccanismo visto in \secref{sec:proc_var_passing}; per questo motivo se
+si passa un'espressione si possono avere effetti indesiderati.
+
+Invece \func{fgetc} è assicurata essere sempre una funzione, per questo
+motivo la sua esecuzione normalmente è più lenta per via dell'overhead
+della chiamata, ma è altresì possibile ricavarne l'indirizzo, che può
+essere passato come parametro ad un altra funzione (e non si hanno i
+problemi accennati in precedenza con \param{stream}).
+
+Le tre funzioni restituiscono tutte un \ctyp{unsigned char} convertito
+ad \ctyp{int} (si usa \ctyp{unsigned char} in modo da evitare
+l'espansione del segno). In questo modo il valore di ritorno è sempre
+positivo, tranne in caso di errore o fine del file.
+
+Nelle estensioni GNU che provvedono la localizzazione sono definite tre
+funzioni equivalenti alle precedenti che invece di un carattere di un
+byte restituiscono un carattere in formato esteso (cioè di tipo
+\ctyp{wint\_t}, il loro prototipo è:
+\begin{functions}
+ \headdecl{stdio.h}
+ \headdecl{wchar.h}
+
+ \funcdecl{wint\_t getwc(FILE *stream)} Legge un carattere esteso da
+ \param{stream}. In genere è implementata come una macro.
+
+ \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
+ \param{stream} È una sempre una funzione.
+
+ \funcdecl{wint\_t getwchar(void)} Equivalente a \code{getwc(stdin)}.
+
+ \bodydesc{Tutte queste funzioni leggono un carattere alla volta, in
+ caso di errore o fine del file il valore di ritorno è \macro{WEOF}.}
+\end{functions}
+
+Per scrivere un carattere si possono usare tre funzioni analoghe alle
+precedenti usate per leggere: \func{putc}, \func{fputc} e
+\func{putchar}; i loro prototipi sono:
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{int putc(int c, FILE *stream)} Scrive il carattere \param{c}
+ su \param{stream}. In genere è implementata come una macro.
+
+ \funcdecl{int fputc(FILE *stream)} Scrive il carattere \param{c} su
+ \param{stream}. È una sempre una funzione.
+
+ \funcdecl{int putchar(void)} Equivalente a \code{putc(stdin)}.
+
+ \bodydesc{Le funzioni scrivono sempre un carattere alla volta, il cui
+ valore viene restituito in caso di successo; in caso di errore o
+ fine del file il valore di ritorno è \macro{EOF}.}
+\end{functions}
+
+Tutte queste funzioni scrivono sempre un byte alla volta, anche se
+prendono come parametro un \ctyp{int} (che pertanto deve essere ottenuto
+con un cast da un \ctyp{unsigned char}). Anche il valore di ritorno è
+sempre un intero; in caso di errore o fine del file il valore di ritorno
+è \macro{EOF}.
+
+Come nel caso dell'I/O binario le \acr{glibc} provvedono per ciascuna
+delle funzioni precedenti, come estensione GNU, una seconda funzione, il
+cui nome è ottenuto aggiungendo un \code{\_unlocked}, che esegue
+esattamente le stesse operazioni evitando però il lock implicito dello
+stream.
+
+Per compatibilità con SVID sono provviste anche due funzioni per leggere
+e scrivere una \textit{word} (che è sempre definita come \ctyp{int}); i
+loro prototipi sono:
+\begin{functions}
+ \headdecl{stdio.h}
+
+ \funcdecl{int getw(FILE *stream)} Legge una parola da \param{stream}.
+ \funcdecl{int putw(int w, FILE *stream)} Scrive la parola \param{w} su
+ \param{stream}.
+
+ \bodydesc{Le funzioni restituiscono la parola \param{w}, o \macro{EOF}
+ in caso di errore o di fine del file.}
+\end{functions}
+\noindent l'uso di queste funzioni è deprecato in favore dell'uso di
+\func{fread} e \func{fwrite}, in quanto non è possibile distinguere il
+valore -1 da una condizione di errore che restituisce \macro{EOF}.
+
+Una degli usi più frequenti dell'input/output a caratteri è nei
+programmi di \textit{parsing} in cui si analizza il testo; in questo
+contesto diventa utile poter analizzare il carattere successivo da uno
+stream senza estrarlo effettivamente (la tecnica è detta \textit{peeking
+ ahead}) in modo che il programma possa regolarsi sulla base avendo
+dato una \textsl{sbirciatina} a quello che viene dopo.
+
+Nel nostro caso questo tipo di comportamento può essere realizzato prima
+leggendo il carattere, e poi rimandandolo indietro, cosicché ridiventi
+disponibile per una lettura successiva; la funzione che inverte la
+lettura si chiama \func{ungetc} ed il suo prototipo è:
+\begin{prototype}{stdio.h}{int ungetc(int c, FILE *stream)}
+ Rimanda indietro il carattere \param{c}, con un cast a \ctyp{unsigned
+ char}, sullo stream \param{stream}.
+
+ \bodydesc{La funzione ritorna \param{c} in caso di successo e
+ \macro{EOF} in caso di errore.}
+\end{prototype}
+\noindent benché lo standard ANSI C preveda che l'operazione possa
+essere ripetuta per un numero arbitrario di caratteri, alle
+implementazioni è richiesto di garantire solo un livello; questo è
+quello che fa la \acr{glibc}, che richiede che avvenga un'altra
+operazione fra due \func{ungetc} successive.
+
+Non è necessario che il carattere che si manda indietro sia l'ultimo che
+si è letto, e non è necessario neanche avere letto nessun carattere
+prima di usare \func{ungetc}, ma di norma la funzione è intesa per
+essere usata per rimandare indietro l'ultimo carattere letto.
+
+Nel caso \param{c} sia un \macro{EOF} la funzione non fa nulla, e
+restituisce sempre \macro{EOF}; così si può usare \func{ungetc} anche
+con il risultato di una lettura alla fine del file.
+
+Se si è alla fine del file si può comunque rimandare indietro un
+carattere, il flag di end-of-file verrà automaticamente cancellato
+perché c'è un nuovo carattere disponibile che potrà essere riletto
+successivamente.
+
+Infine si tenga presente che \func{ungetc} non altera il contenuto del
+file, ma opera esclusivamente sul buffer interno. Se si esegue una
+qualunque delle operazioni di riposizionamento (vedi
+\secref{sec:file_fseek}) i caratteri rimandati indietro vengono
+scartati.
+