2011-04-29 12 views
13

Estoy probando try, catch, throw statements en C++ para el manejo de archivos, y he escrito un código ficticio para detectar todos los errores. Mi pregunta es para verificar si los tengo bien, necesito que ocurra un error. Ahora puedo verificar fácilmente infile.fail() simplemente no creando un archivo con el nombre requerido en el directorio. Pero ¿cómo voy a poder verificar lo mismo para outfile.fail() (outfile es ofstream donde como infile es ifstream). En ese caso, ¿será verdadero el valor de outfile.fail()?¿Cuándo fallará ofstream :: open?

código de ejemplo [de los comentarios sobre la respuesta del unapersson, simplificados para hacer más clara -Zack tema]:

#include <fstream> 
using std::ofstream; 

int main() 
{ 
    ofstream outfile; 
    outfile.open("test.txt"); 
    if (outfile.fail()) 
     // do something...... 
    else 
     // do something else..... 
    return 0; 
} 

Respuesta

6

Por defecto, y por diseño, las corrientes de C++ no generan excepciones en caso de error. No intente escribir código que suponga que lo hacen, aunque sea posible hacerlo. En su lugar, en la lógica de la aplicación, compruebe cada operación de E/S para ver si hay un error y solucione el problema, posiblemente lanzando su propia excepción si ese error no se puede resolver en el lugar específico en el que se produce el código.

La manera canónica de probar las secuencias y las operaciones de flujo no es probar indicadores de flujo específicos, a menos que sea necesario. En su lugar:

ifstream ifs("foo.txt"); 

if (ifs) { 
    // ifs is good 
} 
else { 
    // ifs is bad - deal with it 
} 

de manera similar para las operaciones de lectura:

int x; 
while(cin >> x) { 
    // do something with x 
} 

// at this point test the stream (if you must) 
if (cin.eof()) { 
    // cool - what we expected 
} 
else { 
    // bad 
} 
+0

Bueno, solo quiero saber cuándo se revelará outfile.fail(). – Scranton

+0

@Scranton Publica un código. –

+0

# include # include # include # include using namespace std; int main() { string filename = "test.txt"; de archivo externo; outfile.open (filename.c_str()); if (outfile.fail()) hacer algo ...... else hacer otra cosa ..... return 0; } Entonces, ¿cómo puedo obtener la cláusula if ??? – Scranton

22

La página open(2) hombre en Linux tiene alrededor de 30 condiciones. Algunos más interesantes son:

  • Si el archivo existe y no tiene permiso para escribirlo.
  • Si el archivo no existe, y no tiene permiso (en el directorio) para crearlo.
  • Si no tiene permiso de búsqueda en algún directorio principal.
  • Si pasa un char* falso para el nombre de archivo.
  • Si, al abrir un archivo de dispositivo, presiona CTRL-C.
  • Si el núcleo encontró demasiados enlaces simbólicos al resolver el nombre.
  • Si intenta abrir un directorio para escribir.
  • Si el nombre de ruta es demasiado largo.
  • Si su proceso ya tiene demasiados archivos abiertos.
  • Si el sistema tiene demasiados archivos abiertos ya.
  • Si el nombre de ruta hace referencia a un archivo de dispositivo, y no hay tal dispositivo en el sistema.
  • Si el kernel se ha quedado sin memoria.
  • Si el sistema de archivos está lleno.
  • Si un componente de la ruta de acceso no es un directorio.
  • Si el archivo está en un sistema de archivos de solo lectura.
  • Si el archivo es un archivo ejecutable que se está ejecutando actualmente.
+3

Y vale la pena señalar que el estándar C++ no proporciona diagnósticos específicos para ninguno de estos. –

+1

'errno' y' strerror' son estándar C (++). (Sin embargo, los * códigos * solo están estandarizados por POSIX). – zwol

3

Para obtener ofstream::open a fallar, es necesario organizar para que sea imposible crear el archivo llamado.La forma más fácil de hacerlo es crear un directorio del mismo nombre exacto antes de ejecutar el programa. Aquí hay un programa de demostración casi completo; arreglando para eliminar confiablemente el directorio de prueba si y solo si usted lo creó, lo dejo como un ejercicio.

#include <iostream> 
#include <fstream> 
#include <sys/stat.h> 
#include <cstring> 
#include <cerrno> 

using std::ofstream; 
using std::strerror; 
using std::cerr; 

int main() 
{ 
    ofstream outfile; 

    // set up conditions so outfile.open will fail: 
    if (mkdir("test.txt", 0700)) { 
     cerr << "mkdir failed: " << strerror(errno) << '\n'; 
     return 2; 
    } 

    outfile.open("test.txt"); 
    if (outfile.fail()) { 
     cerr << "open failure as expected: " << strerror(errno) << '\n'; 
     return 0; 
    } else { 
     cerr << "open success, not as expected\n"; 
     return 1; 
    } 
} 

no hay una buena manera de asegurar que la escritura a un fstream falla. Probablemente crearía un falso simulacro de escritura fallida, si tuviera que probar eso.