Scl, inserimento in coda da file

di il
5 risposte

Scl, inserimento in coda da file

Testo:
Implementare in C la funzione:
TipoLista leggi_lista(const char* nomefile);
Tale funzione, presa in input la stringa nomefile che rappresenta il percorso di un file di testo contenente valori reali, restituisce una nuova lista contenente i valori presenti nel le, nello stesso ordine in cui occorrono in esso. I valori nel file sono separati da spazi bianchi o caratteri di ritorno a capo. Ad esempio, con il seguente le di input:
0.456 9.785 13.0
12.9
2.5
La funzione deve restituire la lista:
0.456 9.785 13.0 12.9 2.5
Se il file non puo essere aperto correttamente (perché, ad esempio, inesistente), la funzione deve
restituire la lista vuota
Il mio file txt è:
6.7 0.456 9.785 13.0
12.9
2.5
Il mio programma:

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

struct elemSCL{
	float info;
	struct elemSCL *next;
};

typedef struct elemSCL TipoNodoSCL;
typedef TipoNodoSCL *TipoLista;

TipoLista leggi_lista(const char* nomefile);

int main()
{
	const char *percorso = "double.txt";
	TipoLista scl;
	scl = leggi_lista(percorso);
}

TipoLista leggi_lista(const char* nomefile)
{
	TipoLista aux;
	FILE *f = fopen(nomefile, "r");
	if(f == NULL)
	{
		printf("Errore nell'apertura del file\n");
		TipoLista scl = NULL;
		return scl;
	}
	else
	{
		//Creazione nodo generatore
		
		TipoLista scl = (TipoNodoSCL*) malloc (sizeof(TipoNodoSCL));
		scl -> next = NULL;
		
		TipoLista aux = scl;
		
		float cur_char;
		while(fscanf(f, "%f", &cur_char) != EOF)
		{
			aux -> next = (TipoNodoSCL *) malloc (sizeof(TipoNodoSCL));
			aux = aux -> next;
			aux -> info = cur_char;
			aux -> next = NULL;
		}
		aux = scl;
		scl = aux -> next;
		free(aux);
		
		while(aux != NULL)
		{
			printf("scl -> info: %f\n", aux->info);
			aux = aux -> next;
		}
	}
}
Il quale funziona, ma ha un piccolo neo. Stampa:

scl -> info: 0.000000
scl -> info: 6.700000
scl -> info: 0.456000
scl -> info: 9.785000
scl -> info: 13.000000
scl -> info: 12.900000
scl -> info: 2.500000


scl -> info: 0.000000 da dove salta fuori?
Penso sia riconducibile a *scl = (TipoNodoSCL*) malloc (sizeof(TipoNodoSCL)); (*scl) -> next = NULL;

Non riesco a levarlo..

5 Risposte

  • Re: Scl, inserimento in coda da file

    Ciao,
    non l'ho provato ma, leggendo il codice, credo che l'errore sia qui:
    
    while(fscanf(f, "%f", &cur_char) != EOF)
          {
             aux -> next = (TipoNodoSCL *) malloc (sizeof(TipoNodoSCL));
    
    All'inizio, il primo valore viene inserito subito in un next, lasciando quindi "vuoto" il primo elemento.

    A mio parere, la cosa migliore da fare è scrivere funzioni standard, che facciano cose standard, ed utilizzare quelle. Mi riferisco a una semplice implementazione della funzione per l'inserimento di un elemento in coda a una lista, che contempli anche il caso in cui l'elemento che andiamo ad inserire sia il primo. Dopodiché non farai altro che richiamare questa funzione per ogni elemento da inserire.

  • Re: Scl, inserimento in coda da file

    A proposito... una possibile implementazione per l'inserimento in coda è questa:
    
    TipoLista ins_in_coda (TipoLista lista, TipoElemento el)
    {
    	TipoLista new_el = (TipoLista) malloc(sizeof(struct lista_t));
    	new_el->info = el;
    	new_el->next = NULL;
    	
    	if(lista == NULL)
    		return new_el;
    		
    	TipoLista aux = lista;
    	while(aux->next != NULL)
    		aux = aux->next;
    		
    	aux->next = new_el;
    	
    	return lista;
    }
    
    Anche questa l'ho scritta senza provarla, quindi magari c'è qualche errore. Però l'idea di fondo è quella.
  • Re: Scl, inserimento in coda da file

    Se levassi il -> next a cui tu fai riferimento il programma andrebbe in errore di segmentazione..

    minomic ha scritto:



    A mio parere, la cosa migliore da fare è scrivere funzioni standard, che facciano cose standard, ed utilizzare quelle. Mi riferisco a una semplice implementazione della funzione per l'inserimento di un elemento in coda a una lista, che contempli anche il caso in cui l'elemento che andiamo ad inserire sia il primo. Dopodiché non farai altro che richiamare questa funzione per ogni elemento da inserire.
    Sì, è vero. Però volevo provare senza funzioni ausiliarie
  • Re: Scl, inserimento in coda da file

    davide.fruci ha scritto:


    Se levassi il -> next a cui tu fai riferimento il programma andrebbe in errore di segmentazione..
    Probabilmente è vero, però resta il fatto che l'inserimento del primo elemento non può essere fatto in un next, dato che l'elemento di testa non è il next di un altro elemento.
    Se vuoi mantenere questa impostazione, allora devi modificare un po' la logica. In ogni caso dovresti fare un controllo del tipo
    
    if(lista_vuota) ...
    else ...
    
  • Re: Scl, inserimento in coda da file

    Ho utilizzato una funzione inverti che mi ha "capovolto" la lista (caricata in testa) degli elementi.
    void inverti(TipoLista *scl)
    {
    	TipoLista prec = NULL, suc;
    	while(*scl != NULL)
    	{
    		suc = *scl;
    		*scl = (*scl) -> next;
    		suc -> next = prec;
    		prec = suc;
    	}
    	*scl = prec;
    }
    
    Grazie per i consigli, ne terrò conto! Ciao
Devi accedere o registrarti per scrivere nel forum
5 risposte