Input/Output: novità

Lo standard F90 introduce solamente novità marginali per quanto riguarda l'input/output, tra cui la formalizzazione di alcuni de-facto standard, si riporta quinidi una lista non esaustiva.

Ad es. per i formati di output interi:

  • può essere indicato un secondo argomento numerico opzionale, separato dal punto, che indica il numero minimo di cifre da stampare (aggiungendo eventualmente degli zeri davanti al numero)
  • se l'argomento numerico indicante la larghezza del campo è =0, il campo ha una larghezza variabile, pari al massimo tra la larghezza minima necessaria per rappresentare il numero in questione e l'eventuale larghezza minima richiesta dal secondo parametro se presente.
Non è previsto in F90 l'uso di variabili numeriche nella stringa del formato, se non tramite un'internal write su una stringa da utilizzarsi come descrittore di formato, a differenza di quanto gestito da alcune estensioni F77.

PROGRAM conformato
IMPLICIT NONE

INTEGER :: i,j,k
CHARACTER(LEN=5) :: fl

READ*,i,j

PRINT'(i4.3)',i ! ' 007'
PRINT'(i3.3)',i ! '007'
PRINT'(i0.3)',i ! '007'
PRINT'(i0)',i ! '7'

WRITE(fl,'(I5.5)')j
PRINT'('//fl//'i3)',(i,k=1,j)

END PROGRAM conformato
Tra le novità sull'I/O in F90/95, non c'è purtroppo niente di nuovo sulla gestione delle condizioni di errore e end of file nelle istruzioni OPEN, READ e compagnia; in particolare la keyword IOSTAT= continua a restituire valori di errore non standard (tranne IOSTAT=0, tutto bene). Il consiglio è quindi:
  • usare END=<label> per gestire l'end of file con un GOTO <label> implicito
  • non usare ERR=<label>IOSTAT=<value>, in modo che il programma si interrompa naturalmente in caso di errore e l'utente riceva quindi un utile messaggio esplicativo sul luogo e il motivo dell'errore
Se, nonostante tutto, si desidera proprio che il programma non abortisca in caso di errore di I/O, allora si può usare ERR=<label> o IOSTAT=<value> ricordandosi che non sarà possibile fornire all'utilizzatore una spiegazione dell'errore (sarà invece possibile in F2003).
PROGRAM errio
IMPLICT NONE
CHARACTER (LEN=80) :: line
INTEGER :: io

! Senza gestione dell'errore (abortisce con messaggio fortran)
OPEN(10, FILE='prog.conf', STATUS='OLD')
DO WHILE(.TRUE.)
  READ(10,*,END=40) line
  CALL elabora(line)
ENDDO

40 CLOSE(10)

! Con gestione dell'errore (non abortisce ma non so spiegare il motivo)
OPEN(10, FILE='prog.conf', STATUS='OLD', IOSTAT=io)
IF (io == 0) THEN
  DO WHILE(.TRUE.)
    READ(10,*,END=50,IOSTAT=io) line
    IF (io /= 0) EXIT
    CALL elabora(line)
  ENDDO

50 CLOSE(10)
ENDIF

END PROGRAM errio