[c]Errore di segmentazione

di il
7 risposte

[c]Errore di segmentazione

Salve a tutti, ho un problemone con un programma che sto scrivendo.
Il programma serve per la gestione di lavori e lavoratori.
Vi posto il codice che scritto finora



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

#define MAX_LUN 25



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 lavoro {
	int codice;
	char tipo[MAX_LUN + 1];
	char stato[MAX_LUN + 1];
	struct lavoro *next;
};


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();



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)
{
	FILE *fp1;
	fp1 = fopen("lavoratori.dat", "a+b");
	struct lavoratore *p, *temp;
	while(!feof(fp1))
		fread(&temp, sizeof(struct lavoratore), 1, fp1);
	
	for (p = temp; p != NULL; p = p->next); 
		if (codice == p->codice) 
			return p;
	return NULL;
}

struct lavoro *trova_lavoro(int codice)
{
	FILE *fp2;
	fp2 = fopen("lavori.dat", "a+b");
	struct lavoro *p, *temp;
	int n;
	while(!feof(fp2))
	fread(&temp, sizeof(struct lavoro), 1, fp2);

	for (p = temp; p != NULL; p = p->next); 
	if (codice == p->codice) 
		return p;
	return NULL;
}

void inserire_lavoratori()
{
	FILE *fp1;
	fp1 = fopen("lavoratori.dat", "a+b");
	struct lavoratore *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(&nuovo,sizeof(struct lavoratore),1,fp1);
	fclose(fp1);
}

void inserire_lavori()
{
	FILE *fp2;
	fp2 = fopen("lavori.dat", "a+b");
	struct lavoro *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()
{
	FILE *fp2;
	fp2 = fopen("lavori.dat", "a+b");
	int n;
	struct lavoro *cor, *prec, *temp;
	while(!feof(fp2))
	fread(&temp, sizeof(struct lavoro), 1, fp2);
	
	printf("Inserire il codice del lavoro da cancellare: ");
	scanf ("\n%d", &n);
	
	
	
	for (cor=temp, prec = NULL; cor != NULL && cor->codice != n; 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 
		temp = temp-> 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()

{	
	FILE *fp2;
	fp2 = fopen("lavori.dat", "a+b");
	struct lavoro *temp;

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

void lista_lavoratori()

{	
	FILE *fp1;
	fp1 = fopen("lavoratori.dat", "a+b");
	struct lavoratore *temp;
	
	if (fp1==NULL){
		printf("Impossibile aprire il file\n");
		exit (EXIT_FAILURE);
	}
	while(!feof(fp1))
	{
		fread(&temp, sizeof(struct lavoratore), 1, fp1);
		printf("Codice: %d\tTipo: %s\tStato: %s\t", temp->codice, temp->cognome, temp->nome);
	}
	fclose(fp1);
}


void cancella_lavoratori()
{
	FILE *fp1;
	fp1 = fopen("lavoratori.dat", "a+b");
	int n;
	struct lavoratore *cor, *prec, *temp;
	
	while(!feof(fp1))
		fread(&temp, sizeof(struct lavoratore), 1, fp1);
	
	printf("Inserire il codice del lavoratore da cancellare: ");
	scanf ("\n%d", &n);

	
	for (cor=temp, prec = NULL; cor != NULL && cor->codice != n; 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 
		temp = temp-> next;
	else 
		prec->next = cor->next; // si bypassa il nodo da cancellare
	free(cor);  // si rilascia la memoria occupata dal nodo da cancellare
}
	
	
	







Ogni volta che deve leggere o scrivere nei file mi da un errore di segmentazione.
Sono una principiante, quindi vi prego di avere pazienza con me!

7 Risposte

  • Re: [c]Errore di segmentazione

    Ma intendi usare le liste in memoria o cosa intendi fare?!?
    Cioè non mi puoi sulle funzioni di trova caricare il rekord (sbagliando) e cercando un puntatore alla successiva lista... bho confusione?
  • Re: [c]Errore di segmentazione

    Non ho ben capito cosa mi stai chiedendo.. [ripeto: sono una principiante e ci capisco ben poco]
    la funzione trova legge i dati presenti nel file, e poi con il for legge ogni nodo per vedere se il codice inserito è già presente...
    Questo è quello che intendevo fare io, ma evidentemente è sbagliato
  • Re: [c]Errore di segmentazione

    non ho ben capito cosa mi stai chiedendo.. [ripeto: sono una principiante e ci capisco ben poco]
    la funzione trova legge i dati presenti nel file, e poi con il for legge ogni nodo per vedere se il codice inserito è già presente...
    Questo è quello che intendevo fare io, ma evidentemente è sbagliato
    Quando usi le liste si suppone tu voglia lavorare in memoria, per cui all'inizio della procedura dovresti caricarti tutte le strutture inserendo il nodo next. All'opposto in chiusura risbattere tutto su file.
    Questo è un concetto logico, non centra con la programmazione!
    
    struct lavoratore *trova_lavoratore(int codice, struct lavoratore *primo)
    {
       struct lavoratore *p, *temp;
    
       for (p = primo; p != NULL; p = p->next); 
          if (codice == p->codice) 
             return p;
       return NULL;
    }
    
    tu fai:
    
    --- cut ---
       struct lavoratore *p, *temp;
       while(!feof(fp1))
          fread(&temp, sizeof(struct lavoratore), 1, fp1);
    --- cut ---
    
    dove temp è solo un ptr è senza allocazione da qui l'errore e ...poi ?!
  • Re: [c]Errore di segmentazione

    Ho visto un errore in scrittura:
    
    struct lavoratore *nuovo;
    //fwrite(&nuovo,sizeof(struct lavoratore),1,fp1);
    fwrite(nuovo,sizeof(struct lavoratore),1,fp1);
    
    Non registravi un tubazzo di niente. 'nuovo' è gia un ptr non dev deferenziarlo.
    Stessa cosa nella inserire_lavori()
  • Re: [c]Errore di segmentazione

    Mi segui?
    Allora creati una funzioncina dove di carichi il file nella tua lista (lavoratori AND lavori)
    La richiami all'inizio della procedura e poi tutte le liste te le scorri come vuoi....
    Guarda che se non mi segui vado ... non ho molto tempo a disposizione
    
    struct lavoratore *load_lavoratori ()
    {
      FILE *fp1;
      struct lavoratore *nuovo,*first=NULL,*last=NULL;
      
      if ((fp1 = fopen("lavoratori.dat", "a+b"))==NULL)
      {
        fprintf (stderr,"cannot open file\n");
        return NULL;
      }
    
      while(!feof(fp1))
      {
        if ((nuovo = malloc(sizeof(struct lavoratore)))==NULL)
        {
          fprintf (stderr,"cannot alloc\n");
          return first;
        }
        fread(nuovo, sizeof(struct lavoro), 1, fp1);
        
        if (!first) first=nuovo;
        if (last)   last->next=nuovo;
        
        nuovo->next=NULL;
        last=nuovo;
      }
      fclose (fp1);
      return first;
      
    }
    
    
    EDIT:: modificato per resituire il primo della lista
  • Re: [c]Errore di segmentazione

    Sì, ti sto seguendo, sono un po' lenta ma ti seguo!
    Grazie mille per l'aiuto, sei molto gentile...
    Ora cerco di capire bene l'ultima cosa che hai postato
  • Re: [c]Errore di segmentazione

    Ok... guarda che sto scrivendo senza provarlo...
    
    // All'inizio della procedura
    // usa un nome più consono al primo elemento della lista
    primo_lavoratore=load_lavoratori ();
    //
    
    ora che hai caricato la lista puoi scorrerla per cercare e/o visualizzare...
    se vuoi aggiungere in coda alla lista hai bisogno di un'altra variabile oppure la devi scorrere tutta
    
    struct lavoratore *ultimo_lavoratore=NULL;
    
    Modifica di conseguenza anche il mio pezzetto precedente

    Ora copiati il programma vecchio e applica le modifiche radicali. Ci vediamo tra un paio d'ore
Devi accedere o registrarti per scrivere nel forum
7 risposte