Errores al pasar datos de un archivo a una lista

Iniciado por palacio29, 21 Junio 2020, 03:38 AM

0 Miembros y 1 Visitante están viendo este tema.

palacio29

Buenos Dias
Tengo un problema intentando pasar datos de un archivo a una lista.
El archivo tiene el siguiente formato: %s,%d,%s (Nombre,DNI,Apellido).
La cuestion es que al utilizar la función imprimir, solo me imprime el apellido del ultimo nodo de la lista, mientras que los demas valores los imprime bien
Lo raro es que en la función agregar tambíen imprimo para ver que es lo que estoy pasando a los nodos y esta todo bien, asi que no se que puede estar pasando.

#include <stdio.h>
#include <stdlib.h>
struct s_datos
{
    char*apellido;
    int dni;
    char*pais;

};
typedef struct s_datos t_dato;

struct s_nodo
{
    t_dato dato;
    struct s_nodo*sig;
};
typedef struct s_nodo*t_nodo;
void cargalista(t_nodo*);
void agregar(t_nodo*,t_dato);
void imprimir(t_nodo);
int main()
{
    t_nodo lista=NULL;
    cargalista(&lista);
    imprimir(lista);
    return 0;
}
void cargalista(t_nodo*lista)
{
    FILE*arch=NULL;
    t_dato datito;
    int i=0,r;
    char*aux;
    aux=malloc(sizeof(char));
    arch=fopen("personas.txt","r");
    r=fgetc(arch);
    while(r!=EOF)
    {
        while(r!=',')
        {
            *(aux+i)=r;
            i++;
            aux=realloc(aux,(i+1)*sizeof(char));
            r=fgetc(arch);
        }
        *(aux+i)='\0';
        datito.apellido=aux;
        char*txt2=NULL;
        txt2=malloc(sizeof(char));
        i=0;
        r=fscanf(arch,"%d,",&datito.dni);
        r=fgetc(arch);
        while(r!='\n' && r!=EOF)
        {
            *(txt2+i)=r;
            i++;
            txt2=realloc(txt2,(i+1)*sizeof(char));
            r=fgetc(arch);
        }
        *(txt2+i)='\0';
        datito.pais=txt2;
        i=0;
        r=fgetc(arch);
        printf("\nApellido: %s - DNI: %d - Pais : %s",datito.apellido,datito.dni,datito.pais);
        agregar(lista,datito);
    }

}
void agregar(t_nodo*nodo,t_dato datito)
{
    if(*nodo==NULL)
    {
        *nodo=(t_nodo)malloc(sizeof(struct s_nodo));
        (*nodo)->dato=datito;
        (*nodo)->sig=NULL;
    }
    else
    {
        agregar(&(*nodo)->sig,datito);

    }
}
void imprimir(t_nodo lista)
{
    printf("\nFuncion Imprimir\n");
    if(lista!=NULL)
    {
        printf("\nApellido: %s - DNI: %d - Pais: %s",lista->dato.apellido,lista->dato.dni,lista->dato.pais);
        imprimir(lista->sig);
    }


}
}

ThunderCls

#1
Tus variables "aux" y "txt2" en la funcion "cargalista" son variables locales, luego en tu codigo al hacer algo como

datito.apellido=aux;

simplemente estas copiando el puntero "aux" a tu miembro de estructura pero no el contenido al que apunta, lo que significa que una vez la funcion retorna y la memoria de las variables locales es liberada, ahora tendras lo que se conoce como dangling pointer (puntero colgante), apuntando a memoria desconocida. En este caso entonces necesitas hacer una copia de la memoria a donde apunta el puntero y no del puntero en si, puedes sustituir

datito.apellido=aux;

por


datito.apellido=malloc(strlen(aux) + 1);
strncpy(datito.apellido, aux, i);


lo mismo con "datito.pais" y lo mismo en tu funcion "agregar"

(*nodo)->dato=datito;

por

memcpy(&(*nodo)->dato, &datito, sizeof(struct s_datos));

Saludos

EDIT: Olvidé mencionar que igual no tiene mucho sentido y es mejor que te deshagas por completo de las variables "aux" y "txt2" y uses directamente los miembros de la estructura local "datito"

EDIT2: En la funcion "agregar" estoy usando "shallow copy" con la estructura, pero en este caso supongo que una copia profunda es el camino a tomar

memcpy(&(*nodo)->dato, &datito, sizeof(struct s_datos));

por una llamada a la funcion

void copia_stdatos(t_dato *dest, t_dato *src)
{
    dest->apellido = malloc(strlen(src->apellido) + 1);
    strncpy(dest->apellido, src->apellido, strlen(src->apellido) + 1);
   
    dest->dni = src->dni;
   
    dest->pais = malloc(strlen(src->pais) + 1);
    strncpy(dest->pais, src->pais, strlen(src->pais) + 1);
}
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/