Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - errore di segmentazione in una funzione per passare gli elementi di un albero in un array
Forum - C/C++ - errore di segmentazione in una funzione per passare gli elementi di un albero in un array

Avatar
mik_91 (Normal User)
Newbie


Messaggi: 2
Iscritto: 27/01/2014

Segnala al moderatore
Postato alle 18:35
Lunedì, 27/01/2014
Nel file allegato vi è il codice di un programma che gestisce un database di vini. Il mio problema è che ricevo un errore di segmentazione entrando nella funzione "inserisci_in_albero_bin". E' da un pò di giorni che stò cercando una soluzione ma non riesco a venirne a capo...qualcuno saprebbe aiutarmi??
Codice sorgente - presumibilmente C++

  1. /******************************************************************/
  2. /* Programma per manipolare un file contenente una lista di vini. */
  3. /* Michele Petrocchi            Matricola 256507                  */
  4. /******************************************************************/
  5.  
  6.  
  7. /***********************/
  8. /* inclusione librerie */
  9. /***********************/
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15.  
  16. /*************************************/
  17. /* Dichiarazione costanti simboliche */
  18. /*************************************/
  19.  
  20. #define LUNGHEZZA_NOME 51               /* lunghezza della stringa del nome del vino                    */
  21. #define LUNGHEZZA_CODICE 5              /* lunghezza della stringa del codice del vino                  */
  22. #define LUNGHEZZA_ANNO_PRODUZIONE 5     /* lunghezza della stringa dell'anno di produzione del vino     */
  23. #define LUNGHEZZA_LUOGO_PRODUZIONE 51   /* lunghezza della stringa del luogo di produzione del vino     */
  24. #define PERCORSO_FILE "./file_vini"     /* percorso del file di output                                  */
  25.  
  26.  
  27. /************************/
  28. /* Defibizione dei tipi */
  29. /************************/
  30.  
  31. typedef struct nodo_albero_bin
  32. {
  33.         char    nome_vino[LUNGHEZZA_NOME],                      /* nome del vino                */
  34.                 codice_vino[LUNGHEZZA_CODICE],                  /* codice del vino              */
  35.                 anno_vino[LUNGHEZZA_ANNO_PRODUZIONE],           /* anno di produzione del vino  */
  36.                 luogo_vino[LUNGHEZZA_LUOGO_PRODUZIONE];         /* luogo di produzione del vino */
  37.  
  38.         struct  nodo_albero_bin *sx_p, *dx_p;
  39. } nodo_albero_bin_t;
  40.  
  41.  
  42. typedef struct vino
  43. {
  44.         char    nome_vino[LUNGHEZZA_NOME],                      /* nome del vino                */
  45.                 codice_vino[LUNGHEZZA_CODICE],                  /* codice del vino              */
  46.                 anno_vino[LUNGHEZZA_ANNO_PRODUZIONE],           /* anno di produzione del vino  */
  47.                 luogo_vino[LUNGHEZZA_LUOGO_PRODUZIONE];         /* luogo di produzione del vino */
  48. } vino_t;
  49.  
  50.  
  51. /********************************/
  52. /* Dichiarazione delle funzioni */
  53. /********************************/
  54.  
  55. int controllo_correttezza_file(nodo_albero_bin_t **,
  56.                                FILE *,
  57.                                int *);
  58.  
  59. int inserisci_in_albero_bin(nodo_albero_bin_t ***,     
  60.                             char[],
  61.                             char[],
  62.                             char[],
  63.                             char[]);
  64.  
  65. int inserisci_nuovo_vino(nodo_albero_bin_t **);
  66.  
  67. int rimuovi_vino(nodo_albero_bin_t **);
  68.  
  69. int rimuovi_da_albero_bin(nodo_albero_bin_t ***,       
  70.                           char[]);
  71.  
  72. void stampa_codice(nodo_albero_bin_t *);
  73.  
  74. void stampa_vini(nodo_albero_bin_t *,
  75.                  int,
  76.                  int);
  77.  
  78. void inserisci_vini_in_array(nodo_albero_bin_t *,
  79.                              vino_t [],
  80.                              int);
  81.  
  82. void quicksort_nome(vino_t [],
  83.                     int,
  84.                     int);
  85.  
  86. void quicksort_anno(vino_t [],
  87.                     int,
  88.                     int);
  89.  
  90. void quicksort_luogo(vino_t [],
  91.                      int,
  92.                      int);
  93.  
  94. void stampa_array(int,
  95.                   vino_t *);
  96.  
  97. /******************************/
  98. /* Definizione delle funzioni */
  99. /******************************/
  100.  
  101. int main (int  argc,            /* numero stringhe acquisite lancio comandi */
  102.           char *argv[])         /* stringhe acqusite dal lancio comandi     */
  103. {
  104.         int     esito = 0,
  105.                 esito_ordinamento = 0,
  106.                 esito_pulizia = 1,
  107.                 esito_pulizia_ordinamento = 1,
  108.                 scelta_utente = 0,
  109.                 scelta_ordinamento = 0,
  110.                 rimosso = 0,
  111.                 numero_vini = 0,
  112.                 controllo = 0;
  113.  
  114.         FILE    *input;                                 /* file da dove preleverò la lista dei vini   */
  115.                
  116.         nodo_albero_bin_t       *radice_p = NULL;       /* lavoro: puntatore alla radice dell'albero  */
  117.  
  118.         /* specifichiamo il file di input, quindi deve essere 1 il numero degli argomenti */
  119.         if(argc > 1)
  120.         {
  121.                 /* apriamo il file specificato */
  122.                 input = fopen(argv[1],"r");
  123.  
  124.                 /* se il file specificato esiste */
  125.                 if (input != NULL)
  126.                 {
  127.                         /* acquisisci il numero di vini */
  128.                         esito = fscanf(input, "%d", &numero_vini);
  129.  
  130.                         /* se il numero di vini non è valido */
  131.                         if (esito != 1 || numero_vini < 0)
  132.  
  133.                                 printf("Lettura del numero di vini non riuscita.\n\n");
  134.                         else
  135.                                 controllo = controllo_correttezza_file(&radice_p,
  136.                                                                        input,
  137.                                                                        &numero_vini);
  138.                         /* chiudere il file di input */
  139.                         fclose(input);
  140.  
  141.                         /* se non si sono verificati errori */
  142.                         if (controllo != 1)
  143.                         {
  144.                                 do
  145.                                 {
  146.                                         do
  147.                                         {
  148.                                                 printf("\nL'utente digiti:");
  149.                                                 printf("\n  1-Se si vuole procedere nell'inserimento di un nuovo vino");
  150.                                                 printf("\n  2-Se si vuole procedere nella cancellazione di un altro");
  151.                                                 printf("\n  3-Se si vuole visualizzare la lista con i vini inseriti");
  152.                                                 printf("\n  4-Se si vuole uscire dal programma");
  153.                                                 printf("\nPremere Invio per confermare.\n");
  154.                                                 printf("\n");
  155.  
  156.                                                 /* pulizia del buffer della scanf */
  157.                                                 esito_pulizia = scanf("\n");
  158.                                                 esito = scanf("%d",
  159.                                                               &scelta_utente);
  160.  
  161.                                                 while (getchar() != '\n');
  162.                                         }
  163.                                         while ((scelta_utente < 1) || (scelta_utente > 4) || (esito != 1) || (esito_pulizia != 0));    
  164.  
  165.                                         switch (scelta_utente)
  166.                                         {
  167.                                                 case 1:
  168.                                                         esito = inserisci_nuovo_vino(&radice_p);
  169.                
  170.                                                         if (esito == 1)
  171.                                                                 /* incrementa il numero di vini */
  172.                                                                 numero_vini++;
  173.                                                        
  174.                                                         printf("  (premere Invio per tornare al menù)\n");
  175.                                                         while (getchar() != '\n');
  176.                                                 break;
  177.        
  178.                                                 case 2:
  179.                                                         rimosso = rimuovi_vino(&radice_p);
  180.  
  181.                                                         /* se la rimozione è andata a buon fine */
  182.                                                         if (rimosso == 1)
  183.                                                                 /* decremento il numero di vini */
  184.                                                                 numero_vini--;
  185.  
  186.                                                         printf("  (premere Invio per tornare al menù)\n");
  187.                                                         while (getchar() != '\n');
  188.                                                 break;
  189.                        
  190.                                                 case 3:
  191.                                                         do
  192.                                                         {
  193.                                                                 printf("\nL'utente scelga l'ordine di visualizzaione dei vini:");
  194.                                                                 printf("\n  1-Nome");
  195.                                                                 printf("\n  2-Codice");
  196.                                                                 printf("\n  3-Luogo di produzione");
  197.                                                                 printf("\n  4-Anno di produzione");
  198.                                                                 printf("\nPremere Invio per confermare.\n");
  199.                                                                 printf("\n");
  200.  
  201.                                                                 /* pulizia del buffer della scanf */
  202.                                                                 esito_pulizia_ordinamento = scanf("\n");
  203.                                                                 esito_ordinamento = scanf("%d",
  204.                                                                                           &scelta_ordinamento);
  205.  
  206.                                                                 while (getchar() != '\n');
  207.                                                         }
  208.                                                         while ((scelta_utente < 1) || (scelta_utente > 4) ||
  209.                                                                (esito_ordinamento != 1) || (esito_pulizia_ordinamento != 0));
  210.  
  211.                                                         /* visualizzare la lista dei vini inseriti */
  212.                                                         printf("\n%d vini inseriti:\n",
  213.                                                                 numero_vini);
  214.  
  215.                                                         if (scelta_ordinamento == 2)
  216.                                                                 /* stampa i vini in base al codice */
  217.                                                                 stampa_codice(radice_p);
  218.                                                         else
  219.                                                                 stampa_vini(radice_p,
  220.                                                                             numero_vini,
  221.                                                                             scelta_ordinamento);
  222.                                                         printf("\n");
  223.                                                         printf("(premere Invio per tornare al menù)\n");
  224.  
  225.                                                         while (getchar() != '\n');
  226.                                                 break;
  227.                                                
  228.                                                 case 4:
  229.                                                         /* se l'utente decide di uscire stampiamo un messaggio di saluto */
  230.                                                         printf("\nGrazie per aver utilizzato questo programma!");
  231.                                                         printf("\n\n");
  232.                                                 break;
  233.                                         }                              
  234.                                 }
  235.                                 while ((scelta_utente != 4));
  236.                         }
  237.                 }
  238.                 else/* se il file specificato è uguale a NULL e quindi inesistente */
  239.                         printf("\nIl file specificato non esiste!\n");
  240.         }
  241.         else
  242.         {
  243.                 /* se non è stato inserito il parametro di lancio del file */
  244.                 printf("\nNon è stato immesso il nome del file da dove importare i dati riguardanti i vini!");
  245.                 printf("\nrilanciare il programma con queste specifiche:");
  246.                 printf("\n./<nome_eseguibile> <nome_file_input>\n");
  247.                 printf("\nIl file può essere generato tramite il programma che viene lanciato con ./genera");
  248.                 printf("\n(per la compilazione il comando è make genera_vini!)\n");
  249.                 printf("\n(se il file è nella dir. di lavoro basta specificarne il nome!)\n\n");
  250.         }
  251.         return(0);
  252. }
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262. int controllo_correttezza_file(nodo_albero_bin_t **radice_p,
  263.                                FILE * input,
  264.                                int *numero_vini)
  265. {
  266.         int     esito,
  267.                 controllo_errori = 0,
  268.                 i, j;
  269.  
  270.         char    nome_vino[LUNGHEZZA_NOME],                     
  271.                 codice_vino[LUNGHEZZA_CODICE],                 
  272.                 anno_vino[LUNGHEZZA_ANNO_PRODUZIONE],          
  273.                 luogo_vino[LUNGHEZZA_LUOGO_PRODUZIONE],        
  274.                 carattere_acquisito = '~';              /* lavoro: variabile utilizzata */
  275.                                                         /* per acquisizioni e controlli */
  276.    
  277.         /* il ciclo acquisce i vini uno ad uno dal file e li inserisce nella struttura dati */
  278.         for (i = 0; ((i < *numero_vini) && (controllo_errori == 0)); i++)
  279.         {
  280.                 /* scorro il file fino a trovare il carattere successivo */
  281.                 while (carattere_acquisito != '\n')
  282.                         carattere_acquisito = getc(input);
  283.  
  284.                 /* acquisizione del nome del vino */
  285.                 for (j = 0, carattere_acquisito = '~';
  286.                      ((j < (LUNGHEZZA_NOME - 1)) && (carattere_acquisito != ' ')
  287.                       && (carattere_acquisito != '\n') && (controllo_errori == 0));
  288.                      j++)
  289.                 {
  290.  
  291.                         carattere_acquisito = getc(input);
  292.  
  293.                         if ((carattere_acquisito != ' ') && (carattere_acquisito != '\n'))
  294.                                 nome_vino[j] = carattere_acquisito;
  295.                         else
  296.                                 j--;
  297.                 }
  298.                 nome_vino[j] = '\0';
  299.  
  300.                 /* se il nome del vino ha più caratteri del previsto */
  301.                 if (carattere_acquisito != ' ')
  302.                         printf("I nomi che superano i %d caratteri sono stati abbreviati!\n",
  303.                                 (LUNGHEZZA_NOME - 1));
  304.  
  305.                 /* spostati in avanti nel file in avanti fino ad arrivare all'inizio del codice */
  306.                 while (carattere_acquisito != ' ')
  307.                         carattere_acquisito = getc(input);
  308.  
  309.                 /* acquisizione del codice del vino */
  310.                 for (j = 0;
  311.                      ((j < (LUNGHEZZA_CODICE - 1)) && (controllo_errori == 0));
  312.                      j++)
  313.                 {
  314.                         codice_vino[j] = getc(input);
  315.  
  316.                         /* se il codice vino ha meno caratteri del previsto */
  317.                         if (codice_vino[j] == ' ')
  318.                         {
  319.                                 printf("I codici dei vini devono contenere %d caratteri!\n",
  320.                                         (LUNGHEZZA_CODICE - 1));
  321.  
  322.                                 controllo_errori = 1;
  323.                         }
  324.  
  325.                         /* se il codice contiene caratteri non alfanumerici */
  326.                         else if (codice_vino[j] < '0' || (codice_vino[j] > '9' && codice_vino[j] < 'A') ||
  327.                                  (codice_vino[j] > 'Z' && codice_vino[j] < 'a') || codice_vino[j] > 'z')
  328.                         {
  329.                                 printf("I codici dei vini possono contenere solo caratteri alfanumerici!\n");
  330.              
  331.                                 /* forza la chiusura del programma */
  332.                                 controllo_errori = 1;
  333.                         }
  334.                 }
  335.                 codice_vino[j] = '\0';
  336.  
  337.                 carattere_acquisito = getc(input);
  338.  
  339.                 /* spostati in avanti nel file fino ad arrivare all'inizio dell'anno di produzione */
  340.                 while (carattere_acquisito != ' ')
  341.                         carattere_acquisito = getc(input);
  342.  
  343.                 /* acquisizione dell'anno di produzione */
  344.                 for (j = 0, carattere_acquisito = '~';
  345.                      ((j < (LUNGHEZZA_ANNO_PRODUZIONE - 1)) && (controllo_errori == 0));
  346.                      j++)
  347.                 {
  348.                         anno_vino[j] = getc(input);
  349.  
  350.                         /* se l'anno del vino ha meno caratteri del previsto */
  351.                         if (anno_vino[j] == ' ')
  352.                         {
  353.                                 printf("L'anno di produzione dei vini devono contenere %d caratteri!\n",
  354.                                         (LUNGHEZZA_ANNO_PRODUZIONE - 1));
  355.  
  356.                                 controllo_errori = 1;
  357.                         }
  358.  
  359.                         /* se l'anno contiene caratteri non numerici */
  360.                         else if (anno_vino[j] < '0' || anno_vino[j] > '9' )
  361.                         {
  362.                                 printf("Gli anni dei vini possono contenere solo caratteri numerici!\n");
  363.              
  364.                                 /* forza la chiusura del programma */
  365.                                 controllo_errori = 1;
  366.                         }
  367.                 }
  368.                 anno_vino[j] = '\0';
  369.  
  370.                 carattere_acquisito = getc(input);
  371.  
  372.                 /* spostati in avanti nel file in avanti fino ad arrivare all'inizio del luogo di produzione */
  373.                 while (carattere_acquisito != ' ')
  374.                         carattere_acquisito = getc(input);
  375.              
  376.                 /* acquisizione del luogo di produzione del vino */
  377.                 for (j = 0, carattere_acquisito = '~';
  378.                      ((j < (LUNGHEZZA_LUOGO_PRODUZIONE - 1)) && (carattere_acquisito != ' ')
  379.                       && (carattere_acquisito != '\n') && (controllo_errori == 0));
  380.                      j++)
  381.                 {
  382.  
  383.                         carattere_acquisito = getc(input);
  384.  
  385.                         if ((carattere_acquisito != ' ') && (carattere_acquisito != '\n'))
  386.                                 luogo_vino[j] = carattere_acquisito;
  387.                         else
  388.                                 j--;
  389.                 }
  390.                 luogo_vino[j] = '\0';
  391.  
  392.                 /* se il luogo di produzione del vino ha più caratteri del previsto */
  393.                 if ((carattere_acquisito != '\n') && (controllo_errori == 0))
  394.                         printf("I luoghi che superano i %d caratteri sono stati abbreviati!\n",
  395.                                 (LUNGHEZZA_LUOGO_PRODUZIONE - 1));
  396.                
  397.                 /* inserimento del vino nell'albero ordinato secondo il codice */
  398.                 esito = inserisci_in_albero_bin(&radice_p,
  399.                                                 codice_vino,
  400.                                                 nome_vino,
  401.                                                 anno_vino,
  402.                                                 luogo_vino);
  403.  
  404.                 /* se l'inserimento non è andato a buon fine */
  405.                 if (esito == 0)
  406.                 {
  407.                         printf("\nIl vino con codice \"%s\" non è stato inserito perchè già presente nella lista!\n",
  408.                                 codice_vino);
  409.  
  410.                         /* decrementa il numero dei vini del numero di inserimenti falliti */
  411.                         *numero_vini = *numero_vini - 1;
  412.                 }
  413.         }
  414.         return (controllo_errori);
  415. }
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434. /* Algoritmo per l'inserimento di un vino nell'albero binario ordinato secondo il codice */
  435.  
  436. int inserisci_in_albero_bin(nodo_albero_bin_t ***radice_p,      /* lavoro: puntatore al puntatore alla radice dell'albero */
  437.                             char codice_vino[],                 /* input: codice del vino da inserire                     */
  438.                             char nome_vino[],                   /* input: nome del vino da inserire                       */
  439.                             char anno_vino[],                   /* input: anno di produzione del vino da inserire         */
  440.                             char luogo_vino[])                  /* input: luogo di produzione del vino da inserire        */
  441.                                                                                                        
  442. {
  443.         int     inserito,       /* output: esito dell'inserimento */
  444.                 i;              /* lavoro: indice per i cicli for */
  445.  
  446.         nodo_albero_bin_t *nodo_p,      /* lavoro: puntatore ad un nodo                         */
  447.                           *padre_p,     /* lavoro: puntatore al padre del  nodo_p               */
  448.                           *nuovo_p;     /* lavoro: puntatore al nodo che conterrà il nuovo vino */
  449.  
  450.         /* nodo_p e padre_p vengono inizializzati con l'indirizzo della radice e ad ogni */
  451.         /* iterazione padre_p prende l'indirizzo di nodo_p.nodo_p prende l'indirizzo del */
  452.         /* suo figlio sx o dx a seconda che il codice da inserire sia < o >= al codice   */
  453.         /* puntato da nodo_p.Il ciclo termina quando nodo_p punta a NULL oppure ad un    */
  454.         /* elemento che contiene un codice uguale a quello da inserire.                  */
  455.         for (nodo_p = padre_p = **radice_p;
  456.              ((nodo_p != NULL) && (strcmp(nodo_p->codice_vino, codice_vino) != 0));
  457.              padre_p = nodo_p, nodo_p = (strcmp(codice_vino, nodo_p->codice_vino) < 0)?
  458.                                          nodo_p->sx_p:
  459.                                          nodo_p->dx_p);
  460.  
  461.         /* il vino non verrà inserito se era già presente, ovvero se nodo_p non punta a NULL */
  462.         if (nodo_p != NULL)
  463.                 inserito = 0;
  464.         else
  465.         {
  466.                 inserito = 1;
  467.  
  468.                 /* viene allocata memoria per il nuovo nodo */
  469.                 nuovo_p = (nodo_albero_bin_t *)malloc(sizeof(nodo_albero_bin_t));
  470.      
  471.                 /* inserimento del codice del vino */
  472.                 for (i = 0; (i < LUNGHEZZA_CODICE); i++)
  473.                         nuovo_p->codice_vino[i] = codice_vino[i];
  474.  
  475.                 /* inserimento del nome del vino */
  476.                 for (i = 0; (i < LUNGHEZZA_NOME); i++)
  477.                         nuovo_p->nome_vino[i] = nome_vino[i];
  478.  
  479.                 /* inserimento dell'anno di produzione del vino */
  480.                 for (i = 0; (i < LUNGHEZZA_ANNO_PRODUZIONE); i++)
  481.                         nuovo_p->anno_vino[i] = anno_vino[i];
  482.  
  483.                 /* inserimento del luogo di produzione del vino */
  484.                 for (i = 0; (i < LUNGHEZZA_LUOGO_PRODUZIONE); i++)
  485.                         nuovo_p->luogo_vino[i] = luogo_vino[i];
  486.    
  487.                 /* i puntatori vengono inizializzati a NULL */                                    
  488.                 nuovo_p->sx_p = nuovo_p->dx_p = NULL;                                        
  489.  
  490.                 /* se il nodo si trova in cima all'albero diventa la radice */
  491.                 if (nodo_p == **radice_p)      
  492.                         **radice_p = nuovo_p;  
  493.  
  494.                 /* se il codice inserito è inferiore a quello contenuto nel nodo padre */
  495.                  else if (strcmp(codice_vino, padre_p->codice_vino) < 0)
  496.  
  497.                         /* il nuovo nodo diventa figlio sinistro */
  498.                         padre_p->sx_p = nuovo_p;                              
  499.                  else
  500.  
  501.                         /* il nuovo nodo diventa figlio destro */
  502.                         padre_p->dx_p = nuovo_p;                              
  503.         }
  504.  
  505.         /* viene restituito il valore di esito dell'inserimento */
  506.         return(inserito);
  507. }
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517. /* Funzione per l'inserimento di un nuovo vino */
  518.  
  519. int inserisci_nuovo_vino(nodo_albero_bin_t **radice_p) /* lavoro: puntatore alla radice dell'albero */
  520. {
  521.         char    nome_vino[LUNGHEZZA_NOME],                      /* input: nome del vino da inserire                     */
  522.                 codice_vino[LUNGHEZZA_CODICE],                  /* input: codice del vino da inserire                   */
  523.                 anno_vino[LUNGHEZZA_ANNO_PRODUZIONE],           /* input: anno di produzione del vino da inserire       */
  524.                 luogo_vino[LUNGHEZZA_LUOGO_PRODUZIONE],         /* input: luogo di produzione del vino da inserire      */
  525.                 carattere_acquisito = '~';                      /* lavoro: variabile usata per acquisizioni e controlli */
  526.  
  527.         int     inserito = 0,                                   /* output: esito dell'inserimento       */
  528.                 controllo_errori,                               /* lavoro: variabile di controllo       */
  529.                 i;                                              /* lavoro: indice per i cicli for       */
  530.  
  531.  
  532.  
  533.         /* acquisizione del codice del vino da inserire */
  534.         printf("\nScrivere il codice del vino da inserire: ");
  535.  
  536.         /* non esce dal ciclo se il codice inserito da tastiera è troppo corto */
  537.         do
  538.         {
  539.                 controllo_errori = 0;
  540.                 carattere_acquisito = '~';
  541.  
  542.                 for (i = 0;
  543.                      ((i < (LUNGHEZZA_CODICE - 1)) && (carattere_acquisito != '\n')
  544.                       && (carattere_acquisito != ' ') && (controllo_errori == 0));
  545.                      i++)
  546.                 {
  547.                         carattere_acquisito = getchar();
  548.                         if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  549.                                 codice_vino[i] = carattere_acquisito;
  550.                         else
  551.                         {
  552.                                 i--;
  553.                                 printf("\nIl codice deve contenere %d caratteri alfanumerici!\n",
  554.                                         (LUNGHEZZA_CODICE - 1));
  555.                                 printf("\nRiscrivere il codice del vino: ");
  556.                         }
  557.  
  558.                         /* se il codice contiene caratteri non alfanumerici */
  559.                         if (codice_vino[i] < '0' || (codice_vino[i] > '9' && codice_vino[i] < 'A') ||
  560.                             (codice_vino[i] > 'Z' && codice_vino[i] < 'a') || codice_vino[i] > 'z')
  561.                         {
  562.                                 controllo_errori = 1;
  563.                                 printf("\nRiscrivere il codice del vino: ");
  564.                         }
  565.                 }
  566.                 codice_vino[i] = '\0';
  567.         }
  568.         while ((strlen(codice_vino) != (LUNGHEZZA_CODICE - 1)) || (controllo_errori == 1));
  569.  
  570.         carattere_acquisito = getchar();  
  571.  
  572.         /* se l'utente ha inserito un codice troppo lungo */
  573.         if (carattere_acquisito != '\n')
  574.  
  575.                 /* ripulisci il file stdin */
  576.                 while (carattere_acquisito != '\n')
  577.                         carattere_acquisito = getchar();
  578.  
  579.         /* acquisizione del nome del vino da inserire               */
  580.         /* non esce dal ciclo se l'utente non inserisce nessun nome */
  581.         do
  582.         {
  583.                 printf("Scrivere il nome del vino da inserire: ");
  584.  
  585.                 carattere_acquisito = '~';
  586.    
  587.                 for (i = 0;
  588.                      ((i < (LUNGHEZZA_NOME - 1)) && (carattere_acquisito != '\n') && (carattere_acquisito != ' '));
  589.                      i++)
  590.                 {
  591.                         carattere_acquisito = getchar();
  592.                         if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  593.                                 nome_vino[i] = carattere_acquisito;
  594.                         else
  595.                                 i--;
  596.                 }
  597.                 nome_vino[i] = '\0';
  598.      
  599.                 /* se l'utente ha inserito un nome troppo lungo */
  600.                 if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  601.                 {
  602.                         printf("\nIl nome è stato abbreviato a %d caratteri!\n\n",
  603.                                 (LUNGHEZZA_NOME - 1));
  604.  
  605.                         /* ripulisci il file stdin */
  606.                         while (carattere_acquisito != '\n')
  607.                                 carattere_acquisito = getchar();
  608.                 }
  609.         }
  610.         while (strlen(nome_vino) == 0);
  611.  
  612.  
  613.         /* acquisizione dell'anno di produzione del vino da inserire */
  614.         printf("Scrivere l'anno di produzione del vino da inserire: ");
  615.    
  616.         /* non esce dal ciclo se l'anno inserito da tastiera è troppo corto */
  617.         do
  618.         {
  619.                 controllo_errori = 0;
  620.                 carattere_acquisito = '~';
  621.  
  622.                 for (i = 0;
  623.                      ((i < (LUNGHEZZA_ANNO_PRODUZIONE - 1)) && (carattere_acquisito != '\n')
  624.                       && (carattere_acquisito != ' ') && (controllo_errori == 0));
  625.                      i++)
  626.                 {
  627.                         carattere_acquisito = getchar();
  628.                         if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  629.                                 anno_vino[i] = carattere_acquisito;
  630.                         else
  631.                         {
  632.                                 i--;
  633.                                 printf("\nL'anno deve contenere %d caratteri numerici!\n",
  634.                                         (LUNGHEZZA_ANNO_PRODUZIONE - 1));
  635.                                 printf("\nRiscrivere l'anno di produzione del vino: ");
  636.                         }
  637.  
  638.                         /* se l'anno contiene caratteri non numerici */
  639.                         if (anno_vino[i] < '0' || anno_vino[i] > '9')
  640.                                 controllo_errori = 1;
  641.                 }
  642.                 anno_vino[i] = '\0';
  643.         }
  644.         while ((strlen(anno_vino) != (LUNGHEZZA_ANNO_PRODUZIONE - 1)) || (controllo_errori == 1));
  645.  
  646.         carattere_acquisito = getchar();  
  647.  
  648.         /* se l'utente ha inserito un anno troppo lungo */
  649.         if (carattere_acquisito != '\n')
  650.  
  651.                 /* ripulisci il file stdin */
  652.                 while (carattere_acquisito != '\n')
  653.                         carattere_acquisito = getchar();
  654.  
  655.         /* acquisizione del luogo di produzione del vino da inserire */
  656.         /* non esce dal ciclo se l'utente non inserisce nessun luogo */
  657.         do
  658.         {
  659.                 printf("Scrivere il luogo di produzione del vino da inserire: ");
  660.  
  661.                 carattere_acquisito = '~';
  662.    
  663.                 for (i = 0;
  664.                      ((i < (LUNGHEZZA_LUOGO_PRODUZIONE - 1)) && (carattere_acquisito != '\n') && (carattere_acquisito != ' '));
  665.                      i++)
  666.                 {
  667.                         carattere_acquisito = getchar();
  668.                         if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  669.                                 luogo_vino[i] = carattere_acquisito;
  670.                         else
  671.                                 i--;
  672.                 }
  673.                 luogo_vino[i] = '\0';
  674.      
  675.                 /* se l'utente ha inserito un luogo troppo lungo */
  676.                 if (carattere_acquisito != '\n')
  677.                 {
  678.                         printf("\nIl luogo è stato abbreviato a %d caratteri!\n\n",
  679.                                 (LUNGHEZZA_LUOGO_PRODUZIONE - 1));
  680.  
  681.                         /* ripulisci il file stdin */
  682.                         while (carattere_acquisito != '\n')
  683.                                 carattere_acquisito = getchar();
  684.                 }
  685.         }
  686.         while (strlen(luogo_vino) == 0);
  687.  
  688.         /* inserimento del vino nell'albero */
  689.         inserito = inserisci_in_albero_bin(&radice_p,
  690.                                            codice_vino,
  691.                                            nome_vino,
  692.                                            anno_vino,
  693.                                            luogo_vino);
  694.  
  695.         /* se l'inserimento è andato a buon fine */
  696.         if (inserito != 1)
  697.                 printf("\nVino \"%s\" già presente!", codice_vino);
  698.         else
  699.                 printf("\nIl vino è stato inserito.");
  700.        
  701.         /* viene restituito l'esito dell'inserimento */
  702.         return (inserito);
  703. }
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713. int rimuovi_vino(nodo_albero_bin_t **radice_p)  /* lavoro: puntatore alla radice dell'albero */
  714. {
  715.  
  716.         char    codice_vino[LUNGHEZZA_CODICE]/* input: codice del vino da rimuovere                  */
  717.                 carattere_acquisito = '~';      /* lavoro: variabile usata per acquisizioni e controlli */
  718.  
  719.         int     rimosso = 0,      /* output: esito rimozione            */
  720.                 controllo_errori, /* lavoro: variabile di controllo     */
  721.                 i;                /* lavoro: indice per i cicli         */
  722.  
  723.  
  724.         /* acquisizione del codice del vino da rimuovere */
  725.         printf("\nScrivere il codice del vino da rimuovere: ");
  726.    
  727.         /* non esce dal ciclo se l'utente non inserisce un codice corretto */
  728.         do
  729.         {
  730.                 controllo_errori = 0;
  731.                 carattere_acquisito = '~';
  732.  
  733.                 for (i = 0;
  734.                      ((i < (LUNGHEZZA_CODICE - 1)) && (carattere_acquisito != '\n')
  735.                       && (carattere_acquisito != ' ') && (controllo_errori == 0));
  736.                      i++)
  737.                 {
  738.                         carattere_acquisito = getchar();
  739.                         if ((carattere_acquisito != '\n') && (carattere_acquisito != ' '))
  740.                                 codice_vino[i] = carattere_acquisito;
  741.                         else
  742.                         {
  743.                                 i--;
  744.                                 printf("\nIl codice deve contenere %d caratteri alfanumerici!\n",
  745.                                         (LUNGHEZZA_CODICE - 1));
  746.                                 printf("\nRiscrivere il codice del vino: ");
  747.                         }
  748.  
  749.                         /* se il codice contiene caratteri non alfanumerici */
  750.                         if (codice_vino[i] < '0' || (codice_vino[i] > '9' && codice_vino[i] < 'A') ||
  751.                             (codice_vino[i] > 'Z' && codice_vino[i] < 'a') || codice_vino[i] > 'z')
  752.                         {
  753.                                 controllo_errori = 1;
  754.                                 printf("\nRiscrivere il codice del vino: ");
  755.                         }
  756.                 }
  757.                 codice_vino[i] = '\0';
  758.         }
  759.         while ((strlen(codice_vino) != (LUNGHEZZA_CODICE - 1)) || (controllo_errori == 1));
  760.  
  761.         carattere_acquisito = getchar();  
  762.  
  763.         /* se l'utente ha inserito un codice troppo lungo */
  764.         if (carattere_acquisito != '\n')
  765.  
  766.                 /* ripulisci il file stdin */
  767.                 while (carattere_acquisito != '\n')
  768.                         carattere_acquisito = getchar();
  769.  
  770.         /* rimozione del vino dall'albero */
  771.         rimosso = rimuovi_da_albero_bin(&radice_p,
  772.                                         codice_vino);
  773.         if (rimosso == 1)
  774.                 printf("\nIl vino è stato rimosso!");
  775.         else
  776.                 printf("\nIl vino non è presente nella lista!");
  777.  
  778.         /* viene restituito l'esito della rimozione */
  779.         return (rimosso);
  780. }
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790. /* Algoritmo per la rimozione di un vino dall'albero binario */
  791.  
  792. int rimuovi_da_albero_bin(nodo_albero_bin_t ***radice_p,        /* lavoro: puntatore al puntatore alla radice dell'albero */
  793.                           char codice_vino[])           /* input: codice del vino da rimuovere                    */
  794. {
  795.         int     rimosso, /* output: esito della rimozione     */
  796.                 i;       /* lavoro: contatore per i cicli for */
  797.  
  798.         nodo_albero_bin_t *nodo_p,  /* lavoro: puntatore a un nodo */
  799.                           *padre_p, /* lavoro: padre di nodo_p     */
  800.                           *sost_p;  /* lavoro: sostituto di nodo_p */
  801.  
  802.         /* nodo_p e padre_p vengono inizializzati con l'indirizzo della radice e ad ogni */
  803.         /* iterazione padre_p prende l'indirizzo di nodo_p.nodo_p prende l'indirizzo del */
  804.         /* suo figlio sx o dx a seconda che il codice da inserire sia < o >= al codice   */
  805.         /* puntato da nodo_p.Il ciclo termina quando nodo_p punta a NULL oppure ad un    */
  806.         /* elemento che contiene un codice uguale a quello da rimuovere.                 */
  807.         for (nodo_p = padre_p = **radice_p;
  808.              ((nodo_p != NULL) && (strcmp(nodo_p->codice_vino,codice_vino) != 0));
  809.              padre_p = nodo_p, nodo_p = (strcmp(codice_vino,nodo_p->codice_vino) < 0)?
  810.                                          nodo_p->sx_p:
  811.                                          nodo_p->dx_p);
  812.  
  813.         /* il vino non verrà rimosso se non era presente, ovvero se nodo_p punta a NULL */
  814.         if (nodo_p == NULL)
  815.                 rimosso = 0;
  816.         else
  817.         {
  818.                 rimosso = 1;
  819.  
  820.                 /* se nodo_p non ha figlio sx */
  821.                 if (nodo_p->sx_p == NULL)
  822.                 {
  823.                         /* se nodo_p si trova in cima all'albero */
  824.                         if (nodo_p == **radice_p)
  825.  
  826.                                 /* il figlio destro del nodo diventa la radice */
  827.                                 **radice_p = nodo_p->dx_p;
  828.  
  829.                         /* altrimenti se il codice da rimuovere è minore di quello del padre */
  830.                         else if (strcmp(codice_vino, padre_p->codice_vino) < 0)
  831.  
  832.                                 /* il figlio destro del nodo_p, diventa figlio sinistro del padre */
  833.                                 padre_p->sx_p = nodo_p->dx_p;
  834.  
  835.                         else
  836.  
  837.                                 /* il figlio destro del nodo_p, diventa figlio destro del padre */
  838.                                 padre_p->dx_p = nodo_p->dx_p;
  839.                 }
  840.  
  841.                 /* altrimenti, se nodo_p non ha figlio destro */
  842.                 else if (nodo_p->dx_p == NULL)
  843.                 {  
  844.                         /* se nodo_p si trova in cima all'albero */
  845.                         if (nodo_p == **radice_p)
  846.  
  847.                                 /* il figlio sinistro del nodo diventa la radice */
  848.                                 **radice_p = nodo_p->sx_p;
  849.  
  850.                         /* altrimenti, se il codice da rimuovere è minore di quello del padre */
  851.                         else if (strcmp(codice_vino, padre_p->codice_vino) < 0)
  852.  
  853.                                 /* il figlio sinistro del nodo_p diventa figlio sinistro del padre */
  854.                                 padre_p->sx_p = nodo_p->sx_p;
  855.  
  856.                         else
  857.  
  858.                                 /* il figlio sinistro del nodo_p diventa figlio destro del padre */
  859.                                 padre_p->dx_p = nodo_p->sx_p;
  860.                 }
  861.    
  862.                 /* altrimenti, se il nodo_p ha entrambi i figli */
  863.                 else
  864.                 {
  865.                         /* sost_p prende l'indirizzo contenuto in nodo_p */
  866.                         sost_p = nodo_p;  
  867.  
  868.                         /* ad ogni iterazione del ciclo, padre_p prende l'indirizzo di nodo_p e nodo_p prende */
  869.                         /* l'indirizzo del figlio destro; il ciclo termina quando nodo_p non ha figlio destro */
  870.                         for (padre_p = sost_p, nodo_p = sost_p->sx_p;
  871.                              (nodo_p->dx_p != NULL);
  872.                              padre_p = nodo_p, nodo_p = nodo_p->dx_p);
  873.  
  874.                         /* sostuzione del codice del nodo sost_p con quello del nodo_p */      
  875.                         for (i = 0; (i < LUNGHEZZA_CODICE); i++)
  876.                                 sost_p->codice_vino[i] = nodo_p->codice_vino[i];
  877.  
  878.                         /* sostituzione del nome del nodo sost_p con quello del nodo_p */
  879.                         for (i = 0; (i < LUNGHEZZA_NOME); i++)
  880.                                 sost_p->nome_vino[i] = nodo_p->nome_vino[i];  
  881.  
  882.                         /* sostuzione dell'anno del nodo sost_p con quello del nodo_p */      
  883.                         for (i = 0; (i < LUNGHEZZA_ANNO_PRODUZIONE); i++)
  884.                                 sost_p->anno_vino[i] = nodo_p->anno_vino[i];
  885.  
  886.                         /* sostituzione del luogo del nodo sost_p con quello del nodo_p */
  887.                         for (i = 0; (i < LUNGHEZZA_LUOGO_PRODUZIONE); i++)
  888.                                 sost_p->anno_vino[i] = nodo_p->anno_vino[i];  
  889.        
  890.                         /* se padre_p e sost_p puntano allo stesso nodo */    
  891.                         if (padre_p == sost_p)
  892.  
  893.                                 /* il figlio sinistro del nodo_p diventa figlio sinistro del padre_p */
  894.                                 padre_p->sx_p = nodo_p->sx_p;
  895.  
  896.                         else
  897.  
  898.                                 /* il figlio sinistro del nodo_p diventa figlio destro del padre_p */
  899.                                 padre_p->dx_p = nodo_p->sx_p;
  900.                 }
  901.  
  902.                 /* il nodo puntato da nodo_p viene rimosso dalla memoria */
  903.                 free(nodo_p);
  904.         }  
  905.         return(rimosso);
  906. }
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916. /* funzione per la stampa dei vini in base al codice */
  917. void stampa_codice(nodo_albero_bin_t *nodo_p)
  918. {
  919.         if (nodo_p != NULL)
  920.         {
  921.                 stampa_codice(nodo_p->sx_p);
  922.  
  923.                 printf("%s %s %s %s\n",
  924.                         nodo_p->nome_vino,
  925.                         nodo_p->codice_vino,
  926.                         nodo_p->anno_vino,
  927.                         nodo_p->luogo_vino);
  928.  
  929.                 stampa_codice(nodo_p->dx_p);
  930.         }
  931. }
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941. void stampa_vini(nodo_albero_bin_t *radice_p,
  942.                  int numero_vini,
  943.                  int scelta_ordinamento)
  944. {
  945.  
  946.         vino_t  vini[numero_vini];      /* array per l'ordinamento */
  947.  
  948.         /* trasferimento dei vini dall'albero in un array */
  949.         inserisci_vini_in_array(radice_p,
  950.                                 vini,
  951.                                 0);
  952.  
  953.         switch(scelta_ordinamento)
  954.         {
  955.                 case 1:
  956.                         /* ordina i vini in base al nome */
  957.                         quicksort_nome(vini,
  958.                                        0,
  959.                                        numero_vini - 1);
  960.                 break;
  961.        
  962.                 case 3:
  963.                         /* ordina i vini in base all'anno */
  964.                         quicksort_anno(vini,
  965.                                        0,
  966.                                        numero_vini - 1);
  967.                 break;
  968.  
  969.                 case 4:
  970.                         /* ordina i vini in base al luogo */
  971.                         quicksort_luogo(vini,
  972.                                         0,
  973.                                         numero_vini - 1);
  974.                 break;
  975.         }
  976.         stampa_array(numero_vini,
  977.                      vini);
  978. }
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988. /* funzione per il trasferimento dei vini dall'albero in un array */
  989. void inserisci_vini_in_array(nodo_albero_bin_t *nodo_p,
  990.                              vino_t *vini,
  991.                              int i)
  992. {
  993.         if (nodo_p->codice_vino != NULL)
  994.         {
  995.                 inserisci_vini_in_array(nodo_p->sx_p,
  996.                                         vini,
  997.                                         i);
  998.  
  999.                 strcpy(vini[i].nome_vino, nodo_p->nome_vino);
  1000.                 strcpy(vini[i].codice_vino, nodo_p->codice_vino);
  1001.                 strcpy(vini[i].anno_vino, nodo_p->anno_vino);
  1002.                 strcpy(vini[i].luogo_vino, nodo_p->luogo_vino);
  1003.  
  1004.                 i = i + 1;
  1005.  
  1006.                 inserisci_vini_in_array(nodo_p->dx_p,
  1007.                                         vini,
  1008.                                         i);
  1009.         }
  1010. }
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020. void quicksort_nome(vino_t a[],
  1021.                     int sx,
  1022.                     int dx)
  1023. {
  1024.         int         i, j;       /* variabili di lavoro */
  1025.                    
  1026.         vino_t      tmp,        /* variabile usata per lo scambio */
  1027.                     pivot;      /* puntatore all'elemento che fungera' da pivot */
  1028.  
  1029.         /* si sceglie come pivot il valore centrale e si attua una tri-partizione       */
  1030.         /* scambiando gli elementi in modo che nella porzione a destra del pivot vi     */
  1031.         /* siano elementi maggiori del pivot e nella porzione sinistra quelli minori    */
  1032.         for (pivot = a[(sx + dx) / 2], i = sx, j = dx; (i <= j);)
  1033.         {
  1034.                 while (strcmp(a[i].nome_vino, pivot.nome_vino) == -1)
  1035.                         i++;
  1036.                 while (strcmp(a[j].nome_vino, pivot.nome_vino) == 1)
  1037.                         j--;
  1038.                        
  1039.                 if (i <= j)
  1040.                 {
  1041.                         if (i < j)
  1042.                         {
  1043.                             tmp = a[i];
  1044.                             a[i] = a[j];
  1045.                             a[j] = tmp;
  1046.                         }
  1047.                         i++;
  1048.                         j--;
  1049.                 }
  1050.         }
  1051.         /* si invoca ricorsivamente la funzione sulle porzioni sinistra e destra */
  1052.         if (sx < j)
  1053.                 quicksort_nome(a, sx, j);
  1054.         if (i < dx)
  1055.                 quicksort_nome(a, i, dx);
  1056. }
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066. void quicksort_anno(vino_t a[],
  1067.                     int sx,
  1068.                     int dx)
  1069. {
  1070.         int         i, j;       /* variabili di lavoro */
  1071.                    
  1072.         vino_t      tmp,        /* variabile usata per lo scambio */
  1073.                     pivot;      /* puntatore all'elemento che fungera' da pivot */
  1074.                    
  1075.         /* si sceglie come pivot il valore centrale e si attua una tri-partizione       */
  1076.         /* scambiando gli elementi in modo che nella porzione a destra del pivot vi     */
  1077.         /* siano elementi maggiori del pivot e nella porzione sinistra quelli minori    */
  1078.         for (pivot = a[(sx + dx) / 2], i = sx, j = dx; (i <= j);)
  1079.         {
  1080.                 while (strcmp(a[i].anno_vino, pivot.anno_vino) == -1)
  1081.                         i++;
  1082.                 while (strcmp(a[j].anno_vino, pivot.anno_vino) == 1)
  1083.                         j--;
  1084.                        
  1085.                 if (i <= j)
  1086.                 {
  1087.                         if (i < j)
  1088.                         {
  1089.                             tmp = a[i];
  1090.                             a[i] = a[j];
  1091.                             a[j] = tmp;
  1092.                         }
  1093.                         i++;
  1094.                         j--;
  1095.                 }
  1096.         }
  1097.         /* si invoca ricorsivamente la funzione sulle porzioni sinistra e destra */
  1098.         if (sx < j)
  1099.                 quicksort_anno(a, sx, j);
  1100.         if (i < dx)
  1101.                 quicksort_anno(a, i, dx);
  1102. }
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112. void quicksort_luogo(vino_t a[],
  1113.                      int sx,
  1114.                      int dx)
  1115. {
  1116.         int         i, j;       /* variabili di lavoro */
  1117.                    
  1118.         vino_t      tmp,        /* variabile usata per lo scambio */
  1119.                     pivot;      /* puntatore all'elemento che fungera' da pivot */
  1120.                    
  1121.         /* si sceglie come pivot il valore centrale e si attua una tri-partizione       */
  1122.         /* scambiando gli elementi in modo che nella porzione a destra del pivot vi     */
  1123.         /* siano elementi maggiori del pivot e nella porzione sinistra quelli minori    */
  1124.         for (pivot = a[(sx + dx) / 2], i = sx, j = dx; (i <= j);)
  1125.         {
  1126.                 while (strcmp(a[i].luogo_vino, pivot.luogo_vino) == -1)
  1127.                         i++;
  1128.                 while (strcmp(a[j].luogo_vino, pivot.luogo_vino) == 1)
  1129.                         j--;
  1130.                        
  1131.                 if (i <= j)
  1132.                 {
  1133.                         if (i < j)
  1134.                         {
  1135.                             tmp = a[i];
  1136.                             a[i] = a[j];
  1137.                             a[j] = tmp;
  1138.                         }
  1139.                         i++;
  1140.                         j--;
  1141.                 }
  1142.         }
  1143.         /*Si invoca ricorsivamente la funzione sulle porzioni sinistra e destra*/
  1144.         if (sx < j)
  1145.                 quicksort_luogo(a, sx, j);
  1146.         if (i < dx)
  1147.                 quicksort_luogo(a, i, dx);
  1148. }
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158. void stampa_array(int numero_vini,
  1159.                   vino_t *vini)
  1160. {
  1161.         int i;
  1162.  
  1163.         /*Vengono stampati gli elementi ordinati*/
  1164.         for(i = 0; i < numero_vini; i++)
  1165.        
  1166.                 printf("\n%20s %4s %4s %s",
  1167.                         vini[i].nome_vino,
  1168.                         vini[i].codice_vino,
  1169.                         vini[i].anno_vino,
  1170.                         vini[i].luogo_vino);
  1171. }


Ultima modifica effettuata da mik_91 il 27/01/2014 alle 18:39
PM Quote
Avatar
quello che non so come si chiama (Normal User)
Rookie


Messaggi: 37
Iscritto: 08/01/2013

Segnala al moderatore
Postato alle 19:08
Lunedì, 27/01/2014
Puoi allegare un esempio di file di input?

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6378
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:20
Lunedì, 27/01/2014
Mi sa che un tuo collega stava affrontando lo stesso esercizio in

http://www.iprogrammatori.it/forum-programmazione/cplusplu ...

e a parte un problema risolto, gli funzionava ...



Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
mik_91 (Normal User)
Newbie


Messaggi: 2
Iscritto: 27/01/2014

Segnala al moderatore
Postato alle 8:59
Martedì, 28/01/2014
si, è simile...lui usa una lista e io un albero, però nell'inserimento, come nella cancellazione di una nodo nell'albero non ho problemi..ne ho più tardi quando devo stampare la lista dei vini ordinata.
Di seguito riporto un esempio generico di file:

4 vini inseriti:
Nwlrbbmqbhcdarzowkkyhiddqs 23X5 9228 Frxsjybldbefsarcbynecdyggx
Xpklorellnmpapqfwkhopkmcoq 31W9 2068 Hsqmgbbuqcljjivswmdkqtbxix
Mvtrrbljptnsnfwzqfjmafadrr 08O5 0963 Uvqhffbsaqxwpqcacehchzvfrk
Mlnozjkpqpxrjxkitzyxacbhhk 60Q8 8897 Tomfgdwdwfcgpxiqvkuytdlcgd

Ultima modifica effettuata da mik_91 il 28/01/2014 alle 9:02
PM Quote
Avatar
quello che non so come si chiama (Normal User)
Rookie


Messaggi: 37
Iscritto: 08/01/2013

Segnala al moderatore
Postato alle 19:29
Martedì, 28/01/2014
Parto(male, direi :)) annunciando che non mi sono curato tanto della logica del programma, ma ho solo controllato l'aspetto tecnico.
Comunque...
Ho notato che l'errore avviene nella inserisci_vini_in_array invece che nella inserisci_in_albero_bin, è corretto?
Avviene in quanto tu controlli
Codice sorgente - presumibilmente C/C++

  1. if (nodo_p->codice_vino != NULL)


Senza curarti della validità del nodo_p che passi, cambiando la condizione in
Codice sorgente - presumibilmente C/C++

  1. if (nodo_p != NULL && nodo_p->codice_vino != NULL) //Forse e dico forse si può anche togliere il nodo_p->codice_vino != NULL) ma non essendomi curato della logica non mi pronuncio


Successivamente utilizzi un contatore, ma a mio avviso dovresti usare un puntatore ad esso, come fai tu l'incremento è "relativo" e andrai quasi certamente a sovrascrivere su una posizione dell'array, per cui la funzione modificata sarà:
Codice sorgente - presumibilmente C/C++

  1. void inserisci_vini_in_array(nodo_albero_bin_t *nodo_p,
  2.                              vino_t *vini,
  3.                              int* i)
  4. {
  5.         if (nodo_p != NULL && nodo_p->codice_vino != NULL)
  6.         {
  7.                 inserisci_vini_in_array(nodo_p->sx_p,
  8.                                         vini,
  9.                                         i);
  10.  
  11.                 strcpy(vini[*i].nome_vino, nodo_p->nome_vino);
  12.                 strcpy(vini[*i].codice_vino, nodo_p->codice_vino);
  13.                 strcpy(vini[*i].anno_vino, nodo_p->anno_vino);
  14.                 strcpy(vini[*i].luogo_vino, nodo_p->luogo_vino);
  15.  
  16.                 (*i)++;
  17.  
  18.                 inserisci_vini_in_array(nodo_p->dx_p,
  19.                                         vini,
  20.                                         i);
  21.         }
  22. }


Chiaramente, se sei d'accordo con quanto detto dovrai modificare la dichiarazione del metodo in maniera opportuna:
Codice sorgente - presumibilmente C/C++

  1. void inserisci_vini_in_array(nodo_albero_bin_t *,
  2.                              vino_t [],
  3.                              int*);


E sarà necessario modificare anche la chiamata(nella funzione stampa_vini), per esempio così:
Codice sorgente - presumibilmente C/C++

  1. int contatore = 0;
  2.         /* trasferimento dei vini dall'albero in un array */
  3.         inserisci_vini_in_array(radice_p,
  4.                                 vini,
  5.                                 &contatore);





PS: Ho notato che il file di input necessita di una riga vuota finale, altrimenti, se l'EOF arriva al termine del campo "luogo", esso viene letto in maniera errata(non gli viene aggiunto il carattere terminatore di stringa). Magari potresti dare un'occhiata anche a questo particolare

Ultima modifica effettuata da quello che non so come si chiama il 28/01/2014 alle 23:40
PM Quote