0

I am starting to program in c and I have a question. I have to do a job where I have to program a double link list. In this program I have to insert the nodes and order them by numbers (DNI) and then save it in a text file. I have tried several times, when I put a smaller number it doesn't save it in the list, but when I put the first number or a bigger number it adds it to me, but not in the correct order. Where am I wrong? How could I improve it? Thanks in advance.

struct data {
int dia;
int mes;
int any; };


struct Info {
char nom [30];
long int dni;
char correu [30];
struct data fecha;
char sexe; };

typedef struct nodo
{
  struct Info dato;
  struct nodo* sig;
  struct nodo* atras;
  int cantidadnotes;
  float notes [];
    }Nodo;

typedef Nodo *p_nodo;
typedef Nodo *Lista;

void Insertar(Lista *lista) {
 p_nodo nuevo, actual;
 long int dni;
 int i = 0, cantidad;
 float nota;
actual = *lista;
printf("Introdueix la cuantitat de notes que vols afegir al alumne: ");
scanf("%d",&cantidad);
nuevo = (p_nodo)malloc(sizeof(Nodo) + cantidad * sizeof(float));
if(nuevo==NULL)
{
    printf("Error en la memoria");
    return;
}
else
{
    printf("Escriu el nom complet: ");
    scanf(" %[^\n]", &nuevo->dato.nom[0]);
    printf("Escriu el teu correu: ");
    scanf("%s", &nuevo->dato.correu[0]);
    printf("Escriu el dni sense lletra: ");
    scanf("%ld", &dni);
    while (dni < 0 || dni > 99999999)
    {
        printf("Error amb el dni afegeix un altre: ");
        scanf("%ld", &dni);
    }
    while(actual)
    {
        while (actual->dato.dni == dni)
        {
            printf("Ja existeix el dni afegeix un altre: ");
            scanf("%ld", &dni);
        }
            actual = actual->sig;
    }
    nuevo->dato.dni = dni;
    printf("Escriu la data del teu cumpleanys (DD/MM/ANY): ");
    scanf("%d %d %d", &nuevo->dato.fecha.dia, &nuevo->dato.fecha.mes, &nuevo->dato.fecha.any);
    printf("Escriu el teu genere: ");
    scanf(" %s", &nuevo->dato.sexe);
    while(i<cantidad)
    {
        printf("Nota: ");
        scanf("%f", &nota);
        if (nota >= 0 && nota <= 10)
        {
            nuevo->notes[i] = nota;
            i++;
        }
        else  printf("Error: \n");
    }
    nuevo->cantidadnotes = cantidad;
    actual = *lista;
    if(actual) while(actual->atras) actual = actual->atras;
    if(!actual || actual->dato.dni > dni)
    {
        nuevo->sig = actual;
        nuevo->atras = NULL;
        if(actual) actual->atras = nuevo;
        if(!*lista) *lista = nuevo;
    }
    else
    {
        while(actual->sig && actual->sig->dato.dni <= dni)
        {
            actual = actual->sig;
        }

        nuevo->sig = actual->sig;
        actual->sig = nuevo;
        nuevo->atras = actual;
        if(actual->sig) nuevo->sig->atras = nuevo;
    }
}
}
2
  • 1
    Time to strap this into a debugger and see what's going on internally.
    – tadman
    Commented May 11, 2020 at 22:10
  • 1
    .. and stop hiding pointers behind typedefs ... Commented May 11, 2020 at 22:28

1 Answer 1

0

There are two issues in the code.

Issue #1

When you insert a DNI sequence of 3 and 2, 2 will never be represented in the list. The insert takes place, but the new root-pointer is never assigned to *lista:

if(!*lista) *lista = nuevo;

It must be assigned unconditionally:

*lista = nuevo;

Issue #2

When you insert a DNI sequence of 2 and 3, the code dereferences a NULL-pointer because nuevo->sig is NULL in that case (sig of the last node actual is NULL). This needs an additional condition:

if(actual->sig && nuevo->sig) nuevo->sig->atras = nuevo;

With those two adjustments, the ordered list works as expected with random input:

Lista list = NULL;
for (int i = 0; i < 10; i++) {
    Insertar(&list);
}
while (list) {
    printf("%ld\n", list->dato.dni);
    list = list->sig;
}
171
208
214
337
648
670
745
754
818
993

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.