Eliminare record su file.txt

di Anonimizzato15669 il
15 risposte
Buonasera ragazzi,
sto cercando di capire come si gestiscono i file in C, ho provato ad effettuare il seguente codice per eliminare un record, ma esso risulta errato dato che mi viene restituito un errore di segmentazione. Sapreste spiegarmi il perchè?
void elimina(Rubrica *r){
         Rubrica *curr=NULL;
   	 Rubrica *prev=NULL;
	 Rubrica *tmp=NULL;
	 char *name;
	 FILE *fptr;
	 if((fptr=fopen("rubrica.txt","r"))==NULL){
		  printf("errore di apertura\n");
	 	  exit(EXIT_FAILURE);
	 }	
	 else{
		 while(!feof(fptr)){
	 		 name=malloc(sizeof(30));
		 	 printf("inserisci il nome\n");
			 scanf("%s",name);
			 curr=r;	
		 	 while((name!=curr->nome) && (curr->succ!=NULL)){
 				 prev=curr;
				 curr=curr->succ;
			}

			if(curr->nome==name){
				fscanf(fptr,"%s%s\n",curr->nome,curr->numero);
				tmp=curr;
				prev->succ=curr->succ;
			}
		}
	}
	free(tmp);
	free(name);
	fclose(fptr);
PS: il file rubrica.txt è organizzato nella seguente maniera:
pippo,3333333333
pluto,0000000000

15 Risposte

  • Ciao, non ho letto tutto il codice ma una cosa mi salta subito all'occhio: cosa sarebbe questo?
    
    name=malloc(sizeof(30));
    
    Forse intendevi dire
    
    name=malloc(30 * sizeof(char));
    
  • Chiedo scusa per l'ignoranza ma il codice
    name=malloc(sizeof(30));
    non significa che alla variabile name vengono assegnati 30 byte??
  • Io non l'ho mai visto in quel modo. La documentazione la trovi qui.

    Secondo me con la tua scrittura stai ottenendo la memoria occupata dal numero 30, che dovrebbe essere trattato come un normale intero.
  • Hai totalmente ragione !Grazie mille per la correzione e per il link inviatomi.
    Ma purtroppo non risolve il problema cardine .
  • Purtroppo del tuo problema si sa poco.

    In generale, non è possibile eliminare direttamente una riga di testo ma tu come vorresti fare?
    Dal tuo codice non si capisce.

    Forse intendi eliminare l'elemento della lista che tieni in memoria?
  • oregon ha scritto:


    In generale, non è possibile eliminare direttamente una riga di testo
    Sì giusto, questo non lo avevo sottolineato: solitamente quello che si fa è creare un nuovo file dove si va a ricopiare tutto tranne ciò che si vuole eliminare. Quindi si prende il nuovo file e lo si sostituisce al vecchio.
  • Purtroppo del tuo problema si sa poco.
    Ciò che voglio fare è eliminare un determinato numero e nome presente nella rubrica.La scelta viene effettuata dall'utente tramite il nome.
    name=malloc(30*sizeof(char));//corretto
               printf("inserisci il nome\n");
              scanf("%s",name);
    In generale, non è possibile eliminare direttamente una riga di testo
    Tale operazione può essere effettuata tramite le liste collegate???
    solitamente quello che si fa è creare un nuovo file dove si va a ricopiare tutto tranne ciò che si vuole eliminare. Quindi si prende il nuovo file e lo si sostituisce al vecchio
    Cortesemente, se ne sei ha conoscenza, potresti linkare una pagina ,anche con un esempio, da così poter approfondire tale argomento??
  • Non conosco niente da linkare, però il procedimento è molto semplice. Scorri il file e controlli ogni riga: se il nome corrisponde a quello che vuoi eliminare allora non fai niente, altrimenti scrivi la riga in un nuovo file (in modo da preservarla).
  • Non conosco niente da linkare, però il procedimento è molto semplice. Scorri il file e controlli ogni riga: se il nome corrisponde a quello che vuoi eliminare allora non fai niente, altrimenti scrivi la riga in un nuovo file (in modo da preservarla).
    Così facendo avrò bisogno si un numero di file non definito ed inoltre invece che liberare memoria,essa aumenterebbe solamente.
  • Perché? Ti avevo detto che alla fine si elimina il vecchio file e lo si sostituisce con il nuovo. Dove sarebbe lo spreco di memoria?
  • Chiedo scusa per la colpevole gaf .
    Comunque grazie di tutto, sei stato gentilissimo
  • Di nulla. Se hai ancora bisogno, siamo qui.

  • Ciao ragazzi,
    Ho provato a elaborare il programma più o meno come lo ha descritto minomic ,ma senza ottenere risultati positivi . Probabilmente continuo a fare degli errori, sapresete dirmi dove?
    Il programma è il seguente:
    void elimina(Rubrica *mainptr){
    	//inizializzo le variabili
    	FILE *fptr;
    	FILE *nptr;
    	Rubrica *curr=NULL;
    	Rubrica *agg=NULL;
    	char titolo[30];
    	
    	curr=mainptr;
    	agg=mainptr;
             //apro i file
    	if((nptr=fopen("aggiorna.txt","w"))==NULL){
    		printf("errore apertura file aggiorna.txt\n");
    		exit(EXIT_FAILURE);
    	}
    	if((fptr=fopen("rubrica.txt","r+"))==NULL){
    		printf("errore apertura file rubrica.txt\n");
    		exit(EXIT_FAILURE);
    	}
    		
    	printf("inserisci il nome da eliminare\n");
    	scanf("%s",titolo);
    	//controllo riga per riga fino a fine file "rubrica.txt"
    	while(!feof(fptr)){
    		fscanf(fptr,"%[^,],%s",curr->nome,curr->numero);
    		if((strcmp(curr->nome,titolo))!=0){
    			fprintf(nptr,"%s,%s\n",curr->nome,curr->numero);
    		}
    	curr=curr->succ;
    	}
    	//aggiorno il file "rubrica.txt"
    	while(!feof(nptr)){
    		fscanf(nptr,"%[^,],%s",agg->nome,agg->numero);				
    		fprintf(fptr,"%s,%s\n",agg->nome,agg->numero);
    		agg=agg->succ;
    	}
    	
    	fclose(fptr);
    	fclose(nptr);
    }
    
    la struct è la seguente:
    
    struct rubrica{
        struct rubrica *succ;
        char *nome;
        char *numero;
    };
    typedef struct rubrica Rubrica;
    
  • Ciao, questo è un semplice esempio di come creare un nuovo file eliminando una riga dal file originale. Con poco sforzo dovresti riuscire ad adattarlo al tuo problema.
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    
        FILE* fp_1 = fopen("primo.txt", "r");
        FILE* fp_2 = fopen("secondo.txt", "w");
        int riga_eliminare, conta_righe;
        size_t lungh = 0;
        ssize_t letti;
        char* line = NULL;
    
        printf("Quale riga vuoi eliminare? ");
        scanf("%d", &riga_eliminare);
        riga_eliminare--;   // cosi' conto da zero
    
        conta_righe = 0;
    
        while ((letti = getline(&line, &lungh, fp_1)) != -1) {
            if(conta_righe++ != riga_eliminare) {
                printf("%s", line);     // si puo' anche eliminare
                fprintf(fp_2, "%s", line);    // ricopio la riga
            }
        }
    
        fclose(fp_1);
        fclose(fp_2);
    
        return 0;
    }
    
    P.S. L'ho scritto un po' velocemente, quindi non è da escludere che ci sia quale imprecisione.

    P.P.S. Per la lettura di una riga del file si poteva utilizzare anche la fgets, ma ho preferito la getline perché non richiede di specificare la dimensione massima della riga, quindi mi sembrava più flessibile. Poi vedi tu...
Devi accedere o registrarti per scrivere nel forum
15 risposte