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

Davidson, Steven srd4121 en njit.edu
Mar Ene 12 17:05:08 CET 2016


Hola Hl3,

Si vas a usar un array, entonces te advierto que tendrás que copiar la
cadena de 'ente.nombre' a tal array usando 'strcpy()', aunque recomiendo
usar 'memcpy()', en este caso.

Sospechaba que creaste el fichero usando 'struct miembro' al igual que lees
el fichero usando la misma definición de 'struct miembro', pero obviamente
tenía que indicarlo, por si no se daba este caso.

Recuerda que invocas 'printf()' bajo 'if'. Usando tu código fuente,
posiblemente no veas diferencia en la práctica porque seguramente esa
condición de 'if' no siempre es verdadera. Comprueba el caso eliminando
'if' para que veas el resultado de 'printf()' en el bucle. Deberías
observar el comportamiento extraño que 'printf()' muestra los datos de la
última lectura dos veces. Esto es porque no se activó el bit de EOF en la
iteración previa, pero al intentar una lectura más allá del final del
fichero, entonces sí se activa tal bit, y entonces la condición en 'while'
es falsa, cuando 'feof()' lee tal bit.

La explicación del caso de mostrar igual contenidos de 'lista' y de
'ente.nombre' en el bucle 'while' pero distintos fuera del bucle se basa en
lo que menciono en el párrafo anterior al igual que la explicación en el
correo-e anterior con el comportamiento de 'lista'. El problema es que no
muestras los contenidos en el bucle 'while' (directamente), sino bajo la
sentencia 'if', la cual queda comprendida en el bucle 'while'. Esto implica
que sólo muestras ciertas cadenas y no todas las posibles cadenas leídas.
Como además 'lista' es un puntero que apunta a 'ente.miembro', cualquier
cambio del contenido en este array también se vería reflejado si usas
'lista', porque esta variable es un puntero. Es parecido a hacer esto:

char szCadena[100] = "hola";
char *ptr = szCadena;

printf( "cadena = %s\tpuntero = %s", szCadena, ptr );

strcpy( szCadena, "adios" );
printf( "cadena = %s\tpuntero = %s", szCadena, ptr );

strcpy( szCadena, "mundo" );
strcpy( szCadena, "colina" );
printf( "cadena = %s\tpuntero = %s", szCadena, ptr );

strcpy( szCadena, "tornado" );
strcpy( szCadena, "jardin" );

printf( "puntero = %s", ptr );

Obviamente, la última sentencia mostrará el contenido guardado en
'szCadena', pero a través de 'ptr'.

En general, cualquier comportamiento raro (y posiblemente indeseado)
concerniendo "datos mágicos", que aparecen y desaparecen, se puede atribuir
al (mal) uso de punteros y al de arrays (i.e.: si nos extendemos pasado los
confines de memoria asignada), con casi un 95% de confianza. En otras
palabras, empieza culpando los punteros y arrays.


Espero que todo esto aclare las dudas.

Steven


2016-01-12 4:29 GMT-05:00 Hl3 <halowin3 en gmail.com>:

> Hola Steven, ante todo muchas gracias por tu respuesta, me parece
> interesante lo que comentas.
>
> Creo que el problema está en tu primer comentario, debo tratar lista como
> un array y no como char* (lo voy a rehacer ahora mismo y luego te cuento).
>
> En cuanto a la estructura "miembro", está bien (seguro) ya que otras
> opciones del programa la usan y uso varias veces el mismo fichero
> "fichas.dat" y no hay problema.
>
> Lo de hacer el fread antes de entrar en el bucle también lo he probado
> aunque el comportamiento era el mismo, pero lo tendré en cuenta y haré el
> fread antes de entrar en el while.
>
> Mi curiosidad radica en que dentro de la misma funcion "hijos()", la
> variable lista pierde el valor en cuanto sale del bucle "while" porque
> dentro del bucle compruebo con el "printf" que los valores que va tomando
> son correctos, pero el "printf" último pinta otra cosa, en concreto me
> pinta el "ente.nombre" del último registro, !!! es alucinante y no acabo de
> entender porque lo hace".
> Luego, en el cuerpo del programa, cuando recibo la cedena retornada por
> "hijos()", sigue siendo "la que está mal".
>
> NO ENTIENDO ESE COMPORTAMIENTO, de que fuera del bucle y aun dentro de la
> función, cambie de valor.
>
> Me pongo a ello.
>
> Muchas gracias.
>
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20160112/8539d7a0/attachment.html>


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