Probar stream.good() o !stream.eof() lee la última línea dos veces [duplicado]

Resuelto Prabhu asked hace 13 años • 3 respuestas

Posible duplicado:
¿Por qué iostream::eof dentro de una condición de bucle se considera incorrecto?

Tengo el siguiente fragmento de código:

ifstream f("x.txt");
string line;
while (f.good()) {
  getline(f, line);
  // Use line here.
}

Pero esto lee la última línea dos veces. ¿Por qué sucede esto y cómo lo soluciono?

Algo muy similar sucede con:

ifstream f("x.txt");
string line;
while (!f.eof()) {
  getline(f, line);
  // Use line here.
}
Prabhu avatar Dec 01 '10 19:12 Prabhu
Aceptado

Muy, muy raramente querrás marcar bad, eof y good. En particular para eof (ya que !stream.eof() es un error común), el hecho de que la secuencia se encuentre actualmente en EOF no significa necesariamente que la última operación de entrada haya fallado; por el contrario, no estar en el EOF no significa que la última entrada haya sido exitosa.

Todas las funciones de estado del flujo (fallo, malo, eof y bueno) le indican el estado actual del flujo en lugar de predecir el éxito de una operación futura. Verifique la secuencia en sí (que equivale a una verificación de falla invertida) después de la operación deseada:

if (getline(stream, line)) {
  use(line);
}
else {
  handle_error();
}

if (stream >> foo >> bar) {
  use(foo, bar);
}
else {
  handle_error();
}

if (!(stream >> foo)) {  // operator! is overloaded for streams
  throw SomeException();
}
use(foo);

Para leer y procesar todas las líneas:

for (std::string line; getline(stream, line);) {
  process(line);
}

En concreto, good() tiene un nombre incorrecto y no equivale a probar la secuencia en sí (lo que hacen los ejemplos anteriores).

Fred Nurk avatar Dec 01 '2010 13:12 Fred Nurk

Solo usa

ifstream f("x.txt");
while (getline(f, line)) {
    // whatever
}

Esta es la forma idiomática de escribir dicho bucle. No he podido reproducir el error (en una máquina Linux).

Fred Foo avatar Dec 01 '2010 12:12 Fred Foo