Newsgroup: it.comp.lang.c
Titolo: Sono proprio un cane

 a capire perchè la procedura Pop non funziona.
Se e' per questo non funziona neanche la push(...), Davvero un bel casino ;-)
Di problemi ne erano presenti parecchi, adesso il codice funziona
ma l'intervento ha "ucciso il pazienete" (il codice e' stato stravolto).
Spero che le correzioni siano comprensibili.
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Stack
 {
  int key;
  struct Stack *prec;
 }STACK ;
int pop(STACK **Head ) ;
// Cambiato il prototipo della funzione,
// maggiori dettagli in seguito
// -------------------------------------
// int push(STACK *Head ,int value );
STACK* push(STACK *Head, int value );
main()
{
   STACK* corrente = NULL;
   int    scelta   = 1;
   int    i        = 0;
   int    value    = 0;
   char   inStr[6] = {'\0'}; // Io sono allergico alla scanf(...), vedi dopo
// Il tuo while(...) funzionava per puro caso, infatti "scelta" non era
// inizializzata, pertanto nessuno avrebbe vietato di avere "0 == scelta"
// e addio ciclo.
// ----------------------------------------------------------------------
while (scelta)
{
   printf("\t\t\t\t -Stack-\n\n");
   printf("1 Push   2 Pop      0 Esci\n\n") ;
// L'input con la scanf(...) a me e' antipatico, e poi e'
// sempre bene avere il massimo controllo sull'input. Con
// il codice seguente possono essere introdotte nel codice
// stringhe di 5 catatteri al massimo.
// -------------------------------------------------------
   gets(inStr);
   inStr[5] = 0;  // Taglia ogni stringa piu' lunga di 5 caratteri
   scelta = atoi(inStr); // conversione della stringa in intero.
   inStr[0] = '\0';
 // scanf("%d", &scelta);
 switch(scelta)
 {
  case 1 :  /* PUSH (INSERIMENTO) */
   printf("INSERIMENTO ELEMENTI (Digita 0 per finire) \n") ;
   i = 1 ;
   while (i)
   {
     char   inStr[6] = {'\0'};
     printf("Inserisci il valore dell`elemento : ") ;
     gets(inStr);
     inStr[5] = 0;
     i = atoi(inStr);
     inStr[0] = '\0';
     // scanf("%d",&i) ;
     if(i)
       corrente = push(corrente,i) ;
   }
   break ;
  case 2 : /* POP */
   printf("- Pop - \n") ;
   value = pop(&corrente)  ;
// Perche' compilcarsi la vita??? Se qualcosa e' "not equal" allora e "!="
// -----------------------------------------------------------------------
//   if (!(value == -1) ) printf("Valore dell'elemento cancellato : %d",value);
   if(-1 != value)
       printf("Valore dell'elemento cancellato : %d\n",value);
   else
       printf("Non ci sono piu\' elementi nello stack\n");
   break ;
 } /* Fine switch */
} /* Fine while */
   return 0;
}
// Se vuoi restituire l'indirizzo del nuovo elemento tramite Head
// _DEVI_ usare un puntatore a puntatore (STACK** Head), ma visto
// che non restituisci niente, allora utilizza il valore di ritorno
// per restituire il puntatore al nuovo elemento inseriro nello stack.
// Il codice che hai scritto cambia il valore dell'indirizzo dell'ele_
// mento passato, ma solo nello stack, fuori dalla funzione e' invisibile
// Per cambiare un indirizzo all'interno di una funzione, devi passare
// l'indirizzo dell'indirizzo (STACK**).
// ----------------------------------------------------------------------
STACK* push(STACK *Head, int value)
{
   STACK *new ;
   new = malloc(sizeof(STACK)) ;
   new->key = value ;
   new->prec = Head ;
// Questo non funziona perche' cambia il valore dell'indirizzo
// contenuto nello stack, che viene perso all'uscita dell funzione.
// ----------------------------------------------------------------
//   Head = new ;
// Non e' meglio restituire cosi' il valore di ritorno?
// ----------------------------------------------------
   return new;
}
int pop(STACK **Head)
{
 STACK *tmp ;
 int value ;
// A che serve questa allocazione ???
// Gli elementi devono essere tolti
// dallo stack mica aggiunti !!!
// ----------------------------------
// tmp = (STACK*)malloc ( sizeof(STACK) ) ;
// Se esci ora non cancelli l'ultimo elemento dallo stack
// if (NULL == Head -> prec) return -1 ; /* Se lo Stack è vuoto */
// forse sarebbe stato meglio scrivere tmp = *Head !!!
// visto che con la tua istruzione perdi l'indirizzo
// dell'elemento da cancellare
// ----------------------------------------------------
// *Head = tmp ;
   tmp = *Head;
   value = tmp->key ; /* salva il valore dell'elemento da cancellare */
   *Head = tmp->prec; // si cambia il valore corrente
// Se questo e' l'ultimo elemento dello stack lo calcelli e restituisci NULL
// -------------------------------------------------------------------------
if (!tmp->prec) /* Caso in cui c'è un solo elemento nello stack */
{
   free(tmp);
   value = -1;
}
else
   free(tmp);
   return value;
}
Spero di aver interpretato bene il tuo codice e spero che i "rimaneggiamenti"
non ti abbiano dato fastidio.
Ciao Angelo.

    gets(inStr);
[ snip ]
LOL
Questa mi ha fatto proprio ridere, complimenti !!! 8)
Scherzi a parte ;), questo è un buco notevole: se io inserisco diciamo
100 caratteri, mi spieghi dove vanno a finire gli ultimi 94 ?
Se vuoi limitare l'input, il modo corretto è
	fgets(inStr, sizeof inStr, stdin);
come più volte ripetuto in questo NG.
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

 wrote:
 > Questa mi ha fatto proprio ridere, complimenti !!! 8)
   AUCH! Questo e' un errore che grida VENDETTA!!!!
   Vuol dire che mi vendichero' su di te per averlo evidenziato
   :-).
 > Scherzi a parte ;), questo č un buco notevole: se io inserisco diciamo
 > 100 caratteri, mi spieghi dove vanno a finire gli ultimi 94 ?
  A dare fastidio alle altre variabili?
 > Se vuoi limitare l'input, il modo corretto č
   Il guaio e' che lo so come si limita l'input. Inoltre sono stato
   fregato da una compilazione sotto NT. Se avessi usato gcc sotto
   Linux avrei ottenuto:
   - the `gets' function is dangerous and should not be used
   (ma mingw non deriva da gcc? O io avevo delle fette di prosciutto
   sugli occhi troppo spesse per vedere il warning?)
   Come se non bastasse, il programma che ho postato ha un altro errore.
   Infatti se nella pop() non viene controllato il valore in ingresso e
   lo stack e' vuoto; si ottiene un SIGSEGV sotto Linux e un eccezione
   sotto NT.
   La pop(...) deve essere modificata nel modo seguente
   int pop(STACK** Head)
   {
      if(NULL == *Head)
      {
          printf("Stack vuoto \n");
          return -1;
      }
      ...
      return ???;
   }
   Chiedo ancora scusa.
   Ciao e alla prossima caz... ehm! a presto.
   P.S. Che significa LOL??
   Angelo.

 egrep -A1 '^\W+LOL'
   LOL
          laughing out loud
[root@fokhouse /root]#
