Messa ungetc, ripassato ispell
[gapil.git] / filestd.tex
index dcbb3381f146bb7cd6d0141571274232de019601..14867d51305f3577f41127638d4698390ee0e167 100644 (file)
@@ -223,15 +223,16 @@ prototipi sono:
   stream)}
   Apre il file specificato da \param{path} associandolo allo stream
   specificato da \param{stream}, se questo è già aperto prima lo chiude.
   stream)}
   Apre il file specificato da \param{path} associandolo allo stream
   specificato da \param{stream}, se questo è già aperto prima lo chiude.
-
-  Le funzioni ritornano un puntatore valido in caso di successo e \macro{NULL}
-  in caso di errore, in tal caso \var{errno} viene settata al valore ricevuto
-  dalla funzione sottostante di cui è fallita l'esecuzione.
   
   
-  Gli errori pertanto possono essere quelli di \func{malloc} per tutte e tre
-  le funzioni, quelli \func{open} per \func{fopen}, quelli di \func{fcntl} per
-  \func{fdopen} e quelli di \func{fopen}, \func{fclose} e \func{fflush} per
-  \func{freopen}. 
+  \bodydesc{Le funzioni ritornano un puntatore valido in caso di
+    successo e \macro{NULL} in caso di errore, in tal caso \var{errno}
+    viene settata al valore ricevuto dalla funzione sottostante di cui è
+    fallita l'esecuzione.
+  
+    Gli errori pertanto possono essere quelli di \func{malloc} per tutte
+    e tre le funzioni, quelli \func{open} per \func{fopen}, quelli di
+    \func{fcntl} per \func{fdopen} e quelli di \func{fopen},
+    \func{fclose} e \func{fflush} per \func{freopen}.}
 \end{functions}
 
 Normalmente la funzione che si usa per aprire uno stream è \func{fopen},
 \end{functions}
 
 Normalmente la funzione che si usa per aprire uno stream è \func{fopen},
@@ -341,10 +342,11 @@ Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo 
 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
   Chiude lo stream \param{stream}. 
   
 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
   Chiude lo stream \param{stream}. 
   
-  Restituisce 0 in caso di successo e \macro{EOF} in caso di errore, nel qual
-  caso setta \var{errno} a \macro{EBADF} se il file descriptor indicato da
-  \param{stream} non è valido, o uno dei valori specificati dalla sottostante
-  funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
+  \bodydesc{Restituisce 0 in caso di successo e \macro{EOF} in caso di errore,
+    nel qual caso setta \var{errno} a \macro{EBADF} se il file descriptor
+    indicato da \param{stream} non è valido, o uno dei valori specificati
+    dalla sottostante funzione che è fallita (\func{close}, \func{write} o
+    \func{fflush}).}
 \end{prototype}
 
 La funzione effettua uno scarico di tutti i dati presenti nei buffer di
 \end{prototype}
 
 La funzione effettua uno scarico di tutti i dati presenti nei buffer di
@@ -360,7 +362,7 @@ prototipo 
 \begin{prototype}{stdio.h}{int fcloseall(void)}
   Chiude tutti gli stream. 
   
 \begin{prototype}{stdio.h}{int fcloseall(void)}
   Chiude tutti gli stream. 
   
-  Restituisce 0 se non ci sono errori ed \macro{EOF} altrimenti.
+  \bodydesc{Restituisce 0 se non ci sono errori ed \macro{EOF} altrimenti.}
 \end{prototype}
 la funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
 in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
 \end{prototype}
 la funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
 in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
@@ -432,7 +434,7 @@ ogni volta che si chiama una funzione di libreria.
 
 Entrambi i flag (di errore e di end-of-file) possono essere cancellati usando
 la funzione \func{clearerr}, il cui prototipo è:
 
 Entrambi i flag (di errore e di end-of-file) possono essere cancellati usando
 la funzione \func{clearerr}, il cui prototipo è:
-\begin{prototype}{stdio.h}{void clearerr( FILE *stream)}
+\begin{prototype}{stdio.h}{void clearerr(FILE *stream)}
   Cancella i flag di errore ed end-of-file di \param{stream}. 
 \end{prototype}
 \noindent in genere si usa questa funziona una volta che si sia identificata e
   Cancella i flag di errore ed end-of-file di \param{stream}. 
 \end{prototype}
 \noindent in genere si usa questa funziona una volta che si sia identificata e
@@ -457,13 +459,12 @@ formattati. Le due funzioni che si usano per l'I/O binario sono:
   \funcdecl{size\_t fwrite(const 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)}
   
-  Le funzioni rispettivamente leggono e scrivono \param{nmemb} elementi
-  di dimensione \param{size} dal buffer \param{ptr} al file
-  \param{stream}.
+  Rispettivamente leggono e scrivono \param{nmemb} elementi di dimensione
+  \param{size} dal buffer \param{ptr} al file \param{stream}.
   
   
-  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.
+  \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
 \end{functions}
 
 In genere si usano queste funzioni quando si devono trasferire su file
@@ -557,8 +558,8 @@ gestione delle applicazioni multi-thread (si veda
   \funcdecl{size\_t fwrite\_unlocked(const 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)}
   
-  Le funzioni sono identiche alle analoghe \func{fread} e \func{fwrite}
-  ma non acquisiscono il lock implicito sullo 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}.
 \end{functions}
 \noindent entrambe le funzioni sono estensioni GNU previste solo dalle
 \acr{glibc}.
@@ -568,10 +569,9 @@ gestione delle applicazioni multi-thread (si veda
 \label{sec:file_char_io}
 
 La seconda modalità di input/output è quella a caratteri, in cui si
 \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:
+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} 
 
 \begin{functions}
   \headdecl{stdio.h} 
 
@@ -581,11 +581,11 @@ Le funzioni per la lettura a caratteri sono tre, \func{fgetc},
   \funcdecl{int fgetc(FILE *stream)} Legge un byte da \param{stream} e lo
   restituisce come intero. È una sempre una funzione.
   
   \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 \func{getc(stdin)}.
+  \funcdecl{int getchar(void)} Equivalente a \func{getc(stdin)}.
   
   
-  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}.
+  \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
 \end{functions}
 
 A parte \func{getchar}, che si usa in genere per leggere un carattere da
@@ -608,7 +608,7 @@ ad \type{int} (si usa \type{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.
 
 l'espansione del segno). In questo modo il valore di ritorno è sempre
 positivo, tranne in caso di errore o fine del file.
 
-Nelle estenzioni GNU che provvedono la localizzazione sono definite tre
+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
 \type{wint\_t}, il loro prototipo è:
 funzioni equivalenti alle precedenti che invece di un carattere di un
 byte restituiscono un carattere in formato esteso (cioè di tipo
 \type{wint\_t}, il loro prototipo è:
@@ -621,10 +621,10 @@ byte restituiscono un carattere in formato esteso (cio
   \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
   \param{stream} È una sempre una funzione.
   
   \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
   \param{stream} È una sempre una funzione.
   
-  \funcdecl{wint\_t getwchar(void)} è equivalente a \func{getwc(stdin)}.
+  \funcdecl{wint\_t getwchar(void)} Equivalente a \func{getwc(stdin)}.
   
   
-  Tutte queste funzioni leggono un carattere alla volta, in caso di
-  errore o fine del file il valore di ritorno è \macro{WEOF}.
+  \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
 \end{functions}
 
 Per scrivere un carattere si possono usare tre funzioni analoghe alle
@@ -639,11 +639,11 @@ precedenti usate per leggere: \func{putc}, \func{fputc} e
   \funcdecl{int fputc(FILE *stream)} Scrive il carattere \param{c} su
   \param{stream}. È una sempre una funzione.
   
   \funcdecl{int fputc(FILE *stream)} Scrive il carattere \param{c} su
   \param{stream}. È una sempre una funzione.
   
-  \funcdecl{int putchar(void)} è equivalente a \func{putc(stdin)}.
+  \funcdecl{int putchar(void)} Equivalente a \func{putc(stdin)}.
   
   
-\item \noindent 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}.
+  \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
 \end{functions}
 
 Tutte queste funzioni scrivono sempre un byte alla volta, anche se
@@ -666,13 +666,57 @@ loro prototipi sono:
   \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}.
   \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}.
-
-  Le funzioni restituiscono la parola \param{w}, o \macro{EOF} in caso
-  di errore o di fine del file.
+  
+  \bodydesc{Le funzioni restituiscono la parola \param{w}, o \macro{EOF}
+    in caso di errore o di fine del file.}
 \end{functions}
 \end{functions}
-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}.
+\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 \type{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}
+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.
 
 
 \subsection{Input/output di linea}
 
 
 \subsection{Input/output di linea}
@@ -680,10 +724,11 @@ condizione di errore che restituisce \macro{EOF}.
 
 La terza ed ultima modalità di input/output non formattato è quello di
 linea, in cui legge o scrive una riga alla volta; questa è una modalità
 
 La terza ed ultima modalità di input/output non formattato è quello di
 linea, in cui legge o scrive una riga alla volta; questa è una modalità
-molto usata, ma che presenta le caratteristiche più controverse.
+molto usata per l'I/O da terminale, ma che presenta le caratteristiche
+più controverse.
 
 
-Le funzioni per leggere una linea sono sostazialmente due, \func{gets} e
-\func{fgets}, i rispettivi prototipi sono:
+Le funzioni per leggere una linea sono sostanzialmente due, \func{gets} e
+\func{fgets}, i cui rispettivi prototipi sono:
 \begin{functions}
   \headdecl{stdio.h} 
   
 \begin{functions}
   \headdecl{stdio.h} 
   
@@ -693,9 +738,9 @@ Le funzioni per leggere una linea sono sostazialmente due, \func{gets} e
   \funcdecl{char * fgets(char * string, int size, FILE *stream)}
   Scrive su \param{string} la linea letta da \param{stream} per un
   massimo di \param{size} byte.
   \funcdecl{char * fgets(char * string, int size, FILE *stream)}
   Scrive su \param{string} la linea letta da \param{stream} per un
   massimo di \param{size} byte.
-
-  Le funzioni restituiscono della stringa letta o \macro{NULL} in caso
-  di errore.
+  
+  \bodydesc{Le funzioni restituiscono della stringa letta o \macro{NULL}
+    in caso di errore.}
 \end{functions}
 
 
 \end{functions}
 
 
@@ -780,7 +825,7 @@ stream; se non si 
 
 Gli stream possono essere usati in applicazioni multi-thread allo stesso
 modo in cui sono usati nelle applicazioni normali, ma si deve essere
 
 Gli stream possono essere usati in applicazioni multi-thread allo stesso
 modo in cui sono usati nelle applicazioni normali, ma si deve essere
-consapovoli delle possibili complicazioni anche quando non si usano i
+consapevoli delle possibili complicazioni anche quando non si usano i
 thread, dato che l'implementazione delle librerie è influenzata
 pesantemente dalle richieste necessarie per garantirne l'uso coi thread.
 
 thread, dato che l'implementazione delle librerie è influenzata
 pesantemente dalle richieste necessarie per garantirne l'uso coi thread.