Ciao a tutti..
sono una assoluta principiante nell'ambiente della programmazione in c, quindi chiedo scusa in anticipo.
Per un esame devo fare un piccolo programma, per la gestione dei lavoratori e dei lavori di un'agenzia.. Il programma deve quindi poter inserire, cancellare, modificare lavori e lavoratori. Non ho ancora finito di scrivere l'intero codice, ma ho già diversi problemi... Sono giorni che cerco di risolverli, ma non ci riesco proprio, quindi chiedo a voi.
Per "rappresentare" lavori e lavoratori ho creato delle liste come variabili globali, e poi ho fatto le diverse funzioni per cancellare e aggiungere. Ci sono diverse cose da migliorare nel codice, ma il mio problema sono i file che non so bene come gestire.
Scusate, non mi so neanche spiegare.
Allora, per esempio se provo a stampare a video i lavoratori attraverso la funzione lista_lavoratori mi da un errore di segmentazione, che non riesco proprio a capire. Lo stesso se provo a cancellare un nodo.
E inoltre credo che anche fwrite presente nella funzione inserire_lavoratori sia sbagliata

codice:
#include <stdio.h>
#include <stdlib.h>

#define MAX_LUN 25
#define FILE1 "lavoratori.dat"
#define FILE2 "lavori.dat" 
#define FILE3 "assegnamento.dat"


struct lavoratore {           
	int codice;
	char cognome[MAX_LUN + 1];
	char nome[MAX_LUN + 1];
	struct lavoratore *next; 
};

struct lavoratore *lavoratori = NULL; //punta al primo componenente della lista
struct lavoratore *lavoratori1;

struct lavoro {
	int codice;
	char tipo[MAX_LUN + 1];
	char stato[MAX_LUN + 1];
	struct lavoro *next;
};

struct lavoro *lavori1;
struct lavoro *lavori = NULL; // punta al primo componente della lista


int menu_lavoratori();
int menu_lavori();
struct lavoratore *trova_lavoratore(int codice);
struct lavoro *trova_lavoro(int codice);
void inserire_lavoratori();
void inserire_lavori();
void cancella_lavori();
void lista_lavori();
void lista_lavoratori();
void cancella_lavoratori();


FILE *fp1, *fp2;

int main()
{
	char scelta;
	for (; ;) {
		printf("\n\n");
		printf("			==================\n"
               "			AGENZIA INTERINALE\n"                           
	  	       "			==================\n\n"
	  	       "[a] Assegnamento\n"
	  	       "[l] Gestione lavoratori\n"		
               "[j] Gestione lavori\n"			
               "                                                  [q] Esci\n");
		scanf("\n%c", &scelta);
		
		switch (scelta) {
			case 'l': menu_lavoratori();
				break;
			case 'j': menu_lavori();
				break;
			case 'q': return 0;
				break;
			default: printf ("Operazione non valida\n");
				break;
		}
	}
	
}

int menu_lavoratori()
{
	char scelta;
	for (; ;) {
		printf("\n\n");
		printf("			===================\n"
               "			GESTIONE LAVORATORI\n"                           
	  	       "			===================\n\n"
	  	       "[a] Aggiungi nuovo lavoratore\n"
			   "[c] Cancella lavoratore\n"			
               "[l] Mostra lista\n"			
               "                                                  [m] Torna al menù principale\n"
               "                                                  [q] Esci\n");
        
		
		scanf("\n%c", &scelta);
		switch (scelta) {
			case 'a': inserire_lavoratori();
				break;
			case 'm': main();
				break;
			case 'q': exit(0);
				break;
			case 'l': lista_lavoratori();
				break;
			case 'c': cancella_lavoratori();
				break;
			default: printf ("Operazione non valida\n");
				break;
		}
	}
}

int menu_lavori()
{
	char scelta;
	for (; ;) {
		printf("\n\n");
		printf("			=================\n"
               "			 GESTIONE LAVORI\n"                           
	  	       "			=================\n\n"
	  	       "[a] Aggiungi nuovo lavoro\n"
	  	       "[e] Modifica lavoro esistente\n"		
               "[c] Cancella lavoro\n"			
               "[l] Mostra lista\n"			
               "                                                  [m] Torna al menù principale\n"
               "                                                  [q] Esci\n");	
		scanf("\n%c", &scelta);
		switch (scelta) {
			case 'm': main();
				break;
			case 'q': exit(0);
				break;
			case 'c' : cancella_lavori();
				break;
			case 'a': inserire_lavori();
				break;
			case 'l': lista_lavori();
				break;

			default: printf ("Operazione non valida\n");
				break;
		}
	}
}
struct lavoratore *trova_lavoratore(int codice)
{
	struct lavoratore *p;
	for (p = lavoratori; p != NULL; p = p->next); 
		if (p != NULL && codice == p->codice) 
			return p;
	return NULL;
}

struct lavoro *trova_lavoro(int codice)
{
	struct lavoro *p;
	for (p = lavori; p != NULL; p = p->next); 
	if (p != NULL && codice == p->codice) 
		return p;
	return NULL;
}

void inserire_lavoratori()
{
	fp1 = fopen(FILE1, "ab");
	struct lavoratore *cor, *prec, *nuovo;
	
	nuovo = malloc(sizeof(struct lavoratore));
	
	if (fp1==NULL)
		printf("Impossibile aprire il file\n");
	
	if (nuovo == NULL) {
		printf("Il database è pieno, non è possibile inserire nuovi dati");
		return;
	}
	
	printf ("Inserire codice del lavoratore: ");
	scanf  ("\n%d", &nuovo->codice);
	if (trova_lavoratore(nuovo->codice) != NULL) { 
		printf ("Codice già inserito.\n");
		return;
	}

	printf("Inserire cognome: ");
	scanf("%s", nuovo->cognome);
	printf("Inserire nome: ");
	scanf("%s", nuovo->nome); 
	
	fwrite(&lavoratori,sizeof(struct lavoratore),1,fp1);
	fclose(fp1);
}

void inserire_lavori()
{
	fp2 = fopen(FILE2, "ab");
	struct lavoro *cor, *prec, *nuovo;
	
	nuovo = malloc(sizeof(struct lavoro));
	if (fp2==NULL)
		printf("Impossibile aprire il file\n");
	if (nuovo == NULL) {
		printf("Il database è pieno, non è possibile inserire nuovi dati");
		return;
	}
	
	printf ("Inserire codice del lavoro: ");
	scanf  ("\n%d", &nuovo->codice);
	if (trova_lavoro(nuovo->codice) != NULL) { 
		printf ("Codice già inserito.\n");
		return;
	}
	
	printf("Inserire tipo: ");
	scanf("%s", nuovo->tipo);
	printf("Inserire stato [da fare, in esecuzione, terminato]: ");
	scanf("%s", nuovo->stato);
	
	fwrite(&lavori,sizeof(struct lavoro),1,fp2);
	fclose(fp2);
}


void cancella_lavori()
{
	printf("Inserire il codice del lavoro da cancellare: ");
	scanf ("\n%d", &lavori->codice);
	
	struct lavoro *cor, *prec;
	
	for (cor=lavori, prec = NULL; cor != NULL && cor->codice != lavori->codice; prec = cor, cor = cor->next) 
		;
	if (cor == NULL)   // non è stato trovato il codice
		printf("Il codice non è stato trovato");
	if (prec == NULL)  // il codice è nel primo nodo 
		lavori = lavori-> next;
	else 
		prec->next = cor->next; // si bypassa il nodo da cancellare
	free(cor);  // si rilascia la memoria occupata dal nodo da cancellare
}


void lista_lavori()

{	
	fp2 = fopen(FILE2, "rb");

	if (fp2==NULL)
		printf("Impossibile aprire il file\n");
	
	while(!feof(fp2))
	{
		fread(&lavori1, sizeof(struct lavoro), 1, fp2);
		printf("Codice: %d\tTipo: %s\tStato: %s\t", lavori1->codice, lavori1->tipo, lavori1->stato);
	}
	fclose(fp2);
}

void lista_lavoratori()

{	
	fp1 = fopen(FILE1, "rb");
	
	if (fp1==NULL)
		printf("Impossibile aprire il file\n");
	
	while(!feof(fp1))
	{
		fread(&lavoratori1, sizeof(struct lavoro), 1, fp1);
		printf("Codice: %d\tTipo: %s\tStato: %s\t", lavoratori1->codice, lavoratori1->cognome, lavoratori1->nome);
	}
	fclose(fp1);
}


void cancella_lavoratori()
{
	printf("Inserire il codice del lavoratore da cancellare: ");
	scanf ("\n%d", &lavoratori->codice);
	
	struct lavoratore *cor, *prec;
	
	for (cor=lavoratori, prec = NULL; cor != NULL && cor->codice != lavoratori->codice; prec = cor, cor = cor->next) 
		;
	if (cor == NULL)   // non è stato trovato il codice
		printf("Il codice non è stato trovato");
	if (prec == NULL)  // il codice è nel primo nodo 
		lavoratori = lavoratori-> next;
	else 
		prec->next = cor->next; // si bypassa il nodo da cancellare
	free(cor);  // si rilascia la memoria occupata dal nodo da cancellare
}




Vi avverto, io di memoria non ci capisco granché.