Sorting di record scritti su file

di devdivdav il
22 risposte
Buonasera a tutti. Avrei bisogno di una mano per capire come svolgere questo esercizio, fondamentale per superare l'esame base di programmazione in C. Mi trovo a dover scrivere in maniera sequenziale su file di testo una serie di record (del tipo nome, anno, età, quindi char, int, int). Questi record vanno dunque letti e stampati a schermo ordinati in maniera crescente in base al valore anno. Ora, credo che un semplice bubble sort dovrebbe poter andare per una quantità ridotta di dati (parliamo di 6 o 7 record). Tuttavia, pur conoscendo l'algoritmo applicato a semplici vettori, non saprei come utilizzarlo per questo esercizio su file.
Ecco quanto ho scritto finora.

FILE * puntatore;

int main(){
    if((puntatore=fopen("newFile.txt", "r"))==NULL){
        puts("Errore");
    }else{
        char nome[20];
        int anno;
        int years;

        puts("NOME   ANNO    ANNI");
        fscanf(puntatore, "%19s%d%d", nome, &anno, &years);

        while(!feof(puntatore)){
            printf("%s  %d  %d\n", nome, anno, years);
            fscanf(puntatore, "%19s%d%d", nome, &anno, &years);
        }


    fclose(puntatore);

    }
}
Questo codice legge i record dal file e li stampa leggendoli uno dopo l'altro, come posso applicare il bubble sort (che credo sia il più semplice a livello di implementazione) per ordinare i record in base al valore anno?

22 Risposte

  • Tanto per cominciare devi leggere in memoria tutti i dati. Puoi agire in due modi

    - imposti una struttura (struct) con tutti i dati per singolo record e crei un vettore di strutture

    - crei tanti vettori quanti sono i campi del singolo record

    Poi applichi il sort in base alla scelta fatta
  • Scusami, per leggere in memoria intendi ciò che ho fatto qui sopra aprendo il file in modalità "r"? Potresti altrimenti mostrarmelo in codice, se possibile?
  • 
    #define MAX_ENTRIES 1000
    
    typedef struct {
        char nome[20];
        int anno;
        int years;
    } __record;
    
    __record records[MAX_ENTRIES];
    int rec_index = 0;
    
    
        while(!feof(puntatore) && rec_index < MAX_ENTRIES){
            fscanf(puntatore, "%19s %d %d\n", records[rec_index].nome, &records[rec_index].anno, &records[rec_index].years);
            rec_index++;
        }
    
  • Sì, come hai fatto ma leggendo in un array e non in variabili semplici.

    Weierstrass mi ha anticipato con il codice ... anche se sarebbe bene che ti sforzassi tu di scriverlo ...
  • Tanto ne deve mangiare ancora di pastasciutta per arrivare alla soluzione
  • Weierstrass ha scritto:


    Tanto ne deve mangiare ancora di pastasciutta per arrivare alla soluzione
    Temo di si

    Ho cercato di implementare il bubble sort ma non funziona. Se provo a stampare i record ordina soltanto gli anni ma non non i nomi e le età. Inoltre, stampa una serie di 0 prima di mostrare gli anni ordinati.
    
    
    int temp;
     for(int x = 0; x < MAX_ENTRIES - 1; x++){
    
            for(int y = 0; y < MAX_ENTRIES - x - 1; y++){
    
                if(records[y].anno > records[y + 1].anno){
    
                    temp = records[y].anno;
    
                    records[y].anno = records[y + 1].anno;
    
                    records[y + 1].anno = temp;
    
                }
    
            }
    
        }
    
    
    
    Dove può essere l'errore?
  • L'errore sta nel fatto che tu stai scambiando gli anni dei record, mentre devi scambiare i record nella loro interezza. Il controllo va fatto, correttamente, sul valore dell'anno del singolo record, ma quello che va scambiato è l'intero record!

    Supponiamo di avere Pippo che è nato nel 1998 e Paperino che è nato nel 1996.
    Quello che stai facendo tu è confrontare le due persone e scambiare i loro anni di nascita... risultato: dopo lo scambio Pippo sarà nato nel 1996, mentre Paperino nel 1998. Direi che non va affatto bene.
    Non devi scambiare gli anni di nascita, devi scambiare le due Persone nella loro interezza.
  • Per gli zeri, invece, il numero totale di record sarà il rec_index che avrai quando raggiungi la fine del file. MAX_ENTRIES è la dimensione dell'array buffer, che è tutto inizializzato a zero in quanto variabile globale
  • SpiritoLibero ha scritto:


    L'errore sta nel fatto che tu stai scambiando gli anni dei record, mentre devi scambiare i record nella loro interezza. Il controllo va fatto, correttamente, sul valore dell'anno del singolo record, ma quello che va scambiato è l'intero record!

    Supponiamo di avere Pippo che è nato nel 1998 e Paperino che è nato nel 1996.
    Quello che stai facendo tu è confrontare le due persone e scambiare i loro anni di nascita... risultato: dopo lo scambio Pippo sarà nato nel 1996, mentre Paperino nel 1998. Direi che non va affatto bene.
    Non devi scambiare gli anni di nascita, devi scambiare le due Persone nella loro interezza.
    Ma se cambio la sostituzione con temp = records[y], togliendo quindi il valore .anno, mi dà errore: error: incompatible types when assigning to type 'int' from type '__record {aka struct <anonymous>}'.
  • Weierstrass ha scritto:


    Per gli zeri, invece, il numero totale di record sarà il rec_index che avrai quando raggiungi la fine del file. MAX_ENTRIES è la dimensione dell'array buffer, che è tutto inizializzato a zero in quanto variabile globale
    Giusto, grazie mille
  • devdivdav" post_id="8691199 ha scritto:


    Ma se cambio la sostituzione con temp = records[y], togliendo quindi il valore .anno, mi dà errore: error: incompatible types when assigning to type 'int' from type '__record {aka struct <anonymous>}'.
    Ovviamente dato che temp è in int e il record è una struttura. I tipi dei dati devono essere uguali, quindi...?
  • Ehm...devo fare un cast (?) oppure cambiare uno dei due tipi. Non credo proprio di dover/poter cambiare record[y]. Ma se devo cambiare temp cosa dovrei farne? Una struttura?
  • E lo domandi?
  • Please aiutami, sono alle prime armi con la programmazione non pretendo il codice, sto provando a farlo da solo ma certi "dettagli" ancora mi sfuggono
Devi accedere o registrarti per scrivere nel forum
22 risposte