SCRITTURA DI UNA LISTA SU FILE HELP

di il
9 risposte

SCRITTURA DI UNA LISTA SU FILE HELP

Ho un problema con un programma che sto tentando di sviluppare in C.
Premetto che non ho molta esperienza con la programmazione, quindi mi scuso in anticipo se il
problema verrà considerato banale.
Il programma che ho scritto, ad un certo punto, passa una lista di cinque elementi ad una funzione che stampa la lista sul file; solo che non funziona e non riesco a capire perchè. Posto il codice

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

typedef char tipo_elemento;

struct coda {           // definisco la struttura pe realizzare la lista
     tipo_elemento valore;
     struct coda *next;
};

struct coda *crea_coda(tipo_elemento *elementi);

void stampa_coda(struct coda *queue);

void stampa_coda_su_file(struct coda *queue); // identifico il prototipo di funzione per salvare la //lista su file

tipo_elemento pop(struct coda **queue);

struct coda *push(struct coda *queue, tipo_elemento t);

int libera_coda(struct coda *queue);

int main(int argc, char *argv[])
{ struct coda *c1; //puntatore alla struct coda che verrà passato per creare la coda e per salvarla //su file
  int testa, mem;
  int scelta;
  int decisione;
  char car = '6';
  
  tipo_elemento elems[5] = {'1','2','3','4','5'};
  c1 = NULL;
   
   do{
   printf("scegli l'opzione che preferisci\ndigitare zero per uscire\n1-crea la coda\n2-elimina il primo elemento\n3-inserisci elemento\n4-libera la memoria\n5-salva la coda su file\n");
   scanf("%d", &scelta);    
       
      switch (scelta) {
  
             case 1:  
             printf("creo la coda...\n");
             c1 = crea_coda(elems);
             stampa_coda(c1);
             break;
  
             case 2:
             printf("Elimino la testa: ");
             testa = pop(&c1);
             printf("%c\t", testa);
             stampa_coda(c1);
             break;
  
             case 3:
             printf("inserisco elemento %c ... ", car);
             c1 = push(c1, car);
             stampa_coda(c1);
             break;
  
             case 4:
             printf("libero la memoria...\n");
             mem = libera_coda(c1);
             printf("bytes di memoria liberati: %d\n", mem);
             break;
             
             case 5:
             stampa_coda_su_file(c1); //richiamo la funzione per stampare la lista su file
             break;     
  
             default:
             scelta=0;
             break;        
  }
  } while(scelta != 0);
     
  system("PAUSE");	
  return 0;
}

struct coda *crea_coda(tipo_elemento *elementi)
{  
    struct coda *nuovo, *precedente, *primo;
    int index;
    
      if(elementi == NULL)
        return NULL;
        
    primo = nuovo = precedente = malloc(sizeof(struct coda));
    nuovo->valore = elementi[0];
    nuovo->next = NULL;
    
    for(index=1; index<5; index++)
    { precedente = nuovo;
      nuovo = malloc(sizeof(struct coda));
      memset(nuovo, 0, sizeof(struct coda));
      nuovo->valore = elementi[index];
      precedente->next = nuovo;
       }
       
       return primo;
}

void stampa_coda(struct coda *queue)
{  while (queue != NULL)
     { printf("valore: %c\t", queue->valore);     
       queue = queue->next;  
         }
      //  printf("\b \n");
}

void stampa_coda_su_file(struct coda *queue) //FUNZIONE CHE STAMPA LA CODA SUL FILE
                                                                     // PASSO C1 DAL MAIN
{   FILE *fp;
     
     fp = fopen("LISTA.txt", "rw");
     if(fp == NULL){ 
          printf("impossibile aprire il file");
          return;}
          else
              while (queue != NULL)
              {fprintf(fp,"%c\t",queue->valore);     
               queue = queue->next;  
         }
         fclose(fp);
}

tipo_elemento pop(struct coda **queue)
{ struct coda *q1;
  tipo_elemento elem;
  
    q1 = *queue;
    elem = q1->valore;
    *queue = (*queue)->next;
    free(q1);
    return elem;
  }
  
struct coda *push(struct coda *queue, tipo_elemento t) 
{ 
  struct coda *prev, *first;
  
  first = queue;
  while(queue){
     prev = queue;
     queue = queue->next; 
     }
   prev->next = malloc(sizeof(struct coda));
   memset(prev->next, 0, sizeof(struct coda));
   
   if(prev->next == NULL){
     perror("non c'è abbastanza memoria");
     return queue;
     }
   else { prev->next->valore = t;
          prev->next->next = NULL;
        }
     return first;
  }
  
int libera_coda(struct coda *queue){
    struct coda *q1;
    int bytes = 0;
    while (queue)
    { q1 = queue;
      queue = queue->next;
      free(q1);
      
      q1 = NULL;
      bytes += sizeof(struct coda);
          }
    return bytes;
}
In salva_lista_su_file, passo un argomento di tipo struct coda, poi dovrebbe stampare il file. Non invio la lista prima di cancellarla, quindi il problema non è quello, e tutto il resto del codice funziona perfettamente. Il compilatore è il Dev-C.
Grazie in anticipo per gli eventuali aiuti.

Edit skynet: inserimento code tags

9 Risposte

  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Code tags please.
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Sei stato gentile a postare tutto il codice.

    Se sostituisci
    fp = fopen("LISTA.txt", "rw");
    con
    fp = fopen("LISTA.txt", "w");
    Funziona.

    Ciao.
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Ho provato a fare come mi hai detto, ma non funziona. Mi stampa sul file un output costituito da cinque quadrati uno vicino all'altro. qualcuno sa perchè? Grazie in anticipo per le risposte.
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Scusami solo adesso ho visto che il problema sta nell'uso scorretto di memeset.
    Usata così, la memset non solo non serve a nulla ma crea uno sporcamento di memoria perché copia il carattere "\0" per 5 volte a partire dalla locazione puntata dal puntatore (scusa la ripetizione).
    Poi ci sono un pò di puntatori vaganti o non utilizzati ai quali devi stare attento.
    Se vuoi ci mettiamo mano insieme a tutti gli altri del forum, ma prima proba ad analizzare il tuo codice con questi suggerimenti,

    Ciao
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Ciao,
    uso il devc++ e il sistema operativo è windows. Sono sicuro che il codice si giusto e compilo solo il codice postato. Non è la prfima volta che mi succede una cosa del genere. Mi potresti consigliare un buon compilatore per C?
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Scusa. Leggi il mio precedente messaggio perché l'ho ri-editato. Ho trovato diversi punti nel tuo codice che meritano la tua attenzione. Comunque dev-C++ è un discreto ambiente di sviluppo. L'ambiente usa il compilatore Mingw. La vera alternativa è passare a Linux. Molti apprezzano Visual C, ma io no. Credo che per il tuo livello puoi continuare a usare Dev-C++ ancora per un pò. Magari, se non l'hai fatto, aggiornalo da . Ciao.
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Per quanto riguarda Windows, non ti consiglio di utilizzare DevC++ (soprattutto nella versione che comunemente si trova in rete) in quanto è obsoleto e pieno di bug oltre che dotato di strumenti di debug poco efficienti.

    Se continui a programmare con Windows, potresti utilizzare CodeBlocks oppure, perché no, Visual C++ Express Edition che è un ottimo ambiente e compilatore con un debugger veramente potente (non mi interessa la diatriba anti Microsoft se il prodotto che ho provato è soddisfacente).

    Detto questo, la memset non è un problema e funziona regolarmente, azzerando la memoria allocata per l'elemento della lista, compreso il puntatore al prossimo elemento.

    Se hai corretto la fopen, allora non dovresti avere alcun problema.
    Personalmente ho creato la lista (1) e scritto il file (5) e viene regolarmente creato (l'ho aperto con notepad++).
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Ho risolto. Ho effettuato l'aggiornamento di dev-c++ e mi dava un errore su memset; dovevo includere la libreria <string.h>. Ho scaricato notepad e apro il file con notepad. Funziona, mi escono i numeri e non i quadratini. Deve essere un problema di incompatibilità fra dev-c++ e blocknote.
    Grazie a tutti.
  • Re: SCRITTURA DI UNA LISTA SU FILE HELP

    Me ne compiaccio e scusami per averti dato una indicazione sbagliata:
    l'uso di memset è corretto e anche molto efficiente.
    Per quanto riguarda il compilatore, o meglio l'IDE, sono contento che tu abbai aggiornato Dev-C++. Il progetto Dev-C++ è stato riesumato e spero vada avanti.
    Gli ambienti di sviluppo consigliati da Oregon sono molto validi e, in particolare, Codeblock ha il vantaggio di essere multipiattaforma (se decidi di usarlo ricordati di scaricare anche un compilatore altrimenti non ci farai molto). Il Visual C non lo amo ma non lo sconsiglio.
Devi accedere o registrarti per scrivere nel forum
9 risposte