2010-09-02 9 views
6

yo soy muy nuevo en el mundo de C++ control de errores, pero me dijeron aquí:
Checking for file existence in C++Try-Catch bloque para C++ errores del archivo-IO no funciona

... que la mejor manera de cheques para la existencia del archivo fue con un bloque try-catch. De mi limitado conocimiento sobre el tema, esto suena como un buen consejo. Localicé este fragmento de código:
http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/Readafileintrycatchblock.htm

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

int main() 
{ 
    try{ 
     char buffer[256]; 
     ifstream myfile ("test.txt"); 

     while (! myfile.eof()) 
     { 
     myfile.getline (buffer,100); 
     cout << buffer << endl; 
     } 
    }catch(...){ 
    cout << "There was an error !\n"; 
    } 
    return 0; 
} 

... pero cuando compilo usando

g++ -Wall -pedantic -o test_prog main.cc 

y ejecutar el programa en un directorio donde test.txt no existe, el Prog sigue escupiendo líneas vacías a la terminal. ¿Alguien puede descubrir por qué?

También es esto una buena forma de comprobar la existencia de archivos en un archivo que realmente desea abrir y leer (¿en lugar de simplemente indexar un conjunto de archivos y verificarlos)?

Gracias!

+2

[Su lógica de lectura de archivos es incorrecta.] (Http://punchlet.wordpress.com/2009/12/01/hello-world/) Y use 'std :: string'. Y las transmisiones no usan excepciones, por defecto. – GManNickG

+0

No es mío ... Obtuve el código de un sitio tutorial, como mencioné;) entonces, si las transmisiones no usan excepciones, ¿cómo debo detectar errores si el archivo no existe? –

+0

Ah. El sitio web apesta entonces, no es una sorpresa. Debería obtener [un libro] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) si realmente desea aprender. – GManNickG

Respuesta

10

En C++ iostreams no arroje excepciones por defecto. Lo que necesita es

ifstream myfile("test.txt"); 

if(myfile) { 
    // We have one 
} 
else { 
    // we dont 
} 
+0

Entonces, ¿cuál es mejor (y por qué) - esto o las excepciones habilitadoras como se muestra dirkgently? –

+0

@Jason: No use excepciones. Solo prueba el objeto de flujo de archivos. –

11

Por defecto los objetos fstream no tiran. Debe usar void exceptions (iostate except); para establecer el comportamiento de excepción. Puede recuperar la configuración actual usando iostate exceptions () const;. Cambie su código solo un poco:

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

int main() 
{ 
    try{ 
     char buffer[256]; 
     ifstream myfile ("test.txt"); 
     myfile.exceptions (ifstream::eofbit | ifstream::failbit | ifstream::badbit); 
     while (file) 
     { 
     myfile.getline (buffer,100); 
     cout << buffer << endl; 
     } 
    }catch(std::exception const& e){ 
    cout << "There was an error: " << e.what() << endl; 
    } 
    return 0; 
} 
8

En primer lugar, para el bloque try a hacer ningún bien, necesita habilitar excepciones para la corriente.

En segundo lugar, un bucle como:

while (! myfile.eof()) 

conducirá a nada más que problemas, y que se está viendo que aquí. El problema (en este caso) es que cuando el archivo no se puede abrir, eof nunca se señalará: no puede/no llega al final del archivo porque es ningún archivo. Por lo tanto, su ciclo se ejecuta para siempre, en una búsqueda existencialista para el final de un archivo inexistente. Fijar el bucle, y las cosas mejoran en un apuro:

char buffer[256]; 
ifstream myfile ("test.txt"); 

while (myfile.getline(buffer,100)) 
{ 
    cout << buffer << endl; 
} 

Mientras estás en ello, un poco más de fijación no estaría de más (a menos que realmente quería decir para utilizar menos de la mitad del espacio que asignado para su buffer):

char buffer[256]; 
ifstream myfile ("test.txt"); 

while (myfile.getline(buffer,sizeof(buffer))) 
{ 
    cout << buffer << endl; 
} 

O, por supuesto, eliminar el problema en su totalidad:

std::string buffer; 
ifstream myfile("test.txt"); 
while (getline(myfile, buffer)) 
    cout << buffer << "\n"; 

Editar: en cuenta que ninguno de estos (al menos actualmente) depende de excepciones en absoluto. Están todos configurados para escribir una línea en la salida si logramos intentar leer una línea de la entrada. Si el archivo no se abrió, el cuerpo del bucle simplemente no se ejecutará, porque no podremos leer desde un archivo que no se abrió.Si queremos imprimir un mensaje de error que indique al usuario que el archivo no se abrió, tendríamos que manejarlo por separado de lo que está arriba. Por ejemplo:

ifstream myfile("test.txt"); 

if (!myfile) { 
    std::cerr << "File failed to open"; 
    return FAIL; 
} 

while (std::getline(myfile // ... 
Cuestiones relacionadas