Newsgroup: it.comp.lang.c++
Titolo: semplice domanda sulla lettura di file...

main() 
{ 
........  
fstream   f1; 
 ....... 
 char c; 
 
 f1.open("file.txt", ios::in); 
 
 
 cout << "Contenuto del file: " << endl << endl; 
 
  while(f1 >> c) 
    { 
      cout << c; 
    } 
 
return 0; 
}
Io non capisco il ciclo while :(
O meglio: i "c" che vengono stampati a video perchè "variano"?
Se in un file ho la stringa "vattelapesca" come mai l'istruzione di
controllo f1 >> c permette a while di passare in rassegna tutti i
caratteri di questa stringa?  


ad esempio:
  char r;
  while(cin >> r)
   cout << r;
con "cin" al posto della variabile di tipo file.
Quello sopra è un loop infinito, però per farlo "procedere" devo di
volta in volta premere invio. Perchè prima invece tutti i caratteri
della stringa all'interno del file vengono letti automaticamente?

 della stringa all'interno del file vengono letti automaticamente?
La domanda forse può essere semplice ma non è sicuramente banale! La 
differenza non è nella classe che tu utilizzi come stream, ossia istream nel 
caso di cin e fstream nel caso di f1, infatti puoi leggere benissimo un file 
con l'aiuto di un istream:
  filebuf fb;
  fb.open ("test.txt",ios::in);
  istream is(&fb); //istream non legge da std input
  char c;
  cout << "Contenuto del file: " << endl << endl;
  while(is >> c) {
      cout << c;
    }
Il fatto è che l'oggetto "cin" definito nel file iostream legge da standard 
input che normalmente è la tastiera (che richiede di premere INVIO per 
lanciare un interrupt e permettere la lettura dello stream). Questo però non 
è un vincolo infatti tramite la "redirezione" puoi usare cin per leggere per 
esempio da file:
  filebuf fb;
  fb.open ("test.txt",ios::in);
  istream is(&fb);
  char c;
  cin.rdbuf(is.rdbuf());
  while(cin >> c) { //ora cin legge da file
      cout << c;
    }
Andrea


grazie mille per le informazioni!
Se posso ne approfitto ancora per un'altra domanda riguardo il
seguente loop:
 .....
 char C;
  do 
    { C = cin.get();
     cout << C; }   
   while(C != ' ');
 ......
Il mio dubbio riguarda la funzione cin.get() ed è simile a quello che
chiedevo nelle domande precedenti.
In pratica, se mi è semplicissimo capire che inserendo un carattere e
premendo invio, il carattere inserito viene visualizzato in output
sullo schermo, non mi è altrettanto semplice capire perchè scrivendo
ad esempio "ciao", viene visualizzata tutta la parola "ciao" e non
solo "c".
Perchè cioè cin.get(), pur volendo come argomento un solo carattere,
dopo aver premuto "invio" procede a 4 assegnamenti, uno per ciascuna
lettera di "ciao" (ossia il ciclo viene compiuto 4 volte)????  

 lettera di "ciao" (ossia il ciclo viene compiuto 4 volte)????
Uhm... vedo che abbiamo qualche difficolta' con i "fondamentali" ;-)
Traduzione a fronte:
  do                          // Fai quel che segue:
    { C = cin.get();          //      leggi un carattere da cin
                              //      e assegnalo a C
     cout << C; }             //      stampa C su cout
                              //
   while(C != ' ');           // Finche' C non e' uguale a spazio
quindi, le operazioni all'interno del blocco vengono ripetute un certo
numero di volte (non noto a priori) finche' la condizione di uscita non
e' verificata.
Ma a questo punto, ti consiglio di studiare un altro po' su qualche
testo :-)
Saluti,
Fabio

e' verificata.
grazie per la risposta ma chiedevo qualcosa di leggermente diverso e,
credo, meno intuitivo.
Se chiamo cin.get(), vedo che il programma rimane in attesa di un
input.Nel caso più semplice, l'utente da tastiera preme un tasto, ad
esempio la lettera 'c' e preme 'INVIO'. In pratica ha premuto 2 tasti.
Se premo soltanto c cin.get() mica se ne accorge, ha bisogno del mio
INVIO.
Se ipotizzo che l'utente inserisca di volta in volta *solo* un
carattere + INVIO , allora il codice qui sopra "mi torna" senza
difficoltà...
Ciò che non capisco è il comportamento nel caso in cui l'utente
inserisca una parola come ad esempio "ciao" seguita da INVIO. Cioè
'c','i','a','o',INVIO.
Se cin.get() "parte" dopo l'INVIO (e uno soltanto!), perchè il ciclo
viene comunque ripetuto 4 volte? 
Devo forse "astrarre" il tutto e considerare il premere INVIO come un
segnale di "spedizione avvenuta" (e quello che ho spedito è stato un
"vagone" di 5 caratteri), e dopo che ho premuto INVIO il vagone è
totalmente nelle mani di cin.get() che lo gestisce "un char alla
volta" ???
In altre parole: INVIO non fa partire cin.get() ma più che altro fa
partire i caratteri verso "il programma" ???  


E' proprio così! :o)
cin e cout sono degli oggetti bufferizzati, che significa che il SO accumula 
i caratteri nel buffer sino a che arriva un interrupt che fa restituire il 
buffer all'oggetto.
cin.get() restituisce l'input alla tastiera e accumula i caratteri nel 
proprio buffer. Quando premi INVIO, cin ha nel buffer tutti i caratteri che 
hai inserito non solo il primo o l'ultimo. Quindi cin.get() con 'c' 'i' 'a' 
'o' INVIO, farà scattare 5 volte il ciclo, ma solo dopo che lo standard 
input avrà mandato tramite l'interrupt nuovamente il controllo al programma.
C'è di più. Devi tenere presente che il SO processa "per default" le 
stringhe in ingresso dallo std input una riga per volta (non un carattere o 
una stringa per volta), quindi il ciclo do viene eseguito 5 volte e non è 
possibile per esempio all'interno del ciclo usare funzioni tipo getchar() 
che richiederebbero nuovamente lo std input tramite "stdio.h" prima che il 
SO abbia raggiunto un fine linea.
Prova questo frammento di codice inserendo una stringa abbastanza lunga:
char s[200];
 while(cin.get(s,4)){
     cout << s <<endl;
     getchar(); //questo getchar() verrà soddisfatto solo quando il SO 
raggiungerà la fine linea nel buffer
 }
Se vuoi svuotare il buffer riempito dallo std input puoi eseguire questo 
ciclo:
while ((ch = cin.get()) != '\n' && ch != EOF);
questo ti legge (e quindi svuota) tutto il buffer: il primo controllo 
processa le linee, il secondo controlla che effettivamente siamo arrivati 
alla fine del buffer.
Andrea

 volta" ???
Qualcosa del genere. Tieni inoltre presente che l'input č bufferizzato. 
Ovvero la roba che scrivi finisce in un buffer. E il programma poi va a 
pescare dal buffer.
-enrico
-- 
Never argue with a logician.