[C con Clase] (sin asunto)

Steven R. Davidson vze266ft en verizon.net
Mie Nov 29 10:16:03 CET 2006


Hola Marcelo,

Marcelo Vega wrote:

> Tengo el siguiente codigo.
> Lo que quiero es que depsues de llenar las estructuras, poder encontrar 
> el caballo buskandolo por el jinete, osea una komparacion de strings.
> Al haver fread esta mi consulta. Se hace fread hasta ke el flag sea 1 o 
> se llegue a fin de pagina.
> Cuando salga del while, deberia tener kargada en memoria la ultima 
> estructura leida, no? esa es mi duda, porque despues al imprimir por 
> pantalla me muestra la ultima estructura en ser llenada, no la ultima en 
> ser leida con el fread.
> 

Efectivamente, 'carrerras' contiene la última estructura en memoria. 
Esto es porque tienes algunos errores en tu código. Te voy comentando el 
código a medida que lo vaya viendo.

> 

[CORTE]

>     if ((ptr = fopen("listado.txt", "w")) != NULL)
>     {
>         for(i=0; i<n_carr; i++)
>         {
>             printf("Ingrese numero carrera\n");
>             fflush(stdin);

Este uso de 'fflush()' no es estándar, por lo que no todas las 
implementaciones tienen por qué definirlas. La función estándar 
'fflush()' sólo funciona con canales o flujos (streams, en inglés) de 
salida, no de entrada.

>             scanf("%d", &carreras.numero);
> 
>             printf("Ingrese id del ganador\n");
>             fflush(stdin);
>             scanf("%d", &carreras.id_ganador);
> 
>             for(j=0; j<n_cab; j++)
>             {
>                 printf("Ingrese id caballo %d\n", j+1);
>                 fflush(stdin);
>                 scanf("%d", &carreras.caballos.id);
> 
>                 printf("Ingrese jinete del caballo %d\n", j+1);
>                 fflush(stdin);
>                 gets(carreras.caballos.jinete);
> 

Sugiero usar 'fgets()', en lugar de 'gets()', al ser más seguro que 
'gets()'.

>                 printf("Ingrese tiempo del caballo %d\n", j+1);
>                 fflush(stdin);
>                 scanf("%f", &carreras.caballos.tiempo);
>             }

Este bucle no tiene sentido ya que el miembro 'caballos' es una sola 
estructura y no una serie de ellas. Por lo tanto, estás sobreescribiendo 
la misma estructura.

>         }
> 
>         fwrite(&carreras, sizeof(carreras), 1, ptr);

Aquí, invocas 'fwrite()' una sola vez, por lo que estás escribiendo en 
el fichero un solo registro. Para ser más preciso, el último registro 
introducido por el usuario es el que permanece escrito en el fichero.

La solución implica redefinir tus estructuras y crear varianbles para 
que sean arrays. Por ejemplo,

struct caballo
{
     int id;
     char jinete[MAX];
     float tiempo;
};

struct carrera
{
     int numero;
     int id_ganador;
     struct caballo caballos[n_cab];
};
...
struct carrera carreras[n_carr];

Esto tiene más sentido ya que tenemos varias carreras, en las que 
contienen varios caballos.

Obviamente, tendrás que reescribir las sentencias anteriores para usar 
arrays. Luego, la escritura al fichero implica una sola invocación a 
'fwrite()' indicando la cantidad de estructuras. En tu caso, esto sería,

fwrite( carreras, sizeof carreras, n_carr, ptr );

>     }
>     fclose(ptr);
>     
>     printf("ingrese nombre del jinete a buscar\n");
>     fflush(stdin);
>     gets(jinete_opcion);
> 
>     if ((ptr = fopen("listado.txt", "r")) != NULL)
>     {
>         while ((!feof(ptr)) && (flag = 0))

Aquí tienes un error lógico. Estás asignando el valor de 0 (cero) a 
'flag'. Por lo tanto, esta condición siempre será falsa. He aquí el 
porqué 'carreras' contiene el último registro en memoria, ya que nunca 
llega a leer del fichero.

Supongo que querías escribir algo como:

while( !feof(ptr) && 0 == flag )

Por esta razón, recomiendo definir constantes o incluso un tipo 
enumerado. Por ejemplo,

enum { NO_ENCONTRADO, ENCONTRADO };

o incluso,

#define NO_ENCONTRADO 0
#define ENCONTRADO 1

Ahora puedes usar las constantes, en lugar de usar las literales 
directamente.

>         {
>             fread(&carreras, sizeof(carreras), 1, ptr);
>             if (strcmp(carreras.caballos.jinete, jinete_opcion) == 0)
>                 flag = 1;
>         }
>     }
>     fclose(ptr);
> 

Para la lectura, puedes leer todos los registros en una sola lectura, 
para luego procesar la información desde la memoria. En tu caso, 
decidiste ir leyendo y procesando cada registro. Puedes elegir la opción 
que más te guste.


Espero que esto te ayude.

Steven








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