2012-03-13 16 views
6

Estoy usando std::copy para copiar los objetos en std::deque a un archivo. El código funciona bien, pero necesito verificar si la copia fue exitosa y, en consecuencia, necesito establecer la bandera o si no arrojar una excepción.¿Cómo devolver el valor de std :: copy en caso de éxito o falla?

He buscado en Google pero no he podido encontrar la solución para comprobar si std::copy ha copiado correctamente los valores en el archivo.

Podría alguien arrojar una luz sobre él.

+3

no puedes comprobar el [estado de la secuencia de E/S] (http://en.cppreference.com/w/cpp/io/ios_base/iostate)? –

Respuesta

5

Si falla la escritura en el archivo, se configurarán los indicadores de error de la secuencia de archivos; puede verificarlos después de la copia o llamar a la función de miembro exceptions primero para que arroje una excepción por error. Si algo falla, se lanzará una excepción.

2

AFAIK El algoritmo std :: copy no comprueba nada y simplemente itera sobre todos los elementos y los copia al iterador de salida. Esto significa que debe proporcionar suficiente espacio en el iterador de salida, de lo contrario, el comportamiento no está especificado.

Por lo tanto, en su caso debe verificar que el archivo de salida sea escribible, etc. Una de las posibles maneras de verificar esto es usar banderas de error de uso para la secuencia de archivos que está utilizando, es decir, después de copiar ofstream es good (puede usar good(), eof(), fail() y bad() funciones para esto).

El segundo enfoque es verificar el valor de retorno de std::copy. A medida que devuelve un iterador al final del rango de destino (que apunta al elemento que sigue a la copia del último), puede calcular la diferencia entre el valor de retorno de std::copy y su iterador de salida y asegurarse de que sea igual al tamaño de su deque. P.ej. (Pseudocódigo)

OutputIterator result = std::copy(input.begin(), input.end(), output); 
assert(result - output == input.end() - input.begin()); 

EDIT: El segundo enfoque funciona sólo cuando output es también entrada de tipo repetidor, por lo std::distance que trabajar para ello. Será más correcto escribir:

assert(std::distance(output, result) == std::distance(input.begin(), input.end())); 
+0

Por supuesto, no puede hacer el segundo acercamiento con un 'std :: ostream_iterator', ya que es un iterador de salida,' std :: distance' tampoco funcionará. –

+0

Sí, tienes razón. El segundo enfoque solo funcionará cuando 'output' también sea un iterador de entrada. –

Cuestiones relacionadas