4 votes

Éviter le paradigme GOTO dans Fortran FORMAT lors de la lecture/écriture.

A l'université, le professeur qui nous enseignait le Fortran, nous a donné le code suivant :

     program example
     integer year, month, day, inst, kind, ozone
     real time
     open(unit=1,file='C:\261.dat')
     read(1,1000) year, month, day, inst, kind, ozone, time
     close(1)  
1000 format(i4,1x,i2,1x,i2,1x,i1,1x,i1,1x,i3,1x,f8.3)
     end

Dans ce code, la ligne indexée par 1000 spécifie le format d'entrée particulier. N'est-ce pas quelque chose comme une logique GOTO ? Et si oui, quel est le moyen le plus approprié de l'éviter, dans le contexte de Fortran ?

3voto

francescalus Points 16310

Dans une instruction de transfert de données formatées, il existe trois façons de spécifier le format à utiliser (Fortran 2018 R1215) :

  • référencement d'une déclaration FORMAT étiquetée
  • en utilisant une expression de caractères (par défaut)
  • avec un * (pour le formatage par liste)

Par exemple (en utilisant une instruction PRINT pour plus de clarté) :

1000 FORMAT (I0)

print 1000, 1     ! Pointing to a FORMAT statement
print '(I0)', 1   ! Literal constant: one form of a character expression
print *, 1        ! List-directed formatting

end

Dans aucun de ces cas, la spécification de format ne fonctionne comme une instruction GO TO.

Une instruction GO TO modifie le flux d'exécution, alors que dans la spécification de format, l'exécution reste à l'instruction de transfert de données, puis passe à l'instruction suivante.

Le fait de spécifier une étiquette pour le format ne transfère pas le contrôle de l'exécution à cette instruction, cela signifie simplement "utiliser le format donné par l'instruction 1000". D'un point de vue conceptuel, cela revient à dire que

character(*), parameter :: CHAR_FMT='(I0)'
print CHAR_FMT, 1
end

dit "utiliser l'objet caractère CHAR_FMT (qui est déclaré/défini ailleurs)" comme format.

Vous trouverez de nombreuses objections aux instructions FORMAT et des suggestions (raisonnables) d'alternatives, mais aucune objection à l'utilisation d'une instruction FORMAT n'est fondée sur le fait qu'elle est "comme un GO TO". (Et, bien sûr, les instructions GO TO ne sont pas intrinsèquement mauvaises).


Les spécifications du format peuvent être mises en contraste avec les err= y end= y eor= les spécificateurs : ils sont fonctionnellement comme des instructions GO TO :

1 read(unit, fmt, err=10, end=20, eor=20) x
...
! COME FROM 1
20 continue
...

return
! COME FROM 1
10 ERROR STOP "Error in the read"

Ce type de flux en forme de saut peut être géré alternativement avec le contrôle IOSTAT :

read(unit, fmt, iostat=iostat) x
if (iostat...) ...

2voto

veryreverie Points 71

Vous pouvez éviter d'utiliser les étiquettes de format en utilisant plutôt chaînes de format comme

program example
  integer year, month, day, inst, kind, ozone
  real time

  open(unit=1,file='C:\261.dat')
  read(1,'(i4,1x,i2,1x,i2,1x,i1,1x,i1,1x,i3,1x,f8.3)') year, month, day, inst, kind, ozone, time
  close(1)
end

vous pouvez traiter la chaîne de format comme une chaîne régulière character variable, comme

program example
  integer year, month, day, inst, kind, ozone
  real time
  character(42) :: format

  open(unit=1,file='C:\261.dat')
  format = '(i4,1x,i2,1x,i2,1x,i1,1x,i1,1x,i3,1x,f8.3)'
  read(1,format) year, month, day, inst, kind, ozone, time
  close(1)
end

Cela vous permet de faire passer des formats dans votre code comme n'importe quelle autre variable, et vous permet également de générer et de modifier des formats au moment de l'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X