Sin embargo, los programadores de C ++ notan que lo que siempre sucede es que cin.eof () no devuelve "verdadero" hasta después de que la última línea se haya leído dos veces.
Eso no es lo que está pasando. El eofbit
no juega ningún papel en la conversión a un booleano ( stream::operator bool
(o operator void*
en c ++ anterior)). Solo los badbit
y failbit
están involucrados.
Suponga que está leyendo un archivo que contiene números separados por espacios en blanco. Un bucle basado cin.eof()
inevitablemente será incorrecto o estará lleno de if
pruebas. No estás leyendo hasta EOF. Estás leyendo números. Entonces, haga que su código exprese esa lógica:
while (stream >> some_var) {
process_value(some_var);
}
Esto funcionará si la última línea del archivo termina con 0 42\n
o solo 0 42
(no hay una nueva línea al final de la última línea en el archivo). Si el archivo termina con 0 42\n
, la última lectura correcta recuperará el valor 42 y leerá ese marcador final de final de línea. Tenga en cuenta que el marcador EOF aún no se ha leído. La función process_value
se llama con 42
. La siguiente llamada al operador de extracción de flujo >> lee el EOF, y dado que no se ha extraído nada, se establecerán ambos eofbit
y failbit
.
Supongamos, por otro lado, que el archivo termina con 0 42
(sin nueva línea al final de la última línea). La última lectura correcta recuperará el valor 42 que termina en el marcador EOF. Presumiblemente desea procesar ese 42. Es por eso eofbit
que no juega un papel en el operador de conversión booleana de flujo de entrada. En la próxima llamada al operador de extracción de flujo >>, la maquinaria subyacente rápidamente ve que eofbit
ya está configurado. Esto resulta rápidamente en la configuración de failbit
.
¿Por qué el primer fragmento de código siempre no funciona correctamente?
Porque no deberías estar buscando EOF como condición de bucle. La condición del bucle debe expresar lo que está intentando hacer, que es (por ejemplo), extraer números de una secuencia.