Salve a tutti Sono nuova nel forum e avrei bisogno di un aiuto con un esercizio di preparazione per un esame universitario.

Devo definire le seguenti funzioni:
1. una funzione iterativa che legge i dati dal file di testo e li carica in una lista dove ogni nodo contiene una dato strutturato idoneo a memorizzare gli elementi di una riga, oltre al puntatore al nodo successivo (gli elementi sono stringa, stringa, intero, stringa, intero, intero).
2. Una funzione ricorsiva che stampa il contenuto della lista, visualizzando tutti i campi.
3. Una funzione ricorsiva che, data la matricola di uno studente, stampa la somma dei crediti da lui acquisiti
4. Una funzione iterativa che, dato il cognome di uno studente, crea una seconda lista contenente SOLO i dati degli studenti con tale cognome, eliminandoli dalla lista originaria.

Questo è il programma che ho creato:
codice:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define DIM 20

struct element
{
    char cognome[DIM];
    char nome[DIM];
    int matricola;
    char esame[DIM];
    int crediti;
    int voto;
};

struct persona
{
    struct element info;
    struct persona *next;
};

typedef struct persona studente;
typedef studente *list;

list newnode()
{
    return malloc(sizeof(studente));
}

list make_list()     //funzione 1
{
    FILE *fp;
    list head = NULL, tail = NULL;
    char c[DIM], n[DIM], e[DIM];
    int m, cr, v;
    int i;
    
    fp = fopen("input-esame.txt", "r");
    
    if(fp != NULL)
    {
        i = 0;
        
        while(feof(fp) == 0)
        {
            fscanf(fp,"%s %s %d %s %d %d", &c, &n, &m, &e, &cr, &v);
        
            if(i==0)
            {
                head = newnode();
                strcpy(head->info.cognome, c);
                strcpy(head->info.nome, n);
                head->info.matricola = m;
                strcpy(head->info.esame, e);
                head->info.crediti = cr;
                head->info.voto = v;
                tail = head;
            }
            else
            {
                tail->next = newnode();
                tail = tail->next;
                strcpy(tail->info.cognome, c);
                strcpy(tail->info.nome, n);
                tail->info.matricola = m;
                strcpy(tail->info.esame, e);
                tail->info.crediti = cr;
                tail->info.voto = v;
            }
            i++;
        }
        tail->next = NULL;
        fclose(fp);
    }
    else
    {
        printf("Errore: file non trovato.\n");
        exit(1);
    }
    
    return head;
}

list printlist(list l)   //funzione 2
{
    if(l != NULL)
    {
        printf("%s %s %d %s %d %d\n", l->info.cognome, l->info.nome, l->info.matricola, l->info.esame, l->info.crediti, l->info.voto);
        printlist(l->next);
    }
}

list printsomma(list l, int m, int sum)   //funzione 3
{
    if(l != NULL)
    {
        if(l->info.matricola == m)
        {
            sum = sum + l->info.crediti;
            printsomma(l->next, m, sum);
        }
        else
            printsomma(l->next, m, sum);
    }
    else
        printf("Totale crediti: %d\n", sum);
}

list build_list(list *l, char c[])   //funzione 4
{
    list p, q;
    list head = NULL, tail = NULL;
    
    while(*l != NULL)
    {
        if(strcmp((*l)->info.cognome, c) == 0)
        {
            p = newnode();
            p->info = (*l)->info;
            p->next = NULL;
            
            if(head == NULL)
            {
                head = p;
                tail = p;
            }
            else
            {
                tail->next = p;
                tail = p;
            }
            
            q = *l;
            *l = (*l)->next;
            free(q);
        }
        *l = (*l)->next;
    }
    return head;
}

int main()
{
    list l1, l2;
    l1 = make_list();
    printlist(l1);
    
    int m;
    printf("Inserire matricola di cui calcolare i crediti totali:\t");
    scanf("%d", &m);
    printsomma(l1, m, 0);
    
    printf("\n");
    char c[DIM];
    printf("Inserire cognome dello studente da cercare:\t");
    scanf("%s", c);
    l2 = build_list(&l1, c);
    printlist(l2);
    
    printf("\n");
    printlist(l1);
}
Le funzioni 1, 2 e 3 funzionano correttamente, l'unico problema è la funzione 4 dove devo creare una nuova lista cancellando i nodi dalla lista originaria. Quando compilo il file .c non mi dà errori ma come output mi stampa la nuova lista creata senza l'ultimo nodo e quando cerco di stampare la lista originaria (quella dove non dovrebbero più esserci i nodi della nuova lista) non mi stampa nulla (quindi la lista è vuota e non ha nessun nodo).
Non riesco a capire quale sia il problema