2012-09-27 16 views
6

En C++, ¿hay algún caso en el que std::ifstream open() sea exitoso, pero std::ifstream good() puede ser falso?¿Abrió con éxito pero no es bueno?

EDIT: probado 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; 
} 

volverá: 1, 0, 0, 0 para un archivo vacío que significa good = TRUE y eof = fail = bad = FALSE. Es normal ?

Respuesta

3

Después de verificar el texto real en la norma, no creo eofbit se permite que se fijará después de un open: badbit puede fijarse cuando ya la intemperie real se produce una excepción (creo — la norma no dice realmente qué debería pasar en este caso); failbit debe establecerse si falla la apertura, o si la búsqueda después de la apertura (si ate está configurado) falla; pero no parece haber ningún caso donde se pueda establecer eofbit.

No es que llamar a std::istream::good() es una buena solución en este caso. (Sería interesante saber lo que el PO está tratando de lograr. Sea lo que sea, llamando std::istream::good() probablemente no es la solución correcta.)

Si std::ifstream::good() vuelve false, la siguiente entrada fallará. Si devuelve true, no le dice nada: la siguiente entrada puede tener éxito, pero también puede fallar.

+0

+1 la implementación en realidad podría no probar el archivo hasta que intente una lectura y esa lectura falle. –

+0

@ DavidRodríguez-dribeas En general, no tiene sentido probar el 'eofbit' hasta que falle una entrada. Y el hecho de que 'std :: ifstream :: good()' pruebe el 'eofbit' (además de los otros bits de estado) lo hace prácticamente inútil. –

+0

No creo que haya ningún * daño * en la persona que pregunta usando 'bueno' ¿hay alguno? Es solo que dado que el 'eofbit' no está configurado, también podrías probar la transmisión de la verdad como siempre. Supongo que hay daño de legibilidad al hacer algo inútilmente anormal, y como dices, casi cualquier uso de "bueno" es inútilmente anormal ... –

2

Si el archivo está vacío, el eofbit se activará pero el archivo seguirá abierto así que sí.

+0

Mi entendimiento es que es eofbit solo se establece si una operación intenta leer más allá del final del archivo. Es eso incorrecto? – templatetypedef

+0

@templatetypedef No estoy seguro. Es cierto que la implementación no es necesaria para establecer 'eofbit' si el archivo está vacío, pero no estoy seguro de que no esté permitido. Si 'eofbit' está configurado, significa que la siguiente entrada fallará porque no hay datos. (Si 'eofbit' no está configurado, no significa nada.) –

+1

Esto es incorrecto según mis lecturas de la norma.Todos los bits de estado en la secuencia de archivos se borran cuando el '' open() 'del búfer de archivo subyacente tiene éxito. El estado se establece en 'failbit' si el buffer del archivo' open() 'falla. De cualquier manera, el 'eofbit' será claro después de la llamada al flujo de archivos' open() '. –

1

ifstream::open devuelve nulo, así que tenga cuidado con lo que quiere decir al decir que es "exitoso".

La norma dice para basic_ifstream::open (27.9.1.9):

Efectos: Las llamadas rdbuf() -> open (s, modo | ios_base :: in). Si esa función no devuelve un puntero nulo llama a clear(), las llamadas de otro modo setstate (failbit) (que puede tirar ios_base :: fallo)

Por lo tanto, si la llamada para abrir en el filebuf devuelve un valor indicando éxito, entonces ifstream::open borra todos los bits de error, por lo que good() necesariamente devuelve verdadero.

Si la llamada a abrir en el archivobuf devuelve un valor que indica un error, entonces ifstream::open puede regresar sin lanzar una excepción. Este comportamiento podría confundirse con "éxito", pero en este caso good() devuelve falso porque se establece el failbit.

No es del todo claro por qué esto establece la failbit en lugar de la badbit, pero no creo que mi falta de entendimiento consigue de la manera de informar sobre los hechos :-)

Cuestiones relacionadas