elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Errores al pasar datos de un archivo a una lista
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Errores al pasar datos de un archivo a una lista  (Leído 2,421 veces)
palacio29

Desconectado Desconectado

Mensajes: 103


Ver Perfil
Errores al pasar datos de un archivo a una lista
« en: 21 Junio 2020, 03:38 am »

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.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct s_datos
  4. {
  5.    char*apellido;
  6.    int dni;
  7.    char*pais;
  8.  
  9. };
  10. typedef struct s_datos t_dato;
  11.  
  12. struct s_nodo
  13. {
  14.    t_dato dato;
  15.    struct s_nodo*sig;
  16. };
  17. typedef struct s_nodo*t_nodo;
  18. void cargalista(t_nodo*);
  19. void agregar(t_nodo*,t_dato);
  20. void imprimir(t_nodo);
  21. int main()
  22. {
  23.    t_nodo lista=NULL;
  24.    cargalista(&lista);
  25.    imprimir(lista);
  26.    return 0;
  27. }
  28. void cargalista(t_nodo*lista)
  29. {
  30.    FILE*arch=NULL;
  31.    t_dato datito;
  32.    int i=0,r;
  33.    char*aux;
  34.    aux=malloc(sizeof(char));
  35.    arch=fopen("personas.txt","r");
  36.    r=fgetc(arch);
  37.    while(r!=EOF)
  38.    {
  39.        while(r!=',')
  40.        {
  41.            *(aux+i)=r;
  42.            i++;
  43.            aux=realloc(aux,(i+1)*sizeof(char));
  44.            r=fgetc(arch);
  45.        }
  46.        *(aux+i)='\0';
  47.        datito.apellido=aux;
  48.        char*txt2=NULL;
  49.        txt2=malloc(sizeof(char));
  50.        i=0;
  51.        r=fscanf(arch,"%d,",&datito.dni);
  52.        r=fgetc(arch);
  53.        while(r!='\n' && r!=EOF)
  54.        {
  55.            *(txt2+i)=r;
  56.            i++;
  57.            txt2=realloc(txt2,(i+1)*sizeof(char));
  58.            r=fgetc(arch);
  59.        }
  60.        *(txt2+i)='\0';
  61.        datito.pais=txt2;
  62.        i=0;
  63.        r=fgetc(arch);
  64.        printf("\nApellido: %s - DNI: %d - Pais : %s",datito.apellido,datito.dni,datito.pais);
  65.        agregar(lista,datito);
  66.    }
  67.  
  68. }
  69. void agregar(t_nodo*nodo,t_dato datito)
  70. {
  71.    if(*nodo==NULL)
  72.    {
  73.        *nodo=(t_nodo)malloc(sizeof(struct s_nodo));
  74.        (*nodo)->dato=datito;
  75.        (*nodo)->sig=NULL;
  76.    }
  77.    else
  78.    {
  79.        agregar(&(*nodo)->sig,datito);
  80.  
  81.    }
  82. }
  83. void imprimir(t_nodo lista)
  84. {
  85.    printf("\nFuncion Imprimir\n");
  86.    if(lista!=NULL)
  87.    {
  88.        printf("\nApellido: %s - DNI: %d - Pais: %s",lista->dato.apellido,lista->dato.dni,lista->dato.pais);
  89.        imprimir(lista->sig);
  90.    }
  91.  
  92.  
  93. }
  94. }


« Última modificación: 21 Junio 2020, 04:42 am por palacio29 » En línea

ThunderCls


Desconectado Desconectado

Mensajes: 455


Coder | Reverser | Gamer


Ver Perfil WWW
Re: Errores al pasar datos de un archivo a una lista
« Respuesta #1 en: 23 Junio 2020, 22:01 pm »

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

Código
  1. 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

Código
  1. datito.apellido=aux;

por

Código
  1. datito.apellido=malloc(strlen(aux) + 1);
  2. strncpy(datito.apellido, aux, i);

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

Código
  1. (*nodo)->dato=datito;

por

Código
  1. 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

Código
  1. memcpy(&(*nodo)->dato, &datito, sizeof(struct s_datos));

por una llamada a la funcion

Código
  1. void copia_stdatos(t_dato *dest, t_dato *src)
  2. {
  3.    dest->apellido = malloc(strlen(src->apellido) + 1);
  4.    strncpy(dest->apellido, src->apellido, strlen(src->apellido) + 1);
  5.  
  6.    dest->dni = src->dni;
  7.  
  8.    dest->pais = malloc(strlen(src->pais) + 1);
  9.    strncpy(dest->pais, src->pais, strlen(src->pais) + 1);
  10. }


« Última modificación: 23 Junio 2020, 23:29 pm por ThunderCls » En línea

-[ "…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/
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines