2011-10-21 13 views
6

¿Es posible usar getline() para leer un archivo válido sin establecer failbit? Me gustaría usar failbit para que se genere una excepción si el archivo de entrada no es legible.Use getline() sin configurar failbit

El siguiente código siempre muestra basic_ios::clear como la última línea, incluso si se especifica una entrada válida.

test.cc:

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

int main(int argc, char* argv[]) 
{ 
    ifstream inf; 
    string line; 

    inf.exceptions(ifstream::failbit); 
    try { 
     inf.open(argv[1]); 
     while(getline(inf,line)) 
      cout << line << endl; 
     inf.close(); 
    } catch(ifstream::failure e) { 
     cout << e.what() << endl; 
    } 
} 

input.txt:

the first line 
the second line 
the last line 

resultados:

$ ./a.out input.txt 
the first line 
the second line 
the last line 
basic_ios::clear 
+0

¿Cuándo espera que la failbit a ser elevada cuando se utiliza getline()? – selalerer

+0

Si el archivo no existe. ej. './a.out nosuchfile.txt' – Jeremiah

+0

Para eso puedes marcar is_open() luego de abrir el archivo. – selalerer

Respuesta

6

No se puede. La norma dice acerca getline:

Si la función extrae ningún carácter, se llama is.setstate(ios_base::failbit) que puede tirar ios_base::failure (27.5.5.4).

Si su archivo termina con una línea vacía, es decir, el último carácter es '\ n', entonces la última llamada a getline no lee caracteres y falla. De hecho, ¿cómo desea que termine el ciclo si no establece el error? La condición de while siempre sería cierta y funcionaría para siempre.

Creo que malinterpretas lo que significa failbit. Hace no significa que el archivo no se puede leer. Se usa más bien como una bandera que la última operación tuvo éxito. Para indicar una falla de bajo nivel, se usa el badbit, pero tiene poco uso para las transmisiones de archivos estándar. Por lo general, el failbit y el eofbit no deben interpretarse como situaciones excepcionales. badbit por otro lado debería, y yo argumentaría que fstream :: open debería haber establecido badbit en lugar de failbit.

De todos modos, el código anterior debe escribirse como:

try { 
    ifstream inf(argv[1]); 
    if(!inf) throw SomeError("Cannot open file", argv[1]); 
    string line; 
    while(getline(inf,line)) 
     cout << line << endl; 
    inf.close(); 
} catch(const std::exception& e) { 
    cout << e.what() << endl; 
} 
+0

Gracias por explicar las limitaciones de 'failbit'. Tu implementación funciona – Jeremiah

Cuestiones relacionadas