X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filestd.tex;h=d5c5ce1fde5a42db471be139083d5ba3b7fe0a6a;hp=5bf7cf48a2c56011684998bc940c0370c8e1d99d;hb=520fa6e7cd289a93a0955f3f91848ebd5b424250;hpb=da0899b61653d07d75c8df134906261f1afd2485 diff --git a/filestd.tex b/filestd.tex index 5bf7cf4..d5c5ce1 100644 --- a/filestd.tex +++ b/filestd.tex @@ -1,6 +1,6 @@ %% filestd.tex %% -%% Copyright (C) 2000-2002 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2003 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Prefazione", @@ -81,14 +81,13 @@ contengono tutte le informazioni necessarie a gestire le operazioni sugli stream, come la posizione corrente, lo stato del buffer e degli indicatori di stato e di fine del file. -Per questo motivo gli utenti non devono mai utilizzare direttamente o -allocare queste strutture, ma usare sempre puntatori del tipo \ctyp{FILE - *} ottenuti dalla libreria stessa (tanto che in certi casi il termine -di puntatore a file è diventato sinonimo di stream). Tutte le funzioni -della libreria che operano sui file accettano come parametri solo -variabili di questo tipo, che diventa accessibile includendo l'header -file \file{stdio.h}. - +Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare +queste strutture (che sono dei \textsl{tipi opachi}\index{tipo!opaco}) ma +usare sempre puntatori del tipo \ctyp{FILE *} ottenuti dalla libreria stessa +(tanto che in certi casi il termine di puntatore a file è diventato sinonimo +di stream). Tutte le funzioni della libreria che operano sui file accettano +come parametri solo variabili di questo tipo, che diventa accessibile +includendo l'header file \file{stdio.h}. \subsection{Gli stream standard} @@ -118,10 +117,7 @@ Nelle \acr{glibc} \var{stdin}, \var{stdout} e \var{stderr} sono effettivamente tre variabili di tipo \ctyp{FILE *} che possono essere usate come tutte le altre, ad esempio si può effettuare una redirezione dell'output di un programma con il semplice codice: -\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - fclose(stdout); - stdout = fopen("standard-output-file", "w"); -\end{lstlisting} +\includecodesnip{listati/redir_stdout.c} ma in altri sistemi queste variabili possono essere definite da macro, e se si hanno problemi di portabilità e si vuole essere sicuri, diventa opportuno usare la funzione \func{freopen}. @@ -138,7 +134,7 @@ uno degli aspetti pi riguarda l'aspetto della scrittura dei dati sul file. I caratteri che vengono scritti su di uno stream normalmente vengono -accumulati in un buffer e poi trasmessi in blocco\footnote{qiesta operazione +accumulati in un buffer e poi trasmessi in blocco\footnote{questa operazione viene usualmente chiamata \textsl{scaricamento} dei dati, dal termine inglese \textit{flush}.} tutte le volte che il buffer viene riempito, in maniera asincrona rispetto alla scrittura. Un comportamento analogo avviene @@ -153,7 +149,7 @@ Per lo stesso motivo, in tutte le situazioni in cui si sta facendo dell'input/output interattivo, bisognerà tenere presente le caratteristiche delle operazioni di scaricamento dei dati, poiché non è detto che ad una scrittura sullo stream corrisponda una immediata scrittura sul dispositivo (la -cosa è particolaemente evidente quando con le operazioni di input/output su +cosa è particolarmente evidente quando con le operazioni di input/output su terminale). Per rispondere ad esigenze diverse, lo standard definisce tre distinte @@ -488,40 +484,12 @@ 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 +\includecodesnip{listati/WriteVect.c} 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) -{ - if ( fwrite(vec, sizeof(*histo), 1, stream) !=1) { - perror("Write error"); - } - return nread; -} -\end{lstlisting} -%\normalsize +\includecodesnip{listati/WriteStruct.c} in cui si specifica la dimensione dell'intera struttura ed un solo elemento. @@ -855,7 +823,7 @@ illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono esattamente le stesse operazioni delle loro equivalenti, evitando però il lock implicito dello stream (vedi \secref{sec:file_stream_thread}). Come per le altre forma di I/O, dette funzioni hanno lo stesso nome della loro analoga -normale, con l'aggiuta dell'estensione \code{\_unlocked}. +normale, con l'aggiunta dell'estensione \code{\_unlocked}. Come abbiamo visto, le funzioni di lettura per l'input/output di linea previste dallo standard ANSI C presentano svariati inconvenienti. Benché @@ -907,16 +875,9 @@ e \var{*n} necessaria a contenere la linea. In tutti i casi si ottiene dalla funzione un puntatore all'inizio del testo della linea letta. Un esempio di codice può essere il seguente: -\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - size_t n = 0; - char *ptr = NULL; - int nread; - FILE * file; - ... - nread = getline(&ptr, &n, file); -\end{lstlisting} -e per evitare memory leak occorre ricordarsi di liberare \var{ptr} con -una \func{free}. +\includecodesnip{listati/getline.c} +e per evitare memory leak\index{memory leak} occorre ricordarsi di liberare +\var{ptr} con una \func{free}. Il valore di ritorno della funzione indica il numero di caratteri letti dallo stream (quindi compreso il newline, ma non lo zero di @@ -1003,7 +964,7 @@ si \cmd{\%X} &\ctyp{unsigned int}& Stampano un intero in formato esadecimale, rispettivamente con lettere minuscole e maiuscole. \\ - \cmd{\%f} &\ctyp{unsigned int}& Stampa un numero in virgola mobile con la + \cmd{\%f} &\ctyp{double} & Stampa un numero in virgola mobile con la notazione a virgola fissa \\ \cmd{\%e}, \cmd{\%E} &\ctyp{double} & Stampano un numero in virgola mobile con la @@ -1183,7 +1144,7 @@ restituito (si ricordi quanto detto in \secref{sec:proc_var_passing} a proposito dei \textit{value result argument}) l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando la stringa non serve -più, onde evitare memory leak. +più, onde evitare memory leak\index{memory leak}. Infine una ulteriore estensione GNU definisce le due funzioni \func{dprintf} e \func{vdprintf}, che prendono un file descriptor al posto dello stream. Altre @@ -1195,7 +1156,7 @@ davanti a \texttt{print}, sono trattate in dettaglio nella documentazione delle In corrispondenza alla famiglia di funzioni \func{printf} che si usano per l'output formattato, l'input formattato viene eseguito con le funzioni della famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf}, -\funcd{fscanf} e \funcd{sscanf}, i cui proprotipi sono: +\funcd{fscanf} e \funcd{sscanf}, i cui prototipi sono: \begin{functions} \headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una scansione di \file{stdin} cercando una corrispondenza di quanto letto con il @@ -1250,7 +1211,7 @@ scansione e conversione di quanto serve direttamente con una delle funzioni di conversione delle stringhe; se invece il formato è più complesso diventa più facile utilizzare uno strumento come \cmd{flex}\footnote{il programma \cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di - analizzatori lessicali, per i dettagli si può fare riferimento al manuale + analizzatori lessicali. Per i dettagli si può fare riferimento al manuale \cite{flex}.} per generare un analizzatore lessicale o il \cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo @@ -1621,7 +1582,7 @@ accade per \func{getc} e \func{putc}) sono realizzate come macro. La sostituzione di tutte le funzioni di I/O con le relative versioni \code{\_unlocked} in un programma che non usa i thread è però un lavoro -abbastanza noioso; per questo motivo le \acr{glibc} provvedono al +abbastanza noioso; per questo motivo le \acr{glibc} forniscono al programmatore pigro un'altra via\footnote{anche questa mutuata da estensioni introdotte in Solaris.} da poter utilizzare per disabilitare in blocco il locking degli stream: l'uso della funzione \funcd{\_\_fsetlocking}, il cui