Problema ordinamento in un file [C]

di il
39 risposte

39 Risposte - Pagina 3

  • Re: Problema ordinamento in un file [C]

    Mimonic! È un 5--, va solo per grazia di dio e diamo i nomi giusti nei posti giusti, passiamo per riferimento e non creiamo cose superflue ed inutili.
  • Re: Problema ordinamento in un file [C]

    vbextreme ha scritto:


    È un 5--, va solo per grazia di dio
    Non mi pare di aver chiesto una valutazione. Siamo su un forum per esprimere pareri, quindi se hai osservazioni da fare sono ben lieto di leggerle e imparare da chi ha più esperienza di me. Detto questo, non sono qui per farmi dare un voto: non avrei mai l'arroganza di dare un voto a qualcuno e preferisco che mi si porti lo stesso rispetto.
    Aggiungo che non credo alla grazia di Dio applicata alla programmazione in C: se un codice funziona allora funziona. Se funziona ma è scritto male, beh... funziona comunque. Evidentemente è scritto in maniera sufficientemente corretta da farlo funzionare in quel particolare caso.

    Ripeto: siamo tutti qui per imparare, io per primo. Però cerchiamo di mantenere un atteggiamento costruttivo e di non scadere in atteggiamenti arroganti. Ti pare?

    Saluti.
  • Re: Problema ordinamento in un file [C]

    Sono sempre stato una persona molto diretta e sempre pronta ad imparare.
    Ho solo fatto una osservazione, il codice è poco curato e non si capisce come faccia a funzionare, eccoti la traduzione del post sopra citato.
    So che potresti fare meglio, speravo che il voto ti incoraggiasse.
  • Re: Problema ordinamento in un file [C]

    Sono sempre stato una persona molto diretta e sempre pronta ad imparare.
    Ho solo fatto una osservazione, il codice è poco curato e non si capisce come faccia a funzionare, eccoti la traduzione del post sopra citato.
    So che potresti fare meglio, speravo che il voto ti incoraggiasse.
  • Re: Problema ordinamento in un file [C]

    vbextreme ha scritto:


    So che potresti fare meglio, speravo che il voto ti incoraggiasse.
    Ma a fine anno c'è anche la pagella? I miei genitori possono avere un colloquio con te? Ci mancava solo "e' intelligente ma non si applica"... Ma robe da matti!

    Va beh dai, per me la chiudiamo qui.

  • Re: Problema ordinamento in un file [C]

    minomic ha scritto:


    Io e vbextreme abbiamo provato a farti ragionare a fondo, però secondo me non riusciamo a fare passi avanti. A questo punto proviamo questa strada: guarda bene questo codice, che non è perfetto ma è un punto di partenza.
    
    #include <stdio.h>
    #include <stdlib.h>
    
    // Contenitore generico per i dati
    typedef struct record_t_ {
    	int valore;
    } Record;
    
    // Funzione che esegue il confronto tra due record
    int minore_di(Record r1, Record r2) {
    	if(r1.valore < r2.valore)
    		return 1;
    	return 0;
    }
    
    /* Un nodo della lista, costituito da un
     * record e dal puntatore al nodo successivo */
    typedef struct nodo_lista_t {
    	Record rec;
    	struct nodo_lista_t* next;
    } Nodo;
    
    typedef Nodo* Lista;
    
    /* Funzione che aggiunge un nuovo Record alla lista,
     * mantenendo l'ordinamento della lista stessa */
    Lista aggiungi_in_ordine(Lista L, Record n_elemento) {
    	// Creazione del nuovo nodo
    	Nodo* n_nodo = malloc(sizeof(Nodo));
    	n_nodo->rec = n_elemento;
    	n_nodo->next = NULL;
    
    	if(L == NULL)
    		return n_nodo;
    
    	// Inserimento in testa
    	if(minore_di(n_elemento, L->rec)) {
    		n_nodo->next = L;
    		return n_nodo;
    	}
    
    	// Copia del puntatore alla testa della lista
    	Lista tmp = L;
    
    	while(tmp) {
    		if(tmp->next == NULL || minore_di(n_elemento, tmp->next->rec)) {
    			// Inserisco il nuovo nodo
    			n_nodo->next = tmp->next;
    			tmp->next = n_nodo;
    			return L;
    		}
    		tmp = tmp->next;
    	}
    
    	// Tanto per metterci qualcosa: qui non ci arriva mai
    	return NULL;
    }
    
    void stampa_lista(Lista L) {
    	while(L) {
    		/* La stampa dipende dal tipo di dato che
    		 * viene memorizzato nel Record */
    		printf("%d  ", L->rec.valore);
    		L = L->next;
    	}
    	printf("\n");
    }
    
    int main(int argc, char const *argv[])
    {
    	Lista L = NULL;
    	FILE* fp = fopen("valori.txt", "r");
    	char* buffer = malloc(100 * sizeof(char));
    	int numero_letto;
    	Record record;
    
    	while((buffer = fgets(buffer, 100, fp)) != NULL) {
    		numero_letto = atoi(buffer);
    		printf("Numero letto: %d\n", numero_letto);
    		record.valore = numero_letto;
    		L = aggiungi_in_ordine(L, record);		
    	}
    
    	stampa_lista(L);
    
    	fclose(fp);
    
    	return 0;
    }
    
    Fa le seguenti cose: apre un file, legge dei valori e li memorizza in una lista in ordine crescente. L'ho testato con un file dal seguente contenuto:
    
    2
    3
    4
    1
    5
    
    e l'output prodotto è
    
    Numero letto: 2
    Numero letto: 3
    Numero letto: 4
    Numero letto: 1
    Numero letto: 5
    1  2  3  4  5  
    
    Noterai che ciò che viene memorizzato nella lista non è un singolo valore, ma una struct che ho chiamato Record. Ho fatto questo per facilitarti nel momento in cui lo andrai a modificare per contenere i tuoi numeri complessi (al posto di un int valore avrai un int parte_reale e int parte_immaginaria).
    A questo punto vediamo le modifiche che devi fare per arrivare al tuo risultato definitivo:
    - gestione dei numeri complessi come dicevo prima: due int (o float, o quello che vuoi) all'interno di ogni Record
    - salvataggio su file della lista ordinata: apri un nuovo file in scrittura, scrivi, elimini il vecchio file e rinomini il nuovo

    A questo punto dovresti aver terminato. Per altri dubbi siamo qui.

    Buon lavoro.

    Sto cercando di adattare il codice che mi hai proposto a quello che sto realizzando, ma mi da qualche problema.. Volevo chiederti un paio di cose:
    1. Io ho già una funzione stampa lista quindi volevo sapere se dovevo lasciare la tua oppure potevo usare la mia;
    2. Idem per il main: ho il mio main e la mia funzione la richiamavo solo con un
    ordina_lista(nodo)
    quindi mi chiedevo se la malloc, il while e tutto il resto li dovevo copiare nel mio main.
    Grazie
  • Re: Problema ordinamento in un file [C]

    No quello che ti ho postato è solo un esempio. La funzione stampa la puoi fare come vuoi, basta che stampi! Idem per il resto. Più che altro voleva essere un modello di come affrontare il problema. Anche perché ora ti basta veramente poco per risolvere: l'inserimento ordinato nella lista è già fatto, basta cambiare il tipo di dato che inserisci nel Record (non più un int ma la rappresentazione di un numero complesso) e scrivere tutto su un nuovo file. Poi dovresti aver terminato.
  • Re: Problema ordinamento in un file [C]

    minomic ha scritto:


    No quello che ti ho postato è solo un esempio. La funzione stampa la puoi fare come vuoi, basta che stampi! Idem per il resto. Più che altro voleva essere un modello di come affrontare il problema. Anche perché ora ti basta veramente poco per risolvere: l'inserimento ordinato nella lista è già fatto, basta cambiare il tipo di dato che inserisci nel Record (non più un int ma la rappresentazione di un numero complesso) e scrivere tutto su un nuovo file. Poi dovresti aver terminato.
    Ok capito, quel while che inserisci nel main
    while((buffer = fgets(buffer, 100, fp)) != NULL) {
          		numero_letto = atoi(buffer);
          		record.reale = numero_letto;
          		L1 = aggiungi_in_ordine(L1, record);
    	        fclose(fp);
    cosa significa e cosa fa? Perché non ho mai usato ne la fgets ne la funzione atoi.
    E' necessaria perché il codice funzioni?

    edit: Ho provato a lasciarlo ma il codice non va; non mi da errori in compilazione ma una memory corruption quando chiedo di ordinare una lista. Ti posto il mio tentativo:
    Lista_l aggiungi_in_ordine(Lista_l L1, Record n_elemento) {
       /* Creazione del nuovo nodo*/
       fp = fopen("lista.txt", "r");
       Nodo_l* n_nodo = malloc(sizeof(Nodo_l));
       n_nodo->rec = n_elemento;
       n_nodo->next = NULL;
    
       if(L1 == NULL)
          return n_nodo;
    
       /* Inserimento in testa*/
       if(minore_di(n_elemento, L1->rec)) {
          n_nodo->next = L1;
          return n_nodo;
       }
    
       /* Copia del puntatore alla testa della lista*/
       Lista_l tmp = L1;
    
       	while(tmp) {
          		if(tmp->next == NULL || minore_di(n_elemento, tmp->next->rec)) {
             	/* Inserisco il nuovo nodo*/
             		n_nodo->next = tmp->next;
             		tmp->next = n_nodo;
             		return L1;
          		}
          		tmp = tmp->next;
       	}
    	fn = fopen("secondo.txt", "w+");
    	while(L1) {
    		fprintf(fn, "%s %g %g\n", L1->rec.id, L1->rec.reale, L1->rec.immaginario);
    		L1 = L1->next;
    	}
            fclose(fn);
    	fclose(fp);
    	remove("lista.txt");
    	rename("secondo.txt", "lista.txt");
    
       /* Tanto per metterci qualcosa: qui non ci arriva mai*/
       return NULL;
    }
    
    
  • Re: Problema ordinamento in un file [C]

    ofcar ha scritto:


    quel while che inserisci nel main
    while((buffer = fgets(buffer, 100, fp)) != NULL) {
          		numero_letto = atoi(buffer);
          		record.reale = numero_letto;
          		L1 = aggiungi_in_ordine(L1, record);
    	        fclose(fp);
    cosa significa e cosa fa? Perché non ho mai usato ne la fgets ne la funzione atoi.
    E' necessaria perché il codice funzioni?
    Il while ha la seguente funzione:
    - legge una riga dal file tramite la fgets e la memorizza, sotto forma di stringa, in buffer
    - converte la stringa che abbiamo appena letto nella corrispondente rappresentazione numerica tramite la atoi (ASCII to integer) e memorizza il risultato nella variabile numero_letto
    - memorizza questo numero_letto in un campo del Record
    - aggiunge il record alla lista mantenendone l'ordinamento

    A questo punto però, se fai fclose chiudi il file. Quindi come fai poi a leggere la riga successiva? Io avevo messo fclose solo alla fine!
  • Re: Problema ordinamento in un file [C]

    minomic ha scritto:


    ofcar ha scritto:


    quel while che inserisci nel main
    while((buffer = fgets(buffer, 100, fp)) != NULL) {
          		numero_letto = atoi(buffer);
          		record.reale = numero_letto;
          		L1 = aggiungi_in_ordine(L1, record);
    	        fclose(fp);
    cosa significa e cosa fa? Perché non ho mai usato ne la fgets ne la funzione atoi.
    E' necessaria perché il codice funzioni?
    Il while ha la seguente funzione:
    - legge una riga dal file tramite la fgets e la memorizza, sotto forma di stringa, in buffer
    - converte la stringa che abbiamo appena letto nella corrispondente rappresentazione numerica tramite la atoi (ASCII to integer) e memorizza il risultato nella variabile numero_letto
    - memorizza questo numero_letto in un campo del Record
    - aggiunge il record alla lista mantenendone l'ordinamento

    A questo punto però, se fai fclose chiudi il file. Quindi come fai poi a leggere la riga successiva? Io avevo messo fclose solo alla fine!
    era proprio quello che mi dava errore.
    Solo che ora non ordina.. il codice è rimasto quello che ho postato nel commento prima, con ovviamente l'fclose spostato. Praticamente mi ristampa la lista uguale.
Devi accedere o registrarti per scrivere nel forum
39 risposte