[C] Alberi binari, datemi un mano a capire una piccola porzione di codice.

Messaggioda m4551 » 19/11/2014, 11:42

Codice:
Albero LeggiAlberoFD(FILE *fd) {
  Albero a;
  int res, x;
  char c;

         /* legge la parentesi ( */
  res=fscanf(fd, "%c", &c);
  if(res!=1 || c!='(') {
    ungetc(c, fd);
    return NULL;
  }

         /* legge l'intero oppure ) */
  LeggiNoSpazi(fd);
  res=fscanf(fd, "%c", &c);
  if(res!=1 || c==')')
    return NULL;

  ungetc(c, fd);
  fscanf(fd, "%d", &x);

         /* crea il nodo */
  a=malloc(sizeof(struct NodoAlbero));
  a->radice=x;
  a->sinistro=LeggiAlberoFD(fd);
  a->destro=LeggiAlberoFD(fd);


         /* legge ) */
 
  fscanf(fd, "%c", &c);

  return a;
}


Salve, i miei dubbi sono riguardo la funzione ungetc(c, fd).
Come funziona in questo caso?
Poi non capisco il secondo fscanf: come fa a memorizzare il secondo carattere senza chiamare prima la funzione ungetc(c, fd), che avanza al carattere successivo?
Grazie per l'aiuto.
m4551
Average Member
Average Member
 
Messaggio: 307 di 535
Iscritto il: 11/02/2010, 11:49

Re: [C] Alberi binari, datemi un mano a capire una piccola porzione di codice.

Messaggioda apatriarca » 21/11/2014, 11:38

I tuoi dubbi non hanno nulla a che fare con gli alberi binari, ma solo con l'uso della libreria "stdio.h". Il codice che hai postato fa comunque un pessimo uso di tale libreria (ma non è certamente colpa tua).

ungetc è una funzione che inserisce un carattere all'inizio del buffer di lettura in modo che alla successiva lettura questo carattere sarà il primo letto. Nel tuo codice viene usato per "annullare" la lettura del carattere nel caso in cui questo carattere sia diverso da quello che ci si aspetta.

fscanf(fd, "%c", &c) legge un singolo carattere dallo stream e lo scrive in c. È del tutto equivalente a c = getc(fd) . Sarebbe stato in effetti stato meglio usare getc in quanto MOLTO più efficiente, sicura..

LeggiNoSpazi non so cosa faccia esattamente, ma immagino che sia una funzione che ignora tutti gli spazi fino al primo carattere diverso da uno spazio. Sarebbe stato allora sufficiente scrivere fscanf(fd, " %c", &c) con lo spazio prima di %c per fare la stessa cosa.
apatriarca
Moderatore
Moderatore
 
Messaggio: 3612 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] Alberi binari, datemi un mano a captiire una piccola porzione di codice.

Messaggioda m4551 » 24/11/2014, 11:44

Ti ringrazio molto per la tua CHIARA e sintetica spiegazione di ungetc, adesso ho finalmente capito come si USA!
Proverò a scrivere il mio codice più efficiente con i tuoi consigli!
m4551
Average Member
Average Member
 
Messaggio: 308 di 535
Iscritto il: 11/02/2010, 11:49

Re: [C] Alberi binari, datemi un mano a capire una piccola porzione di codice.

Messaggioda m4551 » 24/11/2014, 12:30

apatriarca ha scritto:I tuoi dubbi non hanno nulla a che fare con gli alberi binari, ma solo con l'uso della libreria "stdio.h". Il codice che hai postato fa comunque un pessimo uso di tale libreria (ma non è certamente colpa tua).

ungetc è una funzione che inserisce un carattere all'inizio del buffer di lettura in modo che alla successiva lettura questo carattere sarà il primo letto. Nel tuo codice viene usato per "annullare" la lettura del carattere nel caso in cui questo carattere sia diverso da quello che ci si aspetta.

fscanf(fd, "%c", &c) legge un singolo carattere dallo stream e lo scrive in c. È del tutto equivalente a c = getc(fd) . Sarebbe stato in effetti stato meglio usare getc in quanto MOLTO più efficiente, sicura..

LeggiNoSpazi non so cosa faccia esattamente, ma immagino che sia una funzione che ignora tutti gli spazi fino al primo carattere diverso da uno spazio. Sarebbe stato allora sufficiente scrivere fscanf(fd, " %c", &c) con lo spazio prima di %c per fare la stessa cosa.


adesso che ho capito a cosa serve ungetc, credo che nel programma sia totalmente inutile.
Ho riscritto il codice in questo modo:
Codice:
fscanf(fp, " %c", &c);
                      if( c!='(' )
                      {   
                      return NULL;
                      }
           
           fscanf(fp, " %c", &c);
                      if( c==')' )
                      return NULL;
                     
                      a=malloc(sizeof(struct albero));
                      a->radice=c;
                      a->s=make_albero(fp);
                      a->d=make_albero(fp);
                                           
          fscanf(fp, "%c", &c);
          return a;           


comunque funziona tutto, francamente non capisco a cosa servisse fgetc nel codice precedente.
Ho messo lo spazio nell'acquisizione di %c su fscanf (come consigliato da te) e legge il carattere dopo lo spazio.
Secondo te ho tralasciato qualcosa di importante, oppure ungetc era strettamente necessario?
m4551
Average Member
Average Member
 
Messaggio: 309 di 535
Iscritto il: 11/02/2010, 11:49

Re: [C] Alberi binari, datemi un mano a capire una piccola porzione di codice.

Messaggioda apatriarca » 24/11/2014, 15:46

Il tuo codice non fa quello che fa il codice originale. In particolare, il secondo carattere letto non sarà uguale al valore da inserire nel nodo. ungetc in quel caso è stato usato per reinserire l'eventuale inizio del numero da inserire nell'albero.
apatriarca
Moderatore
Moderatore
 
Messaggio: 3616 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] Alberi binari, datemi un mano a capire una piccola porzione di codice.

Messaggioda m4551 » 24/11/2014, 20:26

ho capito tutto, grazie per l'aiuto!
m4551
Average Member
Average Member
 
Messaggio: 310 di 535
Iscritto il: 11/02/2010, 11:49


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite