05 octubre 2005

El fin de fichero en C

Una pequeña tontería que suele despistar al principio.

Cuando leemos un fichero en C, normalmente leemos hasta que encontramos el fin de fichero, con la función feof(). Lo normal es hacer un bucle de este estilo

while (!feof(fichero))
{
...
}

El problema que no todo el mundo sabe es que feof() es cierto sólo cuando intentamos leer después de acabar el fichero.

Si el fichero está vacío y hacemos esto

fichero = fopen (...);
while (!feof(fichero))
{
fread (...);
tratarLeido(...);
}

abrimos el fichero. Como no hemos intentado leer, feof() es false y leemos datos. No hay datos que leer, fread() devolverá un error (que solemos ignorar) y tratamos los datos que no hemos leidos. En el siguiente bucle, como ya hemos intentado leer después de fichero, feof() es true y se acaba el bucle.

Si hubiera datos, trataríamos todo bien, pero después de leer los últimos datos y tratarlos, feof() sigue siendo false. Intentamos una nueva lectura fallida y tratamos los datos que no hemos leido.

La forma correcta de hacer este bucle, es hacer una lectura ANTES de mirar la condición feof(). Es decir

fichero = fopen(...);
fread (...)
while (!feof(fichero))
{
tratarLeido(...);
fread(...);
}

De esta forma, inmediatamente después de leer se hace la comprobación de si hemos obtenido el feof() y si no es así, tratamos el dato.

1 comentario:

Alejandro T dijo...

¿No sería válido lo siguiente?

while (!feof(Fich) && fread(...))
{
Tratar_Leido();
}