[C con Clase] problemas con la posicion del puntero en un fichero, funciones fread, frwite, fseek etc.

Salvador Pozo salvador en conclase.net
Lun Mar 5 23:12:08 CET 2012


El pasado 2012-03-05 21:30:06, Albert_Munich escribió:
 
A> Hola, he intentado siguiendo tus indicaciones solucionar el problema, he
A> creado un contador, que recorre el fichero, y ahora lee todo ordenador, a
A> mas con la funcion feof nueva ya no se va hasta el infinito. el problema
A> ahora esta en la primera palabra que lee y la ultima.
A> la primera palabra no la lee, va directo a la segunda, y la ultima palabra
A> no la repite infinitamente, xo la repite 1 vez mas, es decir, la pone dos
A> veces. no se como solucionarlo, ya que el contador con i=0 indica clarament
A> que lea la primera palabra, y con la funcion feof, en teoria, no tendria k
A> volver a entrar en el while, por tanto, no entiendo porque repite la ultima
A> palabra antes de acabar.

Hola:

Esta vez es más fácil. El error está aquí:
----8<------
        if(fread(&palabra, sizeof(palabra), 1, fichero)) {
            fread(&palabra, sizeof(palabra), 1, fichero);
...
----8<------

El fallo es leer dos veces la palabra, con la lectura del interior del "if" es suficiente. En la primera iteración, la segunda lectura anula la lectura de la primera palabra, por eso no sale la primera.

En la última iteración la segunda lectura falla, pero se mantiene la palabra leída en la primera (la del if).

Puedes compactar mucho tu programa:
- No necesitas la estructura t__virt_palabra para nada. Ya que lees una estructura "palabra" desde el fichero, para actualizar el fichero bastará con incrementar palabra.errores o palabra.aciertos, y volver a usar la misma "palabra" para escribirla en el fichero, en la posición en la que estaba. Esto te evita asignar valores que no cambian: las palabras y el contador que no modificas.
- Evita repetir el código, por ejemplo, cuando verificas si el usuario ha acertado o no la respuesta, muchas de las sentencias son comunes tanto al if como al else, saca esas sentencias del bloque if..else.
- No necesitas asignar un valor inicial a la respuesta, ya que la primera vez que se evalúa es después de leerla desde el teclado.
- Evita usar la función gets, en su lugar usa fgets, por ejemplo, fgets(respuesta, 30, stdin);

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase