Ordinamento Struttura in C Language

di il
7 risposte

Ordinamento Struttura in C Language

Ciao a tutti questo e' una simulazione di un' esame universitario, non riesco a ordinare la struttura per data, infatti quando lo eseguo mi visualizza le date in sequenza di come le ho messe in input. Non mi funziona l'ordinamento.Too bad. Please help me
 
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct{
    char codice[5];
    int giorno;
    int mese;
    int anno;
    char luogo[10];
    char descrizione[20];
    int maxpartecipanti;
    int prenotati;
    float prezzo;
}
evento;
evento carica();
void ordinamento(evento eve[], int num);
void visualizza(evento eve);
int main()
{
    evento eventi[MAX];
    int n,i;
    
    printf("INSERIRE NUMERO EVENTI:\n");
    scanf("%d", &n);

    for(i=0;i<n;i++){
        eventi[i]=carica();
        
    }
    for(i=0;i<n;i++){
        ordinamento(&eventi,n);
    }
    for(i=0;i<n;i++){
        visualizza(eventi[i]);
        
    }
    
    return 0;
}
evento carica(){
    evento eve;
    printf("\nINSERIRE CODICE\n");
    scanf("%s", eve.codice);
    printf("\nINSERIRE GIOENO\n");
    scanf("%d", &eve.giorno);
     printf("\nINSERIRE MESE\n");
    scanf("%d", &eve.mese);
    printf("\nINSERIRE ANNO\n");
    scanf("%d", &eve.anno);
    printf("\nINSERIRE DESCRIZIONE\n");
    scanf("%s", eve.descrizione);
    printf("\nINSERIRE LUOGO\n");
    scanf("%s", eve.luogo);
    printf("\nINSERIRE MAX PARTECIPANTI\n");
    scanf("%d", &eve.maxpartecipanti);
    printf("\nINSERIRE PRENOTATI\n");
    scanf("%d", &eve.prenotati);
    printf("\nINSERIRE PREZZO \n");
    scanf("%f", &eve.prezzo);
    return eve;
    
}
void ordinamento(evento eve[], int num){
    int i=0;
    int j=0;
    evento temp;
    for(i=0;i<num-1;i++){
        for (j=i+1;j<num;j++){
            if(eve[i].giorno>eve[j].giorno||eve[i].mese>eve[j].mese||eve[i].anno>eve[j].anno){
                temp=eve[j];
                eve[j]=eve[i];
                eve[i]=temp;
            }
        }
    }
}
void visualizza(evento eve){
    printf("TABELLA AGGIORNATA E ORDINATA");
    printf("\nCODICE %s", eve.codice);
    printf("\nGIORNO %d", eve.giorno);
    printf("\nMESE %d", eve.mese);
    printf("\nANNO %d", eve.anno);
    printf("\nLUOGO %d", eve.luogo);
    printf("\nDESCRIZIONE %s", eve.descrizione);
    printf("\nMAX PARTECIPANTI %d", eve.maxpartecipanti);
    printf("\nPRENOTATI %d", eve.prenotati);
    printf("\nPREZZO %f", eve.prezzo);
}

7 Risposte

  • Re: Ordinamento Struttura in C Language

    La condizione non ha molto senso perchè se hai ad esempio A.anno>B.anno ma B.mese>A.mese lui li scambia comunque. Devi mettere delle condizioni che considerano i sottocasi
    E poi manca la i in eve (scambi sempre con il primo elemento)
  • Re: Ordinamento Struttura in C Language

    Provato su Linux con GCC e non compila...
    gcc -Wall -o "ordinamento" "ordinamento.c" (nella cartella: /home/andrea/SviluppoSW)
    ordinamento.c: In function ‘main’:
    ordinamento.c:31:9: error: assignment to expression with array type
       eventi=carica();
             ^
    ordinamento.c:36:15: warning: passing argument 1 of ‘ordinamento’ from incompatible pointer type [-Wincompatible-pointer-types]
       ordinamento(&eventi,n);
                   ^
    ordinamento.c:19:6: note: expected ‘evento * {aka struct <anonymous> *}’ but argument is of type ‘evento (*)[5] {aka struct <anonymous> (*)[5]}’
     void ordinamento(evento eve[], int num);
          ^~~~~~~~~~~
    ordinamento.c:40:14: error: incompatible type for argument 1 of ‘visualizza’
       visualizza(eventi);
                  ^~~~~~
    ordinamento.c:20:6: note: expected ‘evento {aka struct <anonymous>}’ but argument is of type ‘evento * {aka struct <anonymous> *}’
     void visualizza(evento eve);
          ^~~~~~~~~~
    ordinamento.c: In function ‘ordinamento’:
    ordinamento.c:71:7: error: ‘eve’ is a pointer; did you mean to use ‘->’?
     if(eve.giorno>eve[j].giorno||eve.mese>eve[j].mese||eve.anno>eve[j].anno){
           ^
           ->
    ordinamento.c:71:33: error: ‘eve’ is a pointer; did you mean to use ‘->’?
     if(eve.giorno>eve[j].giorno||eve.mese>eve[j].mese||eve.anno>eve[j].anno){
                                     ^
                                     ->
    ordinamento.c:71:55: error: ‘eve’ is a pointer; did you mean to use ‘->’?
     if(eve.giorno>eve[j].giorno||eve.mese>eve[j].mese||eve.anno>eve[j].anno){
                                                           ^
                                                           ->
    ordinamento.c:72:20: error: incompatible types when assigning to type ‘evento {aka struct <anonymous>}’ from type ‘evento * {aka struct <anonymous> *}’
     temp=eve[j]; eve[j]=eve; eve=temp; } } } } void visualizza(evento eve){
                        ^
    ordinamento.c:72:29: error: incompatible types when assigning to type ‘evento * {aka struct <anonymous> *}’ from type ‘evento {aka struct <anonymous>}’
     temp=eve[j]; eve[j]=eve; eve=temp; } } } } void visualizza(evento eve){
                                 ^
    ordinamento.c: In function ‘visualizza’:
    ordinamento.c:75:60: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
     eve.mese); printf("\nANNO %d", eve.anno); printf("\nLUOGO %d",
                                                                ^
    ordinamento.c:76:65: warning: missing terminating " character
     eve.luogo); printf("\nDESCRIZIONE %s", eve.descrizione); printf("\nMAX
                                                                     ^
    ordinamento.c:76:65: error: missing terminating " character
     eve.luogo); printf("\nDESCRIZIONE %s", eve.descrizione); printf("\nMAX
                                                                     ^~~~~~
    ordinamento.c:77:1: error: ‘PARTECIPANTI’ undeclared (first use in this function)
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
     ^~~~~~~~~~~~
    ordinamento.c:77:1: note: each undeclared identifier is reported only once for each function it appears in
    ordinamento.c:77:15: error: ‘d’ undeclared (first use in this function)
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
                   ^
    ordinamento.c:77:16: error: expected ‘)’ before string constant
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ordinamento.c:77:49: error: stray ‘\’ in program
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
                                                     ^
    ordinamento.c:77:63: warning: missing terminating " character
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
                                                                   ^
    ordinamento.c:77:63: error: missing terminating " character
     PARTECIPANTI %d", eve.maxpartecipanti); printf("\nPRENOTATI %d",
                                                                   ^~
    Compilazione fallita.
    
  • Re: Ordinamento Struttura in C Language

    Per la questione dell'ordinamento, potresti "compattare" le date in un unico valore di tipo unsigned long per semplificare il confronto. Con l'operatore di scostamento bit e qualche cast è abbastanza semplice:
    unsigned long data_in_unsigned_long( const evento *e ) {
        unsigned long a = ((unsigned long)e->anno)<<16;
        unsigned long m = ((unsigned long)e->mese)<<8;
        unsigned long g = ((unsigned long)e->giorno);
        return a | m | g;
    }
    Se non sei pratico dell'operatore di scostamento bit <<, in un esempio con data 20/2/2019 l'operazione provoca questo effetto:
    2019 = 00000000 00000000 00000111 11100011
    2    = 00000000 00000000 00000000 00000010
    20   = 00000000 00000000 00000000 00010100
    
    Scostando a sinistra l'anno 2019 di 16 bit con << si ottiene
    
    prima: 00000000 00000000 00000111 11100011
    dopo:  00000111 11100011 00000000 00000000
    
    scostando a sinistra il mese 2 di 8 bit con << si ottiene
    
    prima: 00000000 00000000 00000000 00000010
    dopo:  00000000 00000000 00000010 00000000
    
    il giorno 20 non serve scostarlo, per cui rimane com'e'
    
    prima: 00000000 00000000 00000000 00010100
    dopo:  00000000 00000000 00000000 00010100
    A questo punto puoi "assemblare" i tre valori in un unico valore a 32 bit usando l'operatore |, che "accorpa" i bit precedentemente posizionati:
    ====== anno====== ==mese== =giorno=
    00000111 11100011 00000010 00010100
    Per confrontare le date in questo formato si possono usare i comuni operatori ==, <, >, <=, >= su un unico valore, il che è molto semplice.

    Per poter usare qsort() dovrai predisporre una funzione "di servizio" della quale passerai poi il puntatore:
    int confronta_eventi( const void *e1, const void *e2 ) {
        unsigned long d1 = data_in_unsigned_long( e1 );
        unsigned long d2 = data_in_unsigned_long( e2 );
        return d1==d2 ? 0 : (d1<d2 ? -1 : 1);
    }
    In C *void è un puntatore generico, per cui puoi benissimo passarlo a data_in_unsigned_long() senza cast.

    Alla fine della fiera, la chiamata a qsort() nel tuo main() si riduce a:
    qsort( eventi, n, sizeof(*eventi), confronta_eventi );
    Dunque, in questo esempio ti ho proposto:

    1) cast di tipo
    2) operatore di scostamento bit
    3) operatore bit-a-bit | (or)
    4) puntatori a void
    5) operatore ternario ?:
    6) qsort() (da stdlib.h)
  • Re: Ordinamento Struttura in C Language

    Probabilmente non avete mai visto/utilizzato la qsort() di libreria, quindi continua ad usare quello che conosci.

    Piuttosto, inserisci i tag CODE nel tuo primo post per il codice altrimenti non si capisce nulla (molti [ i ] sono scomparsi)
  • Re: Ordinamento Struttura in C Language

    Grazie a tutti, questo è il mio primo post su un forum in assoluto quindi scusatemi se non ho usato il Tag CODE come mi avete suggerito... THANKS to everyone per le risposte! Peace
  • Re: Ordinamento Struttura in C Language

    Anche se è il primo post, il regolamento va letto prima. Così avresti saputo che il codice va presentato in un determinato modo per consentire agli altri di risponderti. In ogni caso, adesso perché non lo usi? Modifica il post e inserisci i tag CODE.
  • Re: Ordinamento Struttura in C Language

    Fatto
Devi accedere o registrarti per scrivere nel forum
7 risposte