[C con Clase] Duda que me está volviendo loco

Davidson, Steven srd4121 en njit.edu
Lun Ene 11 22:41:49 CET 2016


Hola Hl3,

Creo que sería de ayuda saber la definición de 'struct miembro' y si
coincide exactamente con el formato del fichero, "fichas.dat". De todas
maneras, existen algunos matices en tu código a destacar:

- Si vas a usar un puntero que apunte a otras cadenas, no sugiero apuntar a
una cadena literal. En su lugar, usa un array para definir tal cadena
literal y haz que 'lista' apunte a ella inicialmente. Por ejemplo,

char szMensajePorDefecto[] = "No encuentro esa persona";
char *lista = szMensajePorDefecto;
...

Sin embargo, en este caso, como quieres "retornar la cadena", esto será un
problema al retornar de la llamada de 'hijos()'. Deberías pasar el array
resultante por parámetro para obligar a que exista fuera de la función; por
ejemplo,

char *hijos( int x, char szResultado[] )
{
  char *lista = szResultado;
  ...
  return lista;
}

- Invocas 'feof()' antes de realizar la lectura; esto es una equivocación.
Debes realizar la lectura y luego invocar 'feof()'. Esto es porque 'feof()'
NO comprueba el final del fichero, sino que comprueba si el bit de
fin-de-fichero (EOF) está habilitado. La función 'fread()' intentará leer
del fichero y si encuentra el final del fichero, entonces habilitará ese
bit de EOF. Esto es,

fread( &ente, sizeof(struct miembro), 1, fp );
while( !feof(fp) )
{
  ...
  fread( &ente, sizeof(struct miembro), 1, fp );
}

- Si 'ente.nombre' es un array, entonces 'lista' no necesita estar
apuntando a la cadena en el bucle, ya que no va a apuntar a otra cosa que
no sea esa misma dirección de memoria. El contenido de 'ente.nombre' puede
cambiar, pero no su dirección de memoria. Por lo tanto, puedes realizar la
asignación una sola vez antes del bucle. Entiendo que quieras agregar ese
mensaje, pero sinceramente aconsejo retornar un puntero nulo si el
algoritmo no pudo encontrar un registro candidato.

- Es posible que tengas un error en la lectura. Como desconocemos la
definición de 'struct miembro', no sabemos el tipo del campo, 'nombre'. Si
tal campo es un array, entonces posiblemente no haya ningún problema, pero
si se trata de un puntero, entonces he ahí el problema. Necesitas un array
o bien estático o bien dinámico.


Espero que esto te oriente.

Steven


2016-01-11 15:04 GMT-05:00 Hl3 <halowin3 en gmail.com>:

> En este código:
>
> char *hijos(int x){
>         char *lista="No encuentro esa persona";
>         FILE *fp;
>         struct miembro ente;
>
>         //abro el fichas.dat
>         if( (fp=fopen("fichas.dat","rb"))==NULL){
>                 puts("No puedo abrir FICHAS.DAT");
>                 exit(1);
>         }
>         //busco hijos de x
>         while(!feof(fp)){
>                 fread(&ente,sizeof(struct miembro),1,fp);
>                 if( (ente.idp == x) || (ente.idm == x) ){
>                         lista = ente.nombre;
>                         printf("ente.nombre: %s   lista: %s\n",
> ente.nombre,lista );//ok
>                 }
>         }
>         close(fp);
>         printf("Envio lista = %s\n",lista );
>         return lista;
> }
>
>
>
> El valor de "lista" dentro del bucle "while" es correcto, pero el valor
> que pinta en el printf que hay despues del "close(fp)" no tiene nada que
> ver con el valor real.
>
> !!!!!   ?????    !!!!!!
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20160111/19cd5b76/attachment.html>


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