Provavi a dereferenziare puntatori NULL. In rosso le modifiche. Le stringhe vengono ordinate in ordine alfabetico inverso, non so se era questa la tua intenzione; se vuoi il contrario, basta negare la seconda condizione del while. Comunque ti ho corretto solo l'errore, ma ci sarebbero una serie di altre cose da aggiustare come il fatto che non deallochi lo spazio allocato dinamicamente... scrivi una funzione per la deallocazione. Attento anche al buffer overflow a cui vai incontro se qualcuno inserisce un nome più lungo di 15 caratteri.
PS: non è il compilatore che dà segmentation fault, ma il sistema operativo dopo che il processo, una volta avviato il programma, riceve il segnale SIGSEGV (se stai su Linux). E non è nemmeno il compilatore a "prendere il nome": il compilatore compila soltanto, è l'esecuzione del programma a fare tutto il resto.
codice:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct lista{
char nome[15];
struct lista *nextptr;
};
typedef struct lista lista_al;
/*prototipi*/
lista_al *my_alloc(void);
void insert_el(lista_al **sptr);
int disordine(char *ial, char *sal);
void stampa_lista(lista_al *sptr);
int main(){
int cntr=0;
lista_al *head=NULL; //all'inizio non ci sono nodi
insert_el(&head);
do{
printf("Per inserire altri elementi,1 to go on, -1 to exit\n");
scanf("%d",&cntr);
if(cntr!=-1)
insert_el(&head);
}while(cntr!=-1);
stampa_lista(head);
return 0;
}
/*definizioni di funzione*/
lista_al *my_alloc(){
lista_al *p;
p=(lista_al*)malloc(sizeof(lista_al));
if(p==NULL){
printf("Errore nell'allocazione della memoria.\n");
exit(-1);
}
return p;
}
void insert_el(lista_al **sptr){
lista_al *newptr,*scanptr=NULL,*previousPtr=NULL;
static int j=0;
int i;
++j; //contatore numero di elementi inseriti;
printf("Inserisci nome alunno:\n");
if(*sptr==NULL){
*sptr=my_alloc();
scanf("%s",(*sptr)->nome);
(*sptr)->nextptr=NULL;
printf("Nome primo alunno inserito correttamente\n");
return ;
}
else{
i=0;
newptr=my_alloc();
scanf("%s",newptr->nome);
newptr->nextptr=NULL;
scanptr=*sptr; //la scansione parte dalla testa della lista
while((scanptr!=NULL)&&(disordine(newptr->nome,scanptr->nome))) { //finché non termina la lista, o ha trovato un elemento
//successivo a quello da inserire
previousPtr=scanptr;
scanptr=scanptr->nextptr; //continua la scansione
++i;
}
newptr->nextptr=scanptr;
if (i == 0) { /* l'inserimento è avvenuto in testa, quindi va aggiornato *sptr */
*sptr = newptr;
} else { /* altrimenti è avvenuto nel mezzo */
previousPtr->nextptr=newptr;
}
printf("Elemento %d inserito correttamente.\n",j);
return ;
}
}
int disordine(char *ial, char *sal){
int cntr=strcmp(ial,sal); //ial=alunno da inserire; sal= alunno da passare in Scansione
if(cntr>0) //se l'alunno da inserire viene dopo quello appena esaminato
return 0;
else return 1;
}
void stampa_lista(lista_al *sptr){
lista_al *scanptr;
for(scanptr=sptr;scanptr!=NULL;scanptr=scanptr->nextptr)
printf("%s-->",scanptr->nome);
return;
}