Newsgroup: it.comp.lang.c++
Titolo: Sistema di I/O

Gentili esperti del NG cosa si intende per "sistema a file bufferizzati"?
Grazie..!

 Gentili esperti del NG cosa si intende per "sistema a file bufferizzati"?
Il fatto che le operazioni di lettura/scrittura non avvengono byte per
byte ma a blocchi gestiti in modo trasparente dal sistema stesso.
EMG

EMG
Ok.!
(domanda OT) Questi blocchi ovviamente vengono memorizzati in ram..?
Es: Supponiamo di voler scivere in un file:
FILE *p;
p=fopen("nomefile.dat" "w");
gets(p);
fprintf(p, "%s", variabile di tipo stringa precedentemente dichiarata);
/* legge una stringa da tastiera e la memorizza in un blocco o buffer sulla
ram, che al momento della chiamata della funzione fprintf(), per mezzo del
canale (*p), scrive il blocco nel file. */
ALT..! Ho capito (penso..!)
"variabile di tipo stringa precedentemente dichiarata", funge da buffer o
blocco?
Non lo so ;-((    correggetemi se sbaglio.!



Mi sembra che l'istruzione gets che tu usi sia sbagliata in quanto la
gets ha un prototipo del tipo seguente mentre tu le passi come parametro
un puntatore a FILE anziche' un puntatore a char.
Dal manuale di Linux:
...
char *gets(char *s);
       ...
       gets() reads a line from stdin into the buffer pointed  to
       by  s  until either a terminating newline or EOF, which it
       replaces with '\0'.  No check for buffer overrun  is  per-
       formed ...
Per quanto ne so io le cose funzionano come illustrato nel seguente
esempio:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
    FILE *f;
    char stringa[100];
    if((f = fopen("file.dat","w")) == NULL) {
        perror("impossibile aprire il file");
        return -1;
    }
    //  pongo ogni byte di stringa = carattere con codice ascii 0
    //                               (da non confondere con '0')
     memset(stringa,0,sizeof(stringa));
    // prelevo la stringa da tastiera. Attenzione a non inserire troppi
    // caratteri per non "sforare" il buffer stringa, che ne 
    // puo' contenere al piu' 100.
    // UNO "SFORAMENTO" DI QUESTO GENERE PUO' AVERE EFFETTI IMPREVEDIBILI.
    // il tutto puo' anche funzionare per 100 volte e alla 101-esima dar
    // luogo a problemi! Questi errori sono difficili da individuare!!
    gets(stringa);
    // la seguente istruzione copia il contenuto di stringa (fino al primo
    // carattere 0 che delimita la fine della stringa escluso) 
    // sicuramente in un buffer "interno" del sistema, associato al file 
    // "file.dat".
    // Cioe' tale istruzione non scrive necessariamente
    // immediatamente su file (ma puo' anche farlo, se il sistema ritiene
    // opportuno scrivere subito sul file);
    fprintf(f,"%s",stringa); 
    // se vuoi forzare la scrittura immediata su file, senza aspettare i
    // comodi del sistema puoi inserire una istruzione del tipo seguente:
    fflush(f);
    //in questo modo costringi il sistema a scaricare subito su file
    // quello che e'  memorizzato nel buffer "interno" ad esso associato.
    // a questo punto potresti compiere ulteriori elaborazioni essendo
    // sicuro che la scrittura su file e' gia' avvenuta. Se non si fosse
    // forzato il flushing del buffer sul file, tramite fflush, a questo
    // punto non si saprebbe se la stringa e' gia' stata scritta sul file
    // o solo nel buffer "interno".
    // Ovviamente quando il buffer "interno" e' pieno dovra' essere 
    // il sistema a provvedere automaticamente al suo svuotamento mediante 
    // la scrittura su file del suo contenuto. (Scusa le ripetizioni, ma
    // quando io ero un principiante assoluto, le avrei gradite molto!).
    // per quanto ne so anche la seguente istruzione, che chiude il file,
    // costringe il sistema a "svuotare" il buffer "interno" prima di
    // effettuare la vera e propria chiusura del file.
    fclose(f);
}
In ogni caso, in C++ in genere si preferisce l'utilizzo della classe
fstream per la scrittura su file. I puristi del linguaggio potranno
spiegarti meglio di me per quale motivo.
Marco Guidi

 blocco?
No. Il meccanismo della bufferizzazione č (quasi) completamente
trasparente. Io scrivo i miei dati sul file e il sistema si preoccupa di
accodarli ad un buffer da lui stesso gestito. Quando il buffer č pieno
effettua la scrittura fisica. Ovviamente questa č una semplificazione.
EMG

effettua la scrittura fisica. Ovviamente questa č una semplificazione.
E' tutto chiaro.!
Ma questo avviene anche per la fase di lettura?

>//(Scusa le ripetizioni, ma quando io ero un principiante assoluto, le
avrei gradite molto!).
Scusa di cosa? anzi altro che ripetizioni, di alcuni concetti non ne sapevo
proprio niente :-)
FILE *p;
char str[100];
p=fopen("file.dat" "w");
gets(str);
fprintf(p, "%s", str);
Scritto cosě va bene come codice semplificato per capire il sistema I/O..?

 Scritto così va bene come codice semplificato per capire il sistema I/O..?
  Penso di si'.
 

 Ma questo avviene anche per la fase di lettura?
Mi sembra di si.
EMG

 Scritto così va bene come codice semplificato per capire il sistema I/O..?
Solo qualche appunto:
1. Dovresti controllare la variabile p per vedere se l'operazione di
fopen() è andata a buon fine:
   if ( p == 0 ) ... /* Gestisci l'errore */
2. Come mi sembra sia già stato detto, la funzione gets() non fa nessun
controllo sul superamento dei limiti dell'array. Meglio utilizzare
   fgets( str, 100, stdin );
3. Alla fine della scrittura dovresti chiudere il file:
   fclose( p );
EMG

 Ma questo avviene anche per la fase di lettura?
Si. La prima volte che si legge, viene riempito il buffer,
le letture successive leggono dal buffer, se il buffer
e' vuoto viene ririempito.
Nel caso di lettura da terminale di solito il buffer e'
di una riga (sarebbe particolarmente scomodo dover scrivere
qualche kb di roba prima che il programma cominci a leggere).
	Mauro

FILE *p;
char str[100];
if(p=fopen("file.dat" "w")==NULL){
    printf("Impossibile aprire il file");
    exit(1);
    }
fgets(str, 100, p);
fprintf(p, "%s", str);
fclose( p );
Così dovrebbe andare meglio..!

 Cosě dovrebbe andare meglio..!
Non credo proprio!  Prova con
if ((p = fopen("file.dat", "w")) == NULL)
    ^                    ^     ^
(perche' in un gruppo di C++ si usa <cstdio> ?  In C++ non si usa in
genere neppure il NULL ...)
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

Piccolo errore di sintassi.!
Grazie per l'attenzione