Ho provato a modificare la funzione in questo modo:
codice:
list build_list(list l, char c[])   //funzione 4
{
    list p, q, n;
    list head = NULL, tail = NULL;
    
    if(l != NULL)
    {
        q = l;
        while(q->next != NULL)
        {
            if(strcmp(q->next->info.cognome, c) == 0)
            {
                n = newnode();
                n->info = q->info;
                n->next = NULL;
                
                if(head == NULL)
                {
                    head = n;
                    tail = n;
                }
                else
                {
                    tail->next = n;
                    tail = n;
                }
                
                p = q->next;
                q->next = q->next->next;
                free(p);
            }
            else 
                q = q->next;
        }
        
        if(strcmp(l->info.cognome, c) == 0) //gestisco la testa della lista
        {
            n = newnode();
            n->info = q->info;
            n->next = NULL;
                
            if(head == NULL)
            {
                head = n;
                tail = n;
            }
            else
            {
                tail->next = n;
                tail = n;
            }
            
            p = l;
            l = l->next;
            free(p);
        }
    }
    return head;
}
Questa volta mi elimina correttamente i nodi dalla prima lista, ma non crea la seconda lista con i nodi eliminati dalla prima (i nodi della seconda lista sono gli stessi della prima :/ ).
(scusa il ritardo nella risposta)