Leyendo desde un archivo de texto hasta que EOF repita la última línea [duplicado]

Resuelto Ashwin Nanjappa asked hace 16 años • 7 respuestas

El siguiente código C++ utiliza un objeto ifstream para leer números enteros de un archivo de texto (que tiene un número por línea) hasta que llega a EOF . ¿Por qué lee dos veces el número entero de la última línea? ¿Cómo arreglar esto?

Código:

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

int main()
{
    ifstream iFile("input.txt");    // input.txt has integers, one per line

    while (!iFile.eof())
    {
        int x;
        iFile >> x;
        cerr << x << endl;
    }

    return 0;
}

entrada.txt :

10  
20  
30

Producción :

10  
20  
30  
30

Nota : Me he saltado todo el código de verificación de errores para mantener el fragmento de código pequeño. El comportamiento anterior se observa en Windows (Visual C++), cygwin (gcc) y Linux (gcc).

Ashwin Nanjappa avatar Aug 22 '08 09:08 Ashwin Nanjappa
Aceptado

Simplemente siga de cerca la cadena de eventos.

  • Agarra 10
  • Agarra 20
  • Agarra 30
  • Agarra EOF

Mire la penúltima iteración. Agarraste 30 y luego continuaste buscando EOF. No has llegado al EOF porque la marca EOF aún no se ha leído (hablando "binariamente", su ubicación conceptual está justo después de la línea 30). Por lo tanto, continúa con la siguiente iteración. x todavía es 30 de la iteración anterior. Ahora lees la transmisión y obtienes EOF. x sigue siendo 30 y se eleva el ios::eofbit. La salida es stderr x (que es 30, como en la iteración anterior). A continuación, verifica si hay EOF en la condición del bucle y esta vez sale del bucle.

Prueba esto:

while (true) {
    int x;
    iFile >> x;
    if( iFile.eof() ) break;
    cerr << x << endl;
}

Por cierto, hay otro error en tu código. ¿Alguna vez intentaste ejecutarlo en un archivo vacío? El comportamiento que obtienes es exactamente por la misma razón.

wilhelmtell avatar Aug 22 '2008 02:08 wilhelmtell

Me gusta este ejemplo, que por ahora omite la marca que podrías agregar dentro del bloque while:

ifstream iFile("input.txt");        // input.txt has integers, one per line
int x;

while (iFile >> x) 
{
    cerr << x << endl;
}

No estoy seguro de qué tan seguro es...

Patrick Loz avatar Aug 22 '2008 02:08 Patrick Loz