PROGRAM Listino2
!--------------------------------------------------------------------------
! Ricerca del prezzo di un articolo in un listino.
!--------------------------------------------------------------------------
  IMPLICIT NONE
!--- Definizione un "tipo derivato"
  TYPE :: Articolo
    CHARACTER(LEN=5) :: codice
!      Dichiarazione di una componente di tipo stringa.
!      NOTA: in Fortran le stringhe hanno lunghezza fissa.
    INTEGER :: prezzo
  END TYPE Articolo
!--- Dichiarazione delle variabili
  INTEGER,PARAMETER :: nmax=100
  TYPE(Articolo),DIMENSION(nmax) :: listino    ! array di tipo Articolo
!   Una variabile di tipo derivato si chiama "struttura"
!   Qui definiamo un vettore di strutture.
!   NOTA: la parola chiave TYPE viene usata in due istruzioni di genere
!   diverso.
  INTEGER :: i,nelem
  CHARACTER(LEN=5) :: cod
  LOGICAL :: trovato
!--- Caricamento del listino
  WRITE(*,*) "Quanti articoli? (massimo", nmax, ") : "
  READ(*,*) nelem
  WRITE(*,*) "Dammi di seguito codice e prezzo: "
  READ(*,*) (listino(i)%codice,listino(i)%prezzo, i=1,nelem)
!   "%" e' il selettore di componente delle strutture.
!   La clausola (..., i=1,nelem) si chiama "DO implicito".

!--- Interrogazione iterata
!   Ciclo a condizione
  DO
    WRITE(*,*) "Codice articolo? ('' per terminare) : "
    READ(*,*) cod
!     Uscita dal ciclo
    IF (cod=='') EXIT       ! Una stringa vuota per terminare
                            ! da inserire da tastiera proprio come '' o ""
!--- Ricerca codice
    trovato = .FALSE.
!     I valori logici sono .TRUE. e .FALSE., punti inclusi!
    DO i=1,nelem                                ! scandisci il listino
      IF (listino(i)%codice == cod) THEN        ! controlla l'i-esimo elem.
        WRITE(*,*) "Prezzo:", listino(i)%prezzo ! codice trovato
        trovato = .TRUE.
        EXIT
!         In caso di cicli annidati, EXIT termina quello più interno.
!         Per uscire dal ciclo esterno bisogna dare un'etichetta al ciclo e
!         nominarla a seguito di EXIT.
      END IF
    END DO

!--- Segnala errore se e' il caso
    IF (.NOT.trovato) WRITE(*,*) "Codice inesistente!"
!     Gli operatori logici sono .NOT., .AND., .OR., .EQV., .NEQV.,
!     in ordine di precedenza.
!     .NEQV. e' l'OR esclusivo, .EQV. il suo contrario.
  END DO
  STOP
END PROGRAM Listino2
