Newsgroup: it.comp.lang.c++
Titolo: cin.eof()

Se qualcuno ctrl-z termina il file di input e cin.getline(..,..) restituisce
sempre una stringa vuota.
Come si puo'  fare per evitare questo inconveniente ?
Ciao
---------------------------------------
Email: sostituire "nospam" con "netsis"

Come si puo'  fare per evitare questo inconveniente ?
Mi sembra di capire che quello che desideri e` di riaprire cin
sullo standard input ogni volta che si verifica una end-of-file
su cin, giusto?  Un modo interamente portabile non esiste, che
io sappia, comunque in generale si puo` ottenere questo effetto
(assai peculiare!) con una ripetizione del costruttore di cin.
Ad esempio, con la libreria Standard C++ fornita con VC++5.0,
questa funzione puo` servire:
#include <iostream>
#include <fstream>
#include <new>
void reopen()
{
    using std::istream;
    if(std::cin.eof()) {
	std::cin.~istream();
	static std::filebuf* fin = new std::filebuf(stdin);
	new(&std::cin) istream(fin, true);
    }
}
Questa, naturalmente, va chiamata ogni volta che pensi
possa essersi verificato un EOF.  Ad esempio puoi incapsulare
la getline e questo controllo in una sola funzione, tipo:
#include <string>
#include <istream>
#include <iostream>
std::string
getcin()
{
    std::string result;
    std::getline(std::cin, result);
    reopen();
    return result;
}
Alex
--
 ____    Alex Martelli, Bologna, Italia -- email: 
al...@magenta.com
 \SM/___                                 
http://magenta.com/~alex
  \/\bi/     You never know what is enough unless you know what
     \/          is more than enough.

questa funzione puo` servire:
Ho provato a compilare con VC++4.0 e non c'e' stato verso. 
Ho provato anche con una versione del DJGPP abbastanza recente, ma non sono
riuscito a compilare. Qui pero' almeno esisteva il file <new>   *:)
<iostream> ed <fstream> senza .h non li ho trovati. Anche aggiungendo
l'estensione .h il codice non si compila. Probabilmente il VC++5.0 ha adottato
una sintassi molto recente del C++
Altro problema.
Se io richiamo una cin.get() il programma si blocca fino a quando  non viene
premuto un tasto della tastiera.
C'e' un modo standard per sapere se c'e' qualcosa da leggere senza dover
bloccare tutto il programma ?


bloccare tutto il programma ?
In generale, no.  Puoi provare con cin.rdbuf()->in_avail() [sempre sulle
implementazioni standard o ragionevolmente tali, come quella di VC++5;
se vuoi lavorare in ambienti non-standard, come VC++4 o DJGPP, ti
servirebbe molto poco sapere cosa dovresti fare SE standard fossero!],
ma la in_avail() ha come specifica solo quella di tornare il numero di
caratteri che possono sicuramente essere letti senza attendere -- se
risulta difficile determinarlo, e` perfettamente accettabile che essa sia
implementata tornando *sempre* 0, e questo mi pare facciano ora le
implementazioni piu` diffuse di iostream.
(Implementare in_avail() in modo da scoprire l'effettivo numero di
caratteri "disponibili" e` semplicemente un inferno in tutti i sistemi
operativi piu` diffusi -- su Unix renderebbe necessario bypassare tutto
il normale processing dell'input da tastiera scendendo al "raw input",
su Win32 analogamente richiederebbe uno sgradito flirt con le
"console API", ecc ecc; per questo iostream.h e` normalmente
implementato in piena compatibilita` con lo stdio.h o lo strato Unix
open/read/write ad esso immediatamente sottogiacente, e quindi
senza la possibilita` di scoperta "asincrona" di caratteri digitati da
tastiera).
Ti conviene chiamare la _kbhit() di <conio.h> e simili routine
dichiaratamente
non portatili, hai piu` probabilita` di prenderci...!-)  Oppure, crea un
thread secondario che puo` continuare a lavorare mentre quello
primario si ferma ad aspettare l'input, ecc ecc.
Alex