2012-09-27 12 views
6

In C++, c'è un caso in cui std::ifstream open() può avere successo, ma std::ifstream good() può essere falso?Aperto con successo ma non buono?

EDIT: provato con g ++ 4.7.1

#include <iostream> 
#include <fstream> 
int main(int argc, char *argv[]) 
{ 
    std::ifstream filestream("testfile"); 
    std::cout<<filestream.good()<<std::endl; 
    std::cout<<filestream.eof()<<std::endl; 
    std::cout<<filestream.fail()<<std::endl; 
    std::cout<<filestream.bad()<<std::endl; 
    return 0; 
} 

tornerà: 1, 0, 0, 0 per un file vuoto che significa good = TRUE e eof = fail = bad = FALSE. È normale ?

risposta

3

Dopo aver verificato il testo effettivo nella norma, non credo eofbit è permesso di essere impostato dopo un open: badbit possono essere impostate se l'apertura effettiva genera un'eccezione (credo — lo standard in realtà non dire cosa dovrebbe accadere in questo caso); failbit deve essere impostato se l'apertura non riesce o se la ricerca dopo l'apertura (se ate è fallita); ma non sembra esserci alcun caso in cui è possibile impostare eofbit.

Non che chiamare std::istream::good() sia una buona soluzione in questo caso. (Sarebbe interessante sapere che cosa il PO sta cercando di raggiungere. Qualunque cosa sia, chiamando std::istream::good() probabilmente non è la giusta soluzione.)

Se std::ifstream::good() ritorna false, la prossima entrata fallirà. Se restituisce true, non dice nulla: l'input successivo può riuscire, ma potrebbe anche non riuscire.

+0

+1 l'implementazione potrebbe effettivamente non testare il file finché non si tenta una lettura e quella lettura non riesce. –

+0

@ DavidRodríguez-dribeas In generale, non ha senso testare 'eofbit' finché un input non ha avuto esito positivo. E il fatto che 'std :: ifstream :: good()' testa l''eofbit' (oltre agli altri bit di stato) lo rende praticamente inutile. –

+0

Non penso ci sia alcun * danno * nell'interrogante usando 'buono' c'è? È solo che dal momento che il 'eofbit' non è impostato, si potrebbe anche testare il flusso per la verità come normale. Suppongo che ci sia un danno di leggibilità nel fare qualcosa di inutilmente anormale, e come dici tu praticamente qualsiasi uso di 'buono' è inutilmente anormale ... –

2

Se il file è vuoto, l'eofbit verrà attivato ma il file sarà ancora aperto, quindi sì.

+0

La mia comprensione è che è eofbit imposta solo se un'operazione tenta di leggere oltre la fine del file. È sbagliato? – templatetypedef

+0

@templatetypedef Non sono sicuro. È certo che l'implementazione non è necessaria per impostare 'eofbit' se il file è vuoto, ma non sono sicuro che non sia permesso. Se 'eofbit' è impostato, significa che il prossimo input fallirà perché non ci sono dati. (Se 'eofbit' non è impostato, non significa nulla.) –

+1

Questo non è corretto per le mie letture dello standard.Tutti i bit di stato nel flusso di file vengono cancellati quando il buffer del file sottostante 'open()' riesce. Lo stato è impostato su 'failbit' se il buffer di file' open() 'fallisce. In entrambi i casi, 'eofbit' sarà chiaro dopo la chiamata al file stream' open() '. –

1

ifstream::open restituisce nulla, quindi fai attenzione esattamente a cosa intendi dicendo che è "riuscito".

Lo standard dice per basic_ifstream::open (27.9.1.9):

Effetti: chiamate rdbuf() -> open (s, modalità | ios_base :: in). Se tale funzione non restituisce un puntatore nullo chiama clear(), altrimenti le chiamate setstate (failbit) (che possono gettare ios_base :: fallimento)

Quindi, se la chiamata per aprire sul filebuf restituisce un valore indicando il successo, quindi ifstream::open cancella tutti i bit di errore e quindi good() restituisce necessariamente true.

Se la chiamata per aprire sul filebuf restituisce un valore che indica un errore, è possibile restituire ifstream::open senza generare un'eccezione. Questo comportamento potrebbe essere confuso con "successo", ma in questo caso good() restituisce false perché è impostato il failbit.

Non è del tutto chiaro per me perché questa imposta la failbit piuttosto che il badbit, ma non credo che la mia mancanza di comprensione ottiene nel modo di riportare i fatti :-)

Problemi correlati