Using a list to store data from a .txt file, only stores the last input (C)

122 views Asked by At

I need a way to store data from a file as well as save it on a file, it all needs to be done through a list using pointers, as the menu specifies it has to be able to delete and search for an specific person`s data within the list, my problem is, it reads the data from the file and stores it, but the show (on screen) function gets stuck on a loop showing me the data it read from the file for the last person's information(what would go on the last node before pointing to NULL), the same happens with the save (to file) function and the search (on list) and delete (from list) functions, which leads me to think it's somehow not pointing to NULL at the end of the list, I checked several times every function and their calls and couldn't find anything wrong but I'm barely a student and I really need help with this, thanks in advance (I'm sorry if I didn't format the code properly).

This is the library I made with the functions I needed:

#define EOL '\n'

struct fecha{
  int dia,mes,año;
};

struct lista{
    long cedula;
       int genero;
       char nombre[20];
       char apellido[20]; 
       char direccion[50];
       fecha f;
       lista *prox;
};

void asignar (int i,char lectura[50],lista **t){
       switch (i)
{
   case 1:
        (*t)->cedula=atol(lectura);//atol convierte string a long
       break;
   case 2:
        (*t)->genero=atoi(lectura);//atoi convierte string a int
       break;
   case 3:
        strcpy((*t)->nombre,lectura);
       break;
    case 4:
        strcpy((*t)->apellido,lectura);
        break;
    case 5:
        strcpy((*t)->direccion,lectura);
        break;
    case 6:
         (*t)->f.dia=atoi(lectura);
        break;
    case 7:
         (*t)->f.mes=atoi(lectura);
        break;
    case 8:
         (*t)->f.año=atoi(lectura);
        break;
    };
}

void insertaCab(lista **p, char path[100]){
        lista *t = new lista;//crea el nodo
        FILE *archivo;//apuntador para el archivo
        int i=1;
        char lectura[50];
        archivo = fopen(path, "r");
        if (archivo != NULL){//Si el archivo existe
            while (!feof(archivo)){//Mientras no es final de archivo
                while (i<=8){//lee 8 lineas y pasa al siguiente nodo de la lista
                 memset(lectura, 0, 50);
                  fgets(lectura,50,archivo);//Lee una linea
                   asignar(i,lectura,&t);>le pasa a asignar el contador,los datos y el apuntador de la lista
                i++;
            }i=1;
    t->prox =(*p);//T->datos->||
    (*p)=t;//P->datos->||
        }fclose(archivo);
    }
}

void muestra(lista *p){
    lista *t = p;
    while (t){
        printf("Cedula: %i\n",t->cedula);
        if (t->genero == 1) printf("Genero: Femenino\n");
        else printf("Genero: Masculino\n");
        printf("Nombre: %s\n",t->nombre);
        printf("Apellido: %s\n",t->apellido);
        printf("Direccion: %s\n",t->direccion);
        printf("Fecha de nacimiento: %i/%i/%i\n\n",t->f.dia,t->f.mes,t->f.año);

        t=t->prox;
    }
    printf("\n");
    }

int buscarlista(lista *p,long x){
lista *t=p;
while (t!= NULL ){
    if (t->cedula == x)
        return 1;
    t=t->prox;
}
return 0;
}

void eliminar(lista **p, long x){
    lista *t=(*p),*aux;
    if (t!= NULL)
        if (t->cedula == x){
            (*p)=t->prox;
            delete t;
        }
        else{
            while ((t->prox!= NULL) && (t->prox->cedula!=x))
                t=t->prox;
            if (t->prox!= NULL){
                aux=t->prox;
                t->prox=aux->prox;
                delete aux;
            }
        }
    }

void guardar(lista *p,char path[100]){
lista *t= new lista;
t=p;//apuntador auxiliar para recorrer la lista
FILE *archivo;//apuntador para el archivo
archivo = fopen(path,"a");//abre el archivo en modo append, si no existe lo crea
if(archivo !=NULL){//Si el archivo existe
 while (t){
  fprintf(archivo,"Cedula: %i\n",t->cedula);
   if (t->genero == 1) fprintf(archivo,"Genero: Femenino\n");
   else fprintf(archivo,"Genero: Masculino\n");
  fprintf(archivo,"Nombre: %s\n",t->nombre);
  fprintf(archivo,"Apellido: %s\n",t->apellido);
  fprintf(archivo,"Direccion: %s\n",t->direccion);
  fprintf(archivo,"Fecha de nacimiento: %i/%i/%i\n\n",t->f.dia,t->f.mes,t->f.año);
  t=t->prox;
    }
    fclose(archivo);
}   
}

And this is my main:

void main ( )
{
 lista *p=NULL;
 long x = 0;
 int op;
 char path[100]; 
 op=-1;
 while (op!=0){
    printf ("1. Agregar\n");
    printf ("2. Buscar\n");
    printf ("3. Eliminar\n");
    printf ("4. Mostrar\n");
    printf ("5. Guardar\n");
    printf ("0. Salir\n");
    scanf ("%d", &op);
    switch (op){
        case 1: printf("Introduzca la direccion del archivo:");
                 memset(path,0,100);//Inicializa dir
                  scanf("%s",path);//Lee la direccion del archivo
                   insertaCab(&p,path);//Recibe el apuntador de la lista y la direccion del archivo
                break;
        case 2: printf("Indique el numero de cedula a buscar:");
                 scanf("%d",&x);
                  if (buscarlista(p,x) == 1)printf("El numero %i se encuentra en la lista\n",x);
                  else printf("No se encuentra en la lista\n");
                break;
        case 3: printf("Indique numero de cedula a eliminar:");
                 scanf("%d",&x);
                  eliminar(&p,x);
                break;
        case 4: muestra(p);
                break;
       case 5: printf("Introduzca la direccion en donde desea guardar la lista:");
                 memset(path,0,100);
                  scanf("%s",path);
                   guardar(p,path);
                break;
    };
 }
    }
2

There are 2 answers

2
atf01 On BEST ANSWER

Alright so I was able to solve it, I was missing the use of the malloc function, that's the reason as to why the list never got to NULL. The following is the fixed and working version of the function to input data into the list from the file:

void insertaCab(lista **p, char path[100]){
    lista *t = new lista;
     t = (struct lista *) malloc( sizeof(struct lista) ); 
    char lectura[50];
    int i=1;
    FILE *archivo = fopen(path, "r");
    if (archivo == NULL) return;
        while (fgets(lectura,50,archivo)){ 
            t = (struct lista *) malloc( sizeof(struct lista) ); 
             for (i=1; (i<=8) && (fgets(lectura,50,archivo)); i++)
              asignar(i,lectura,&t);
            if(i<=8) break;
    t->prox =(*p);
    (*p)=t;
        }
        fclose(archivo);
}
2
ooga On

You aren't detecting EOF properly. Try this:

void insertaCab(lista **p, char path[100]){
    char lectura[50];
    FILE *archivo; = fopen(path, "r");
    if (archivo == NULL) return;
    lista *t = new lista;
    while (fgets(lectura, 50, archivo)) {
        for (i = 1; i <= 8 && fgets(lectura, 50, archivo); i++)
           asignar(i, lectura, &t);
        if (i <= 8) break; // reached EOF before 8 lines were read.
        t->prox = *p;
        *p = t;
    }
    fclose(archivo);
}