Problema rimozione elemento da lista [C]

di il
35 risposte

35 Risposte - Pagina 2

  • Re: Problema rimozione elemento da lista [C]

    No ma aspetta un momento perché mi sta venendo un dubbio vedendo quel fp. Ma stai cercando di cancellare un numero da una lista scritta su un file?
  • Re: Problema rimozione elemento da lista [C]

    Ho velocemente visto solo questa funzione, noto alcune cose che non vanno.
    Tante uscite non strutturali dalla funzione, si possono utilizzare, ma bisogna stare attenti, poi apri un file ma non utilizzi mai lo stream, che cosa intendevi fare?
    
    Lista elimina_valore(Lista L) {
    
       fp = fopen("lista.txt", "a");  /* Apri il file ma non utilizzi il puntatore, cioè non fai nulla */
       if(L == NULL) 
          return L;
    
       Nodo* tmp;
       
       printf("Inserisci il numero da cancellare\n");
       scanf("%s %lg %lg", id, &reale, &immaginario);
    
       /* eliminazione in testa*/
          if((strcmp(L->id, id) == 0) && (L->reale == reale) && (L->immaginario == immaginario)) {
             tmp = L->next;
             free(L);
             return tmp;  /* Dopo aver cancellato ritorni, qui la funzione finisce il suo  compito */
          }
         /* Se non cancelli nulla allora fai una copia della lista L in copia */
          Lista copia = L;
    
          while(copia->next && ((strcmp(copia->next->id, id) != 0) && (copia->next->reale != reale) && (copia->next->immaginario != immaginario))) {
                /* se il seguente non ha un seguente
                 * abbiamo finito: l'elemento non e'
                 * presente nella lista */
                if(!copia->next->next)
                   return L; /* Qui di nuovo esci proprio dalla funzione */
                copia = copia->next;
          }     
    
          tmp = copia->next;
          copia->next = copia->next->next;
          free(tmp);
          return L; /* Qui di nuovo esci proprio dalla funzione */
       fclose(fp); /* In questo punto la funzione non arriverà mai */
    }
    
  • Re: Problema rimozione elemento da lista [C]

    minomic ha scritto:


    No ma aspetta un momento perché mi sta venendo un dubbio vedendo quel fp. Ma stai cercando di cancellare un numero da una lista scritta su un file?
    si esattamente.. perché?
  • Re: Problema rimozione elemento da lista [C]

    SVNiko ha scritto:


    Ho velocemente visto solo questa funzione, noto alcune cose che non vanno.
    Tante uscite non strutturali dalla funzione, si possono utilizzare, ma bisogna stare attenti, poi apri un file ma non utilizzi mai lo stream, che cosa intendevi fare?
    
    Lista elimina_valore(Lista L) {
    
       fp = fopen("lista.txt", "a");  /* Apri il file ma non utilizzi il puntatore, cioè non fai nulla */
       if(L == NULL) 
          return L;
    
    Cosa intendi con quel " non fai nulla", apro il file visto che devo eliminare una riga di quel file..
    
       Nodo* tmp;
       
       printf("Inserisci il numero da cancellare\n");
       scanf("%s %lg %lg", id, &reale, &immaginario);
    
       /* eliminazione in testa*/
          if((strcmp(L->id, id) == 0) && (L->reale == reale) && (L->immaginario == immaginario)) {
             tmp = L->next;
             free(L);
             return tmp;  /* Dopo aver cancellato ritorni, qui la funzione finisce il suo  compito */
          }
         /* Se non cancelli nulla allora fai una copia della lista L in copia */
          Lista copia = L;
    
    Qui contollo se il numero inserito è il primo nono della lista e in quel caso la funzione è giusto che finisca qua, se non è il primo nodo della lista, copio la lista L in copia e vado avanti.. giusto?
    
          while(copia->next && ((strcmp(copia->next->id, id) != 0) && (copia->next->reale != reale) && (copia->next->immaginario != immaginario))) {
                /* se il seguente non ha un seguente
                 * abbiamo finito: l'elemento non e'
                 * presente nella lista */
                if(!copia->next->next)
                   return L; /* Qui di nuovo esci proprio dalla funzione */
                copia = copia->next;
          }     
    
    Ciclo finché non trovo il nodo che ho inserito, e se non lo trovo esco.
    
          tmp = copia->next;
          copia->next = copia->next->next;
          free(tmp);
          return L; /* Qui di nuovo esci proprio dalla funzione */
       fclose(fp); /* In questo punto la funzione non arriverà mai */
    }
    
    se lo trovo faccio la free ed esco dalla funzione. fclose in quella posizione è sbagliato hai ragione..
  • Re: Problema rimozione elemento da lista [C]

    ofcar ha scritto:


    SVNiko ha scritto:


    Ho velocemente visto solo questa funzione, noto alcune cose che non vanno.
    Tante uscite non strutturali dalla funzione, si possono utilizzare, ma bisogna stare attenti, poi apri un file ma non utilizzi mai lo stream, che cosa intendevi fare?
    
    Lista elimina_valore(Lista L) {
    
       fp = fopen("lista.txt", "a");  /* Apri il file ma non utilizzi il puntatore, cioè non fai nulla */
       if(L == NULL) 
          return L;
    
    Cosa intendi con quel " non fai nulla", apro il file visto che devo eliminare una riga di quel file..

    Allora se apri un file, il puntatore allo stream del file devi utilizzarlo, per poter leggere o scrivere nel file, tu non utilizzi affato il puntatore fp. Apri semplicemente il file.
    
       Nodo* tmp;
       
       printf("Inserisci il numero da cancellare\n");
       scanf("%s %lg %lg", id, &reale, &immaginario);
    
       /* eliminazione in testa*/
          if((strcmp(L->id, id) == 0) && (L->reale == reale) && (L->immaginario == immaginario)) {
             tmp = L->next;
             free(L);
             return tmp;  /* Dopo aver cancellato ritorni, qui la funzione finisce il suo  compito */
          }
         /* Se non cancelli nulla allora fai una copia della lista L in copia */
          Lista copia = L;
    
    Qui contollo se il numero inserito è il primo nono della lista e in quel caso la funzione è giusto che finisca qua, se non è il primo nodo della lista, copio la lista L in copia e vado avanti.. giusto?

    La lista L è quella passata come parametro alla funzione, quindi tu cancelli qualcosa alla lista che passi, il file non è minimamente toccato.
    
          while(copia->next && ((strcmp(copia->next->id, id) != 0) && (copia->next->reale != reale) && (copia->next->immaginario != immaginario))) {
                /* se il seguente non ha un seguente
                 * abbiamo finito: l'elemento non e'
                 * presente nella lista */
                if(!copia->next->next)
                   return L; /* Qui di nuovo esci proprio dalla funzione */
                copia = copia->next;
          }     
    
    Ciclo finché non trovo il nodo che ho inserito, e se non lo trovo esco.
    
          tmp = copia->next;
          copia->next = copia->next->next;
          free(tmp);
          return L; /* Qui di nuovo esci proprio dalla funzione */
       fclose(fp); /* In questo punto la funzione non arriverà mai */
    }
    
    se lo trovo faccio la free ed esco dalla funzione. fclose in quella posizione è sbagliato hai ragione..
    Concludendo! Se vuoi cancellare una riga del file, dovresti:
    acquisire il file costruendo una lista di appoggio
    fare le eventuali cancellazioni
    riscrivere la lista modificata su file
  • Re: Problema rimozione elemento da lista [C]

    SVNiko ha scritto:


    ofcar ha scritto:


    SVNiko ha scritto:


    Ho velocemente visto solo questa funzione, noto alcune cose che non vanno.
    Tante uscite non strutturali dalla funzione, si possono utilizzare, ma bisogna stare attenti, poi apri un file ma non utilizzi mai lo stream, che cosa intendevi fare?
    
    Lista elimina_valore(Lista L) {
    
       fp = fopen("lista.txt", "a");  /* Apri il file ma non utilizzi il puntatore, cioè non fai nulla */
       if(L == NULL) 
          return L;
    
    Cosa intendi con quel " non fai nulla", apro il file visto che devo eliminare una riga di quel file..

    Allora se apri un file, il puntatore allo stream del file devi utilizzarlo, per poter leggere o scrivere nel file, tu non utilizzi affato il puntatore fp. Apri semplicemente il file.
    
       Nodo* tmp;
       
       printf("Inserisci il numero da cancellare\n");
       scanf("%s %lg %lg", id, &reale, &immaginario);
    
       /* eliminazione in testa*/
          if((strcmp(L->id, id) == 0) && (L->reale == reale) && (L->immaginario == immaginario)) {
             tmp = L->next;
             free(L);
             return tmp;  /* Dopo aver cancellato ritorni, qui la funzione finisce il suo  compito */
          }
         /* Se non cancelli nulla allora fai una copia della lista L in copia */
          Lista copia = L;
    
    Qui contollo se il numero inserito è il primo nono della lista e in quel caso la funzione è giusto che finisca qua, se non è il primo nodo della lista, copio la lista L in copia e vado avanti.. giusto?

    La lista L è quella passata come parametro alla funzione, quindi tu cancelli qualcosa alla lista che passi, il file non è minimamente toccato.
    
          while(copia->next && ((strcmp(copia->next->id, id) != 0) && (copia->next->reale != reale) && (copia->next->immaginario != immaginario))) {
                /* se il seguente non ha un seguente
                 * abbiamo finito: l'elemento non e'
                 * presente nella lista */
                if(!copia->next->next)
                   return L; /* Qui di nuovo esci proprio dalla funzione */
                copia = copia->next;
          }     
    
    Ciclo finché non trovo il nodo che ho inserito, e se non lo trovo esco.
    
          tmp = copia->next;
          copia->next = copia->next->next;
          free(tmp);
          return L; /* Qui di nuovo esci proprio dalla funzione */
       fclose(fp); /* In questo punto la funzione non arriverà mai */
    }
    
    se lo trovo faccio la free ed esco dalla funzione. fclose in quella posizione è sbagliato hai ragione..

    Concludendo! Se vuoi cancellare una riga del file, dovresti:
    acquisire il file costruendo una lista di appoggio
    fare le eventuali cancellazioni
    riscrivere la lista modificata su file
    Per costruire una lista di appoggio devo creare un altro puntatore alla mia lista originale?
    Riguardo a quell'fp: io la lista l'ho allocata dinamicamente, non mi basta aprire il file, lavorarci e richiuderlo per poterlo modificare?
    Riguardo le eventuali cancellazioni: secondo me nel codice vengono effettuate ma poi non applicate.
    Come faccio per stampare le modifiche sul file?
    Sono nuovo alla programmazione in C e non mi è stato spiegato molto.
    Grazie.
  • Re: Problema rimozione elemento da lista [C]

    Facciamo un passo indietro. Ti faccio una domanda:

    Hai un file con su scritte tre stringhe; cartoni.txt
    pippo
    pluto
    paperino

    vuoi cancellare dal file la stringa pluto acquisendo il file in una lista

    Come faresti?
    Scrivi in pseudocodice i passaggi
  • Re: Problema rimozione elemento da lista [C]

    SVNiko ha scritto:


    Facciamo un passo indietro. Ti faccio una domanda:

    Hai un file con su scritte tre stringhe; cartoni.txt
    pippo
    pluto
    paperino

    vuoi cancellare dal file la stringa pluto acquisendo il file in una lista

    Come faresti?
    Scrivi in pseudocodice i passaggi
    
    /*definisco il nodo della lista*/
    typedef struct personaggi {
         char nome;
         struct personaggi *next;
    }personaggi, *p;  
    
    /*dichiaro la funz per eliminare*/
    elimina_nome(p *p_lista);
    
    main {
       elimina_nome();
       return();
    }
    
    elimina_nome(p *p_lista){
    
        personaggi* tmp;
        fp = fopen("cartoni.txt", "a");
       printf("Inserisci il nome da cancellare\n");
       scanf("%c", nome);
       /*se il nodo da eliminare è il primo*/
       if((strcmp(*p_lista->nome, nome))== 0 ){
          	tmp = (*p_lista)->next;
          	free(*p_lista);
       /*se il nodo è in mezzo*/
       }else{
           /*ciclo finché quello che ho inserito è diverso da quello scritto nel file*/
            while((strcmp(*p_lista->next->nome, nome))!= 0 ) {
                (*p_lista) = (*p_lista)->next;
            }
            /*se esco dal while vuol dire che ho trovato il nodo che mi interessa, quindi lo libero*/
            tmp = (*p_lista)->next;
            (*p_lista)->next = (*p_lista)->next->next;
       	free(tmp);
    }
    fclose(fp);
  • Re: Problema rimozione elemento da lista [C]

    No! Non è corretto.

    Prova a scrivere pseudocodice non codice, dei passaggi che faresti.

    Fidati è un utile esercizio se vuoi imparare.

    Provo a darti l'input.

    Apro il file
    Leggo da file e memorizzo in una lista
    Chiedo il nome da eliminare
    .... continua tu
  • Re: Problema rimozione elemento da lista [C]

    ofcar ha scritto:


    minomic ha scritto:


    No ma aspetta un momento perché mi sta venendo un dubbio vedendo quel fp. Ma stai cercando di cancellare un numero da una lista scritta su un file?
    si esattamente.. perché?
    Ah allora il mio dubbio era fondato...
    In questo caso semplicemente non puoi fare come stavi tentando di fare perché tu leggi il file e memorizzi il contenuto in una lista, ma quando elimini un nodo dalla lista non fai alcuna operazione sul file: elimini il nodo dalla lista ma il file rimane invariato.
  • Re: Problema rimozione elemento da lista [C]

    minomic ha scritto:


    ofcar ha scritto:


    minomic ha scritto:


    No ma aspetta un momento perché mi sta venendo un dubbio vedendo quel fp. Ma stai cercando di cancellare un numero da una lista scritta su un file?
    si esattamente.. perché?
    Ah allora il mio dubbio era fondato...
    In questo caso semplicemente non puoi fare come stavi tentando di fare perché tu leggi il file e memorizzi il contenuto in una lista, ma quando elimini un nodo dalla lista non fai alcuna operazione sul file: elimini il nodo dalla lista ma il file rimane invariato.
    Esatto e io non so come applicare l'eliminazione sulla lista..
  • Re: Problema rimozione elemento da lista [C]

    Continui a dire "eliminazione sulla lista" ma a questo punto credo di aver capito che intendi "eliminazione dal file". E' giusto? Insomma, vuoi eliminare fisicamente la riga dal file oppure no? Se non chiarisci questo non possiamo andare avanti.

    Se davvero vuoi eliminare la riga dal file allora la procedura è un po' elaborata ma piuttosto semplice:
    - apri il tuo file in lettura
    - apri un nuovo file in scrittura
    - leggi il tuo file: se il record che hai letto non è da eliminare allora lo ricopi sul nuovo file, altrimenti lo salti
    - chiudi entrambi i file
    - elimini il primo file
    - rinomini il secondo file con il nome che aveva il primo
  • Re: Problema rimozione elemento da lista [C]

    SVNiko ha scritto:


    No! Non è corretto.

    Prova a scrivere pseudocodice non codice, dei passaggi che faresti.

    Fidati è un utile esercizio se vuoi imparare.

    Provo a darti l'input.

    Apro il file
    Leggo da file e memorizzo in una lista
    Chiedo il nome da eliminare
    .... continua tu
    ok..
    Chiedo se il primo elemento corrisponde a quello inserito da tastiera e in quel caso inizializzo un valore temporaneo come il successivo del valore che sto per eliminare.
    Libero il primo nodo
    Altrimenti inizializzo una copia della lista (L)
    Ciclo finché l'elemento inserito è diverso da quelli nella lista, controllo che il nodo successivo non sia nullo
    Scorro i nodi con copia = copia->next
    Esco dal while o quando l'elemento è nullo o quando trovo l'elemento che mi interessa
    In quel caso assegno a temp il valore del nodo che mi interessa e a copia assegno il valore successivo ad esso
    Libero temp.


    Mi manca la parte in cui applico quello che ho fatto sulla lista nel file..
    L'ho fatto sul mio codice invece che su quello dei cartoni animati.. Se vuoi provo anche sul tuo; il mio ce l'avevo sotto:)
  • Re: Problema rimozione elemento da lista [C]

    minomic ha scritto:


    Continui a dire "eliminazione sulla lista" ma a questo punto credo di aver capito che intendi "eliminazione dal file". E' giusto? Insomma, vuoi eliminare fisicamente la riga dal file oppure no? Se non chiarisci questo non possiamo andare avanti.

    Se davvero vuoi eliminare la riga dal file allora la procedura è un po' elaborata ma piuttosto semplice:
    - apri il tuo file in lettura
    - apri un nuovo file in scrittura
    - leggi il tuo file: se il record che hai letto non è da eliminare allora lo ricopi sul nuovo file, altrimenti lo salti
    - chiudi entrambi i file
    - elimini il primo file
    - rinomini il secondo file con il nome che aveva il primo

    Ok adesso provo, intanto grazie mille.
    solo una cosa, come rinomino il secondo file? e come elimino il primo?
    e per stampare le righe nel nuovo file come faccio? me ne stampa solo una..
  • Re: Problema rimozione elemento da lista [C]

    Per eliminare e rinominare ci sono le funzioni rename e remove. Ad esempio
    
        remove("primo.txt");
        rename("secondo.txt", "primo.txt");
    
    Per stampare tutte le righe ti servirà un while.
Devi accedere o registrarti per scrivere nel forum
35 risposte