c++ para que - ¿Por qué se considera incorrecto iostream :: eof dentro de una condición de bucle?





2 Answers

Línea inferior superior: con el manejo adecuado del espacio en blanco, lo siguiente es cómo se puede usar eof (e incluso, ser más confiable que fail() para la comprobación de errores):

while( !(in>>std::ws).eof() ) {  
   int data;
   in >> data;
   if ( in.fail() ) /* handle with break or throw */; 
   // now use data
}    

( Gracias a Tony D por la sugerencia de resaltar la respuesta. Vea su comentario a continuación para ver un ejemplo de por qué esto es más sólido ) .

El principal argumento en contra del uso de eof() parece que falta una sutileza importante sobre el papel del espacio en blanco. Mi propuesta es que verificar eof() explícitamente no solo no es " siempre incorrecto ", lo que parece ser una opinión primordial en este y otros hilos similares, sino que, con el manejo adecuado del espacio en blanco, proporciona un limpiador y un manejo de errores más confiable, y es la solución siempre correcta (aunque no necesariamente la más tersa).

Para resumir lo que se sugiere como la terminación "correcta" y el orden de lectura es lo siguiente:

int data;
while(in >> data) {  /* ... */ }

// which is equivalent to 
while( !(in >> data).fail() )  {  /* ... */ }

La falla debida al intento de lectura más allá de eof se toma como condición de terminación. Esto significa que no hay una manera fácil de distinguir entre una transmisión exitosa y otra que realmente falla por otras razones además de eof. Tome las siguientes corrientes:

  • 1 2 3 4 5<eof>
  • 1 2 a 3 4 5<eof>
  • a<eof>

while(in>>data) termina con un conjunto de failbit para las tres entradas. En el primero y el tercero, eofbit también se establece. Por lo tanto, más allá del bucle, se necesita una lógica extra muy fea para distinguir una entrada correcta (1ª) de una incorrecta (2ª y 3ª).

Considerando que, tome lo siguiente:

while( !in.eof() ) 
{  
   int data;
   in >> data;
   if ( in.fail() ) /* handle with break or throw */; 
   // now use data
}    

Aquí, in.fail() verifica que siempre que haya algo para leer, este sea el correcto. Su propósito no es un simple terminador de bucle while.

Hasta ahora todo bien, pero ¿qué sucede si hay un espacio final en la secuencia? ¿ eof() la principal preocupación contra eof() como terminador?

No necesitamos rendir nuestro manejo de errores; solo come el espacio en blanco:

while( !in.eof() ) 
{  
   int data;
   in >> data >> ws; // eat whitespace with std::ws
   if ( in.fail() ) /* handle with break or throw */; 
   // now use data
}

std::ws omite cualquier espacio al final potencial (cero o más) en el flujo al configurar el eofbit , y no el failbit . Por lo tanto, in.fail() funciona como se espera, siempre que haya al menos un dato para leer. Si también se aceptan flujos en blanco, la forma correcta es:

while( !(in>>ws).eof() ) 
{  
   int data;
   in >> data; 
   if ( in.fail() ) /* handle with break or throw */; 
   /* this will never fire if the eof is reached cleanly */
   // now use data
}

Resumen: Un momento correctamente construido while(!eof) no solo es posible y no es incorrecto, sino que permite que los datos se localicen dentro del alcance, y proporciona una separación más clara de la verificación de errores de la actividad habitual. Dicho esto, while(!fail) es indudablemente un lenguaje más común y conciso, y puede preferirse en escenarios simples (datos únicos por tipo de lectura).

utiliza dev funcion

Acabo de encontrar un comentario en this respuesta que dice que el uso de iostream::eof en una condición de bucle es "casi seguro que está mal". Generalmente uso algo así como while(cin>>n) , que supongo que comprueba implícitamente la EOF, ¿por qué la comprobación de eof utilizando explícitamente iostream::eof incorrecta?

¿En qué se diferencia del uso de scanf("...",...)!=EOF en C (que a menudo utilizo sin problemas)?




1 while (!read.fail()) {
2     cout << ch;
3     read.get(ch);
4 }

Si usa la línea 2 en 3 y la línea 3 en 2, se imprimirá ch dos veces. Así que cout antes de leer.




Related