IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Les notions de base du Fortran

Support de cours


précédentsommairesuivant

7. Entrées-Sorties

7-1. Introduction

On appelle entrée-sortie, un transfert d'informations entre la mémoire de l'ordinateur et l'un de ses périphériques (un disque le plus souvent).

Une entrée se traduit par une lecture d'informations du périphérique vers la mémoire, tandis qu'une sortie implique une écriture de la mémoire vers le périphérique.

Ces informations sont stockées dans un fichier qui possède un nom.

L'unité de transmission entre la mémoire et le périphérique s'appelle le bloc. Il permet d'effectuer le traitement en passant par une zone intermédiaire dite zone tampon (buffer) permettant ainsi de limiter le nombre de transferts entre la mémoire et le périphérique : opération coûteuse.

L'unité de traitement est l'enregistrement logique : il correspond à la longueur des données traitées lors d'une opération de lecture-écriture.

L'exploitation d'un fichier au sein d'un programme nécessite au préalable son ouverture qui, en Fortran, est faite au moyen de l'instruction OPEN.

Cette instruction permet notamment :

  • de connecter le fichier à un numéro d'unité logique : c'est celui-ci que l'on indiquera par la suite pour toute opération de lecture-écriture ;
  • de spécifier le mode désiré : lecture, écriture ou lecture-écriture ;
  • d'indiquer le mode de transfert : avec ou sans conversion en caractères ;
  • d'indiquer le mode d'accès au fichier : séquentiel ou direct.

Si l'ouverture du fichier est fructueuse, des lectures-écritures pourront être lancées à l'aide des instructions READ/WRITE par l'intermédiaire du numéro d'unité logique.

Une fois le traitement du fichier terminé, on le fermera au moyen de l'instruction CLOSE.

7-2. Accès séquentiel

On dit qu'un fichier est séquentiel lorsqu'il est nécessaire d'avoir traité les enregistrements précédant celui auquel on désire accéder.

Pour un fichier en lecture le paramètre IOSTAT de l'instruction READ permet de gérer la fin de fichier, celui-ci fait référence à une variable entière qui est valorisée à l'issue de la lecture comme suit :

  • à 0 si la lecture s'est bien déroulée ;
  • à une valeur positive si une erreur s'est produite ;
  • à une valeur négative si la fin de fichier ou une fin d'enregistrement à été rencontrée.

On prendra soin de tester la valeur de cette variable immédiatement après chaque lecture.

7-2-1. Fichier binaire séquentiel

On appelle fichier binaire un fichier dans lequel on stocke les informations telles qu'elles sont représentées en mémoire.

C'est au moment de l'ouverture du fichier que l'on indique le type de fichier à traiter.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  real, dimension(100)  :: tab
  integer               :: i
  real                  :: r
  integer               :: ios

  OPEN( UNIT=1,              &
        FILE="data_bin_seq", &
        FORM="unformatted",  &
        ACCESS="sequential", &
        ACTION="read",       &
        POSITION="rewind",   &
        IOSTAT=ios )
  if ( ios /= 0 ) stop "Problème à l'ouverture"
  READ( UNIT=1, IOSTAT=ios ) tab, i, r
  do while ( ios == 0 )
      ...
    READ( UNIT=1, IOSTAT=ios ) tab, i, r
  end do
  CLOSE( UNIT=1 )

On demande l'ouverture du fichier dont le nom est data_bin_seq. C'est un fichier binaire séquentiel (unformatted, sequential) que l'on désire lire depuis le début (rewind).

Ce fichier est connecté à l'unité logique dont le numéro est 1. C'est ce numéro que l'on indique au moment de la lecture des variables tab, i, r, ainsi qu'à la fermeture du fichier.

L'entier ios contient le code retour de l'OPEN : il est nul si tout s'est bien passé, non nul sinon. Il est vivement conseillé de le tester avant toute opération de lecture ou d'écriture.

Ce même entier est utilisé au sein de l'instruction READ afin de connaître l'état de la lecture.

7-2-2. Fichier texte séquentiel

Dans un fichier texte, les données sont stockées sous forme de caractères. De ce fait :

  • lors d'une lecture, elles sont converties en binaire avant d'être rangées en mémoire ;
  • lors d'une écriture, elles sont converties en caractères avant d'être écrites dans le fichier.

Cette opération de conversion est signalée au sein des instructions READ/WRITE :

  • à l'aide d'une chaîne de caractères appelée format d'édition (paramètre FMT=) ;
  • ou bien en utilisant un nom de liste (NAMELIST) regroupant les variables que l'on désire exploiter (paramètre NML=).
7-2-2-a. Formats d'édition

Pour que la conversion puisse être faite, il est nécessaire de connaître le type de la donnée à convertir.

Pour cela le format d'édition contient des descripteurs :

  • descripteur I pour le type INTEGER ;
  • descripteurs F, E pour le type REAL ;
  • descripteur L pour le type LOGICAL ;
  • descripteur A pour le type CHARACTER.
Exemple
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
PROGRAM texte_sequentiel
  real, dimension(10) :: tab
  integer             :: i
  real                :: r
  integer             :: ios

  OPEN( UNIT=1,          &
    FILE="data_txt_seq", &
    FORM="formatted",    &
    ACCESS="sequential", &
    STATUS="old",        &
    ACTION="write",      &
    POSITION="rewind",   &
    IOSTAT=ios )
  if ( ios /= 0 ) then ! Problème à l'ouverture
    ...
  else
    WRITE( UNIT=1, &
      FMT='(10F8.4,I3,F6.3)') tab, i, r
    ...
  endif
  ...
  CLOSE( UNIT=1 )
END PROGRAM texte_sequentiel

Dans cet exemple, on demande l'ouverture du fichier dont le nom est data_txt_seq. C'est un fichier texte séquentiel (formatted, sequential) existant (old) que l'on désire écraser (rewind).

Comme précédemment, à l'issue de l'OPEN on teste la valeur de retour contenue dans l'entier ios.

Si l'ouverture s'est bien passée on lance, à l'aide de l'instruction WRITE, l'écriture en caractères d'un enregistrement comportant un tableau de réels (tab) suivi d'un entier puis d'un réel (i, r).

Le format d'édition spécifié sous la forme d'une constante chaîne de caractères ('(10F8.4,I3,F6.3)') permet de convertir en caractères les variables ci-dessus :

  • 10F8.4 : écriture des 10 éléments du tableau tab.

Chacun a un gabarit de 8 caractères avec 4 chiffres en partie décimale,

  • I3 : écriture de l'entier i sur 3 caractères ;
  • F6.3 : écriture du réel r sur 6 caractères avec 3 chiffres en partie décimale.
7-2-2-b. Formats d'édition en lecture
  • Iw permet la conversion des w caractères suivants dans le type INTEGER.
  • Fw.d : permet la conversion des w caractères suivants dans le type REAL. Si le point décimal n'est pas présent alors les d derniers caractères désignent la partie fractionnaire.
  • Ew.d : permet la conversion des w caractères suivants (interprétés comme un nombre réel en notation exponentielle) dans le type REAL.
  • Lw : permet la conversion des w caractères suivants dans le type LOGICAL.
  • A[w] : permet de lire des caractères.

Exemples

Dans ce qui suit le caractère ^ représente l'espace. Les différentes entrées présentées sont supposées figurer dans un fichier texte séquentiel connecté à l'unité 1 après un OPEN.

Format d'édition I en lecture

 
Sélectionnez
1.
2.
3.
4.
INTEGER i, j
  ...
READ( UNIT=1, FMT='(I5,I4)' ) i, j
  ...

Entrées

Affectations

^^45^^^9^

i=45, j=9

^-24^10^^

i=-24, j=10

À noter : dans un champ en entrée, l'espace est ignoré.

Formats d'édition F, E et D en lecture

Ce format a la forme générale : Fw.d , Ew.d ou bien Dw.d.

Le nombre réel à lire peut être soit en notation virgule fixe, soit exponentielle avec, dans ce dernier cas, l'exposant préfixé de la lettre E ou D.

Le point décimal peut ne pas figurer :

  • s'il est spécifié alors le nombre indiqué par d est ignoré, c'est le nombre de décimales figurant en entrée qui est pris en compte ;
  • s'il est omis c'est le nombre indiqué par d qui est considéré.
 
Sélectionnez
1.
2.
3.
4.
REAL x, y
  ...
READ( UNIT=1, FMT='(F4.1,F6.2)' ) x, y
  ...

Entrées

Affectations

^3.1-3.141

x=3.1, y=-3.141

^123^^5678

x=12.3, y=56.78

 
Sélectionnez
1.
2.
3.
4.
5.
6.
REAL x
  ...
READ( UNIT=1, FMT='(E12.6)' ) x
! ou bien
READ( UNIT=1, FMT='(F12.6)' ) x
  ...

Entrées

Affectations

2.718281^^^^

x=2.718281

2718281^^^^^

x=2.718281

27.18281d-1^

x=2.718281

.2718281e+1^

x=2.718281

.2718281^e^1

x=2.718281

^^^^^2718281

x=2.718281

^^^^^^^^^271

x=0.000271

Format d'édition L en lecture

Ce format a la forme générale : Lw.

Ce type de format permet la lecture de valeurs logiques.

Le caractère w indique comme précédemment la largeur du champ en entrée. Celui-ci doit comporter comme premier caractère non blanc l'une des lettres F, f, T ou t éventuellement précédée du caractère '.'. N'importe quels caractères peuvent compléter le champ.

 
Sélectionnez
1.
2.
3.
4.
LOGICAL l1, l2
  ...
READ( UNIT=1, FMT='(L6,L7)' ) l1, l2
  ...

Entrées

Affectations

.true..false.

l1=.TRUE., l2=.FALSE.

^^^^t..FACILE

l1=.TRUE., l2=.FALSE.

t^^^^^F^^^^^^

l1=.TRUE., l2=.FALSE.

Format d'édition A en lecture

Ce format a la forme générale : A[w].

Ce type de format permet la lecture de caractères. La valeur w indique le nombre de caractères que l'on désire traiter en entrée :

  • si la valeur de w est plus grande que la longueur l de la chaîne réceptrice, ce sont les l caractères les plus à droite qui seront lus ;
  • si elle est plus petite, w caractères seront lus et stockées dans la chaîne réceptrice qui sera complétée à droite par des blancs ;
  • si elle n'est pas précisée, c'est la longueur spécifiée lors de la déclaration de la chaîne de caractères qui indiquera le nombre de caractères à lire. Si la fin de l'enregistrement est atteinte avant la fin de la lecture, la chaîne est complétée par des blancs.
Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
CHARACTER(len=7) :: ch1, ch2
  ...
READ( UNIT=1, FMT='(A6,A8)' ) ch1, ch2
READ( UNIT=1, FMT='(A6,A8)' ) ch1, ch2
READ( UNIT=1, FMT='(A,A)'   ) ch1, ch2
  ...

Entrées

Affectations

BACH^^^^BACH^^

ch1=« BACH^^^ »,ch2=« ^BACH^^ »

MOZARTHAENDEL^

ch1=« MOZART^ »,ch2=« AENDEL^ »

MOZARTHAENDEL^

ch1=« MOZARTH »,ch2=« AENDEL^ »

7-2-2-c. Formats d'édition en écriture
  • Iw [.d] : permet l'édition d'une variable de type INTEGER sur w caractères. S'il est présent d indique le nombre minimum de chiffres édités : si nécessaire des 0 apparaîtront en tête du nombre.
  • Fw.d : permet l'édition d'une variable de type REAL sur w caractères comprenant le point décimal suivi de d chiffres pour la partie fractionnaire.
  • Ew.d : idem format F, mais la sortie est faite en notation exponentielle.
  • Lw : permet l'édition d'une variable de type LOGICAL sur w caractères.
  • A[w] : permet l'édition d'une variable de type CHARACTER.

Format d'édition I en écriture

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
INTEGER i, j, k

i = -125
j = 1756
k = 1791
WRITE( UNIT=1, FMT='(I4,I4,I4)' ) i, j, k
WRITE( UNIT=1, FMT='(I5,I6,I6)' ) i, j, k
WRITE( UNIT=1, FMT='(I6.5,I6.6,I6.6)' ) i, j, k

Sorties

-12517561791

^-125^^1756^^1791

-00125001756001791

Format d'édition F en écriture

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
REAL x, y, z

x = 3.14159
y = -15.137
z = 799.7432
WRITE( UNIT=1, &
       FMT='(F7.5,F8.3,F9.4)' ) x, y, z
WRITE( UNIT=1, &
       FMT='(F6.2,F9.4,F10.5)' ) x, y, z

Sorties

3.14159^-15.137^799.7432

^^3.14^-15.1370^799.74323

Remarque

En ce qui concerne les formats(1) d'écriture I, B, O, Z et F, lorsque le gabarit de la zone réceptrice est insuffisant celle-ci est remplie par le caractère *. Depuis la norme Fortran 95, il est possible d'éviter cela en indiquant 0 comme largeur de zone.

Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
PROGRAM gabarit
  INTEGER I
  REAL    R

  I = 129876
  R = -2345.78

  WRITE( UNIT=1, FMT='(I4, F6.3)' ) I, R
  WRITE( UNIT=1, FMT='(I0, F0.3)' ) I, R
END PROGRAM gabarit

Sorties

**********

129876-2345.780

Format d'édition E et D en écriture

Avec les formats Ew.d, Dw.d on obtiendra en sortie le motif :

 
Sélectionnez
S0.XXXXXXXESXX, S0.XXXXXXXDSXX
   <--d-->         <--d-->
<-----w------>  <-----w------>

Le caractère S indique une position pour le signe.

Un facteur d'échelle peut précéder ce type de format. Il s'écrit sous la forme kP et permet d'éditer le nombre avec kitxmlcodeinlinelatexdvpkfinkitxmlcodeinlinelatexdvp chiffres avant le point décimal (modifie en conséquence la valeur de l'exposant).

Si kitxmlcodeinlinelatexdvp−d < k \le 0finkitxmlcodeinlinelatexdvp, la partie décimale sera constituée de kitxmlcodeinlinelatexdvp|k|finkitxmlcodeinlinelatexdvp zéros suivis de kitxmlcodeinlinelatexdvpd − |k|finkitxmlcodeinlinelatexdvp chiffres significatifs.

Si kitxmlcodeinlinelatexdvp0 < k < d + 2finkitxmlcodeinlinelatexdvp, le nombre en sortie sera constitué de kitxmlcodeinlinelatexdvpkfinkitxmlcodeinlinelatexdvp chiffres significatifs avant le point décimal et de kitxmlcodeinlinelatexdvpd − k + 1finkitxmlcodeinlinelatexdvp chiffres significatifs en partie décimale.

Toute autre valeur de kitxmlcodeinlinelatexdvpkfinkitxmlcodeinlinelatexdvp est invalide : dans ce cas, la zone en sortie sera remplie par le caractère .

Celui-ci s'applique à tous les formats E qui suivent. Pour retrouver le comportement par défaut, il suffit de préciser le facteur 0P.

Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
REAL x, y, z
DOUBLE PRECISION xd, yd, zd
x = 3.14159;   xd = 3.14159d0
y = -15.137;   yd = -15.137d0
z = 799.74328; zd = 799.74328d0
WRITE( UNIT=1, &
       FMT='(D12.6,E13.5,E15.8)' ) x, y, z
WRITE( UNIT=1, &
       FMT='(4P,D12.6,E13.5,0P,E10.3)' ) x, y, z
WRITE( UNIT=1, &
       FMT='(D12.6,E13.5,E15.8)' ) xd, yd, zd
WRITE( UNIT=1, &
       FMT='(4P,D12.6,E13.5,0P,E15.8)' ) xd, yd, zd

Sorties

0.314159D+01^-0.15137E+02^0.79974329E+03

3141.590D-03^-1513.70E-02^0.800E+03

0.314159D+01^-0.15137E+02^0.79974328E+03

3141.590D-03^-1513.70E-02^0.79974328E+03

Il existe deux variantes du format E qui correspondent aux descripteurs EN et ES. Le facteur d'échelle kP ne peut être appliqué dans ce contexte.

Le descripteur EN permet la sortie d'un réel en notation dite ingénieure. Dans ce type de représentation, la valeur absolue de la partie entière est supérieure ou égale à 1 et inférieure à 1000 et l'exposant est divisible par 3.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
REAL x, y, z, t
x = 6.421
y = -.5
z = .00217
t = 4721.3
WRITE( UNIT=1, &
       FMT='(EN12.3,EN12.3,EN12.3,EN12.3)' ) x, y, z, t

Sorties

^^^6.421E+00-500.000E-03^^^2.170E-03^^^4.721E+03

Le descripteur ES permet la sortie d'un réel en notation dite scientifique. Dans ce type de représentation, la valeur absolue de la partie entière est supérieure ou égale à 1 et inférieure à 10.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
REAL x, y, z, t
x = 6.421
y = -.5
z = .00217
t = 4721.3
WRITE( UNIT=1, &
       FMT='(ES12.3,ES12.3,ES12.3,ES12.3)' ) x, y, z, t

Sorties

^^^6.421E+00^^-5.000E-01^^^2.170E-03^^^4.721E+03

Par défaut, la présence du signe + pour les données numériques positives dépend du compilateur. Il existe des descripteurs permettant de forcer sa présence ou bien de le supprimer :

  • SS (sign suppress) : le signe + n'apparaît pas ;
  • SP (sign print) : le signe + précède la donnée ;
  • S : restauration du mode par défaut.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
INTEGER i, j
REAL x, y
i = 1756
j = -69
x = 6.421
y = .00217
WRITE( UNIT=1, &
       FMT='(SP,F7.3,SS,ES12.3,I4,SP,I6)' ) x, y, j, i

Sorties

^+6.421^^^2.170E-03^-69^+1756

Format d'édition L en écriture

Ce format a la forme générale : Lw.

Ce type de format permet l'écriture de valeurs logiques.

En sortie on obtiendra w-1 blancs suivis de la lettre T pour une valeur .true. et F pour une valeur .false..

 
Sélectionnez
1.
2.
3.
4.
LOGICAL l1/.true./, l2/.false./
  ...
WRITE( UNIT=1, FMT='(L6,L7)' ) l1, l2
  ...

Sorties

^^^^^T^^^^^^F

Format d'édition A en écriture

Le format A[w] permet la sortie de chaînes de caractères. La valeur w est facultative. Si elle est précisée, elle indique la largeur de la zone réceptrice :

  • si la valeur de w est plus grande que la longueur l de la chaîne, en sortie celle-ci apparaîtra précédée de w-l blancs ;
  • si elle est plus petite, seuls les w caractères les plus à gauche de la chaîne seront écrits ;
  • si la valeur w est absente, c'est la longueur de la chaîne spécifiée à la déclaration qui indique la largeur du champ en sortie.
Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CHARACTER(len=9) :: ch1, ch2, ch3
  ...
ch1 = "BEETHOVEN"
ch2 = "PUCCINI"
ch3 = "VERDI"
WRITE( UNIT=1, FMT='(A9,A8,A6,A)' ) ch1, &
                                    ch2, &
                                    ch3, &
                                    ch3
WRITE( UNIT=1, FMT='(A10)' ) ch3
ch1 = "Ludwig"
ch2 = " Van"
ch3 = "BEETHOVEN"
WRITE( UNIT=1, FMT='(A,A,A,A)' ) trim(ch1), &
                                 trim(ch2), &
                                 ' ', &
                                 ch3
  ...

Sorties

BEETHOVENPUCCINI^VERDI^VERDI^^^^

^VERDI^^^^

Ludwig^Van^BEETHOVEN

Format d'édition : Litteral string

Si une constante littérale de type chaîne de caractères est spécifiée dans un format, celle-ci est reproduite telle quelle en sortie.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
CHARACTER(len=9) :: ch1, ch2, ch3
  ...
ch1 = "Ludwig"
ch2 = " Van"
ch3 = "BEETHOVEN"
WRITE( UNIT=1, &
       FMT='("NOM : ",A,", PRÉNOM : ",A,A)' ) &
       ch3, trim(ch1), trim(ch2)
  ...

Sortie

NOM^:^BEETHOVEN,^PRéNOM^:^Ludwig^Van

7-2-2-d. Descripteurs de contrôle
  • Descripteurs de positionnement :

    • nX : ignore (en entrée), saute (en sortie) les ncaractères suivants ;
    • Tc : permet de se positionner au caractère de rang c ;
    • TLn : permet de se positionner au caractère situé n positions à gauche par rapport à la position courante ;
    • TRn : permet de se positionner au caractère situé n positions à droite par rapport à la position courante.
  • Descripteurs de gestion des blancs dans les champs numériques en entrée :

    • BN (Blank Null) : ignore les blancs ;
    • BZ (Blank Zero) : interprète le caractère blanc comme un 0.
 
Sélectionnez
1.
2.
3.
4.
5.
INTEGER i, j, k, l
  ...
READ( UNIT=1, &
      FMT='(I4,3X,I2,T12,I3,TL4,I1)' ) i, j, k, l
  ...

Entrées

Affectations

1901^1254^4361

i=1901,j=54,k=361,l=4

 
Sélectionnez
1.
2.
3.
4.
5.
INTEGER i, j, k
  ...
READ( UNIT=1, &
      FMT='(I3,BZ,I2,BN,I3)' ) i, j, k
  ...

Entrées

Affectations

^8^2^4^^

i=8,j=20,k=4

Un autre descripteur, /, provoque le passage à l'enregistrement suivant :

  • en entrée : abandon de l'enregistrement courant et positionnement au début du suivant,
 
Sélectionnez
1.
2.
INTEGER i, j
READ( UNIT=1, FMT='(I4,/,I4)') i, j

Entrées

Affectations

1756^1254

i=1756,j=1791

1791

 
  • en sortie : écriture du caractère newline.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
CHARACTER(len=9) :: ch1, ch2, ch3
ch1 = "Ludwig"
ch2 = " Van"
ch3 = "BEETHOVEN"
WRITE( UNIT=1, &
       FMT='("NOM : ",A,/,"PRÉNOM : ",A,A)' ) &
       ch3, trim(ch1), trim(ch2)

Sortie

NOM^^^^:^BEETHOVEN

PRéNOM^:^Ludwig^Van

7-2-2-e. Facteur de répétition

Lorsqu'une liste de descripteurs identiques figure dans un format, il est possible de les regrouper au moyen d'un facteur de répétition indiqué sous la forme d'une constante littérale entière.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
INTEGER i, j, k
INTEGER t(3)
  ...
READ( UNIT=1, FMT='(I4,I4,I4)' ) i, j, k
READ( UNIT=1, FMT='(3I4)' ) t
  ...
WRITE(6, '(3(1X,I4))') t

Entrées

Affectations

^^45^^^9^^10

i=45, j=9, k=10

^-24^10^^^99

t(1)=-24, t(2)=10, t(3)=99

Sortie

^^-24^^^10^^^99

7-2-2-f. Réexploration d'un format

L'ensemble des variables spécifiées dans une instruction READ/WRITE s'appelle la liste d'entrée-sortie. Chaque élément de cette liste est associé à un descripteur du format :

  • si le nombre de descripteurs correspond au nombre de variables de la liste, ceux-ci s'appliquent aux éléments successifs de cette liste ;
  • s'il est plus grand, les suivants sont ignorés (le format est abandonné) ;
  • s'il est plus petit, le format est réexploré. Cette réexploration entraîne le passage à l'enregistrement suivant.

Conclusion : en Fortran la liste d'entrée-sortie est toujours satisfaite.

La règle de réexploration est la suivante :

  • si le format ne contient aucun groupe de descripteurs entre parenthèses, alors il est réexploré depuis son début ;
  • sinon, la réexploration est faite à partir du groupe de niveau 1 le plus à droite. S'il est précédé d'un facteur de répétition, il est pris en compte.

Exemples

Le caractère | indique l'endroit à partir duquel la réexploration est effectuée.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
'( I6, 10X,I5, 3F10.2 )'
   |-------------------
'( I6, 10X,I5, (3F10.2) )'
               |--------
'( I6,(10X,I5), 3F10.2 )'
      |----------------
'( F6.2, (2F4.1,2X,I4, 4(I7,F7.2)) )'
         |--------------------------
'( F6.2, 2(2F4.1,2X,I4), 4(I7,F7.2) )'
                         |----------
'( F6.2,(2(2F4.1,2X,I4), 4(I7,F7.2)) )'
        |-----------------------------

Exemples

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
INTEGER i/100/, &
        j/200/, &
        k/300/, &
        l/400/
REAL t(3,4)
DATA t/ 1., 4., 9.,   &
       16., 25., 36., &
       49., 64., 81., &
      100., 121., 144. /
WRITE(6, '( 4i5, (t25,4f8.2) )') &
          i, j, k, l,            &
          ((t(i,j),j=1,4),i=1,3)

Sorties

^^100^^200^^300^^400^^^^^^^^1.00^^^16.00^^^49.00^^100.00

^^^^^^^^^^^^^^^^^^^^^^^^^^^^4.00^^^25.00^^^64.00^^121.00

^^^^^^^^^^^^^^^^^^^^^^^^^^^^9.00^^^36.00^^^81.00^^144.00

7-2-2-g. Format libre

En Fortran, il existe un format implicite appelé format libre (list-directed formatting).

Dans l'instruction READ/WRITE, on spécifie alors le caractère * à la place du format.

Dans ce contexte, les enregistrements sont interprétés comme une suite de valeurs séparées par des caractères appelés séparateurs. C'est le type des variables auxquelles ces valeurs vont être affectées qui détermine la conversion à effectuer.

Les caractères interprétés comme des séparateurs sont :

  • la virgule (,) ;
  • le blanc (espace).

Une chaîne de caractères contenant un caractère séparateur doit être délimitée soit par des quotes (') soit par des guillemets (").

En entrée, plusieurs valeurs identiques peuvent être regroupées à l'aide d'un facteur de répétition sous la forme n*valeur.

Une constante complexe est codée comme 2 nombres réels entre parenthèses séparés par une virgule. Les parenthèses ainsi que la virgule peuvent être suivies ou précédées de blancs.

Une fin d'enregistrement (newline) a le même effet qu'un blanc. Elle peut apparaître :

  • au sein d'une chaîne de caractères (délimitée par des quotes (') ou par des guillemets (")) ;
  • entre la partie réelle et la virgule ou entre la virgule et la partie imaginaire d'une constante complexe.

Si une chaîne de caractères a été déclarée avec une longueur plus petite que celle de la valeur lue alors seuls les caractères les plus à gauche de la valeur seront stockés dans la chaîne. Sinon, celle-ci est complétée par des blancs.

Si dans l'enregistrement en entrée apparaissent deux virgules à la suite (éventuellement avec des blancs entre) alors l'élément correspondant de la liste ne sera pas modifié.

Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
INTEGER i/100/, &
        j/200/, &
        k/300/
REAL    t(3)
COMPLEX c
CHARACTER(len=8) ch
  ...
READ ( UNIT=1, FMT=* ) i, j, k, t, c, ch
WRITE( UNIT=2, FMT=* ) i, j, k, c, ch
WRITE( UNIT=2, FMT=* ) t

Entrées

Affectations

150

i=150

260,,

j=260

3*2.718

t=(/ 2.718,2.718,2.718 /)

(^2.

c=(2.,3.)

,^3.^)^^^'Wolfgang Amadeus Mozart'

ch='Wolfgang'

Sorties

^150^260^300^(2.000000000,3.000000000)^Wolfgang

^2.717999935^2.717999935^2.717999935

7-2-2-h. namelist

On peut regrouper les variables que l'on désire lire ou écrire au sein d'une liste à laquelle on donne un nom.

Ce regroupement s'effectue au moyen de l'instruction NAMELIST :

 
Sélectionnez
NAMELIST/nom_liste/liste_variables
  • nom_liste est le nom de la NAMELIST ;
  • liste_variables est une liste de variables précédemment déclarées.

Au niveau de l'instruction READ/WRITE la namelist remplace le format ainsi que la liste de variables qui, dans ce contexte, devient inutile.

L'enregistrement correspondant (lu ou écrit) respecte le format suivant :

 
Sélectionnez
&nom_liste liste d'affectations /

La liste d'affectations concerne les variables de la namelist qui peuvent apparaître dans n'importe quel ordre, certaines pouvant être omises. Les différentes affectations sont séparées par des caractères séparateurs (, ou blancs).

Le caractère / indique la fin de la namelist. En entrée, les éventuels caractères qui suivent sont ignorés. En entrée, les chaînes de caractères doivent être délimitées à l'aide du caractère ' ou ".

En sortie, celles-ci apparaissent par défaut sans délimiteur. C'est le paramètre DELIM= de l'instruction OPEN qui permet de le définir.

Dans l'instruction READ/WRITE, la namelist est indiquée à l'aide du paramètre NML= (à la place de FMT=).

L'utilisation des namelist est un moyen très commode d'effectuer des entrées-sorties sans avoir à définir de format.

Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
INTEGER i/100/, j/200/, k/300/
INTEGER t(3)
CHARACTER(len=11) ch
NAMELIST/LISTE/i,j,k,t,ch
  ...
READ ( UNIT=1, NML=liste )
WRITE( UNIT=2, NML=liste )
  ...

Entrées

Affectations

&LISTE t=3*2,i=1, k=4 ch=« Rythm&Blues » /

i=1,k=4,t(1)=t(2)=t(3)=2,ch=« Rythm&Blues »

Sorties

^&LISTE

^I=1,^J=200,^K=4,^T=2,^2,^2,^CH=Rythm&Blues

^/

7-3. Accès direct

À la différence d'un fichier séquentiel, il est possible d'accéder à un enregistrement d'un fichier à accès direct sans avoir traité les précédents.

Chaque enregistrement est repéré par un numéro qui est son rang dans le fichier. Leur taille est fixe. Au sein de l'instruction OPEN :

  • le paramètre RECL= est obligatoire, sa valeur indique la taille des enregistrements (en caractères pour les fichiers textes, dépend du processeur pour les fichiers binaires) ;
  • le paramètre POSITION= est invalide ;
  • si le paramètre FORM n'est pas précisé, c'est la valeur unformatted qui est prise en compte.

Le rang de l'enregistrement que l'on désire traiter doit être spécifié à l'aide du paramètre REC= de l'instruction READ/WRITE. Un enregistrement ne peut pas être détruit, mais par contre, il peut être réécrit. Dans ce contexte, les namelist ainsi que le format libre sont interdits.

7-3-1. Fichier binaire à accès direct

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
real, dimension(100) :: tab
integer ios, n
OPEN( UNIT=1,                 &
      FILE="data_bin_direct", &
      ACCESS="direct",        &
      ACTION="read",          &
      STATUS="old",           &
      RECL=400,               &
      IOSTAT=ios )
if ( ios /= 0 ) then ! Problème à l'ouverture
  ...
else
  OPEN( UNIT=2, FILE="data_txt_seq", &
        ACTION="read", STATUS="old", &
        IOSTAT=ios )
    ...
  READ( UNIT=2, FMT=* ) n
  READ( UNIT=1, REC=n, IOSTAT=ios ) tab
  if ( ios > 0 ) stop "erreur à la lecture."
    ...
  CLOSE( UNIT=2 )
end if
CLOSE( UNIT=1 )

Le fichier dont le nom est data_bin_direct est connecté à l'unité logique numéro 1. C'est un fichier binaire à accès direct (ACCESS="direct" et paramètre FORM absent donc considéré égal à unformatted). Chaque enregistrement fait 400 octets (RECL=400).

On accède à l'enregistrement de rang n, valeur préalablement lue dans le fichier texte séquentiel de nom data_txt_seq connecté à l'unité logique numéro 2. Le paramètre IOSTAT de l'instruction READ permet de récupérer l'état de la lecture dans l'entier ios : une valeur non nulle positive signale une erreur du type enregistrement inexistant par exemple.

7-3-2. Fichier texte à accès direct

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
real, dimension(100) :: tab
integer ios, n

OPEN( UNIT=1,                 &
      FILE="data_txt_direct", &
      FORM="formatted"        &
      ACCESS="direct",        &
      ACTION="read",          &
      STATUS="old",           &
      RECL=800,               &
      IOSTAT=ios )
if ( ios /= 0 ) stop "Problème à l'ouverture!"
OPEN( UNIT=2,              &
      FILE="data_txt_seq", &
      ACTION="read",       &
      STATUS="old",        &
      IOSTAT=ios )
  ...
READ( UNIT=2, FMT=* ) n
READ( UNIT=1, REC=n, &
      IOSTAT=ios, FMT='(100F8.4)' ) tab
if ( ios > 0 ) stop "erreur à la lecture."
  ...
CLOSE( UNIT=2 )
CLOSE( UNIT=1 )

On a adapté l'exemple précédent à un fichier texte à accès direct : le paramètre FORM="formatted" a donc été précisé.

La valeur du paramètre RECL correspond à la taille en caractères de chacun des enregistrements qui correspond ici au format indiqué au niveau de l'instruction READ (100*8 = 800).

Notes :

  • il n'est pas permis de lire un fichier texte à accès direct au moyen d'un format libre ;
  • un fichier dans lequel on écrit un seul enregistrement de rang n, contiendra en réalité n enregistrements avec les n-1 premiers ayant un contenu indéterminé. Lors de la lecture d'un tel fichier, se pose le problème de la reconnaissance de la nature de celui-ci. On pourra résoudre ce problème en adjoignant aux données une marque sous la forme d'une variable logique par exemple.

Dans l'exemple suivant, des enregistrements de rang aléatoire sont créés. Pour les repérer, on ajoute en tête des données une variable logique flag.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
program dir
  implicit none
  integer, parameter   :: n = 100, m = 1000
  real, dimension(n,m) :: matrice
  real, dimension(n)   :: vec
  integer i,j, rang, ios, size
  logical flag

inquire( iolength=size ) flag, matrice(:,1)
open( unit=1,             &
      file="direct.file", &
      form="unformatted", &
      access="direct",    &
      action="readwrite", &
      status="unknown",   &
      recl=size,          &
      iostat=ios )
if ( ios /= 0 ) stop "Erreur à l'ouverture"

flag = .false.
do j=1,m
  write( unit=1, rec=j ) flag
end do
call random_number( matrice )
flag = .true.
do j=1,m
  if ( matrice(1,j) > matrice(n,j) ) &
    write( unit=1, rec=j ) flag, matrice(:,j)
end do

do
  print *,"Entrez un rang : "
  read( *, *, iostat=ios ) rang
  if ( ios < 0 ) exit
  if ( ios > 0 ) then
    print *,"Erreur de saisie. Veuillez recommencer."
    cycle
  end if
  read( unit=1, rec=rang, iostat=ios ) flag, vec
  if ( ios > 0 ) then
    print *,"Erreur lors de la lecture."; cycle
  end if
  if ( flag ) then
    print *,"vec(1) = ", vec(1), "vec(n) = ", vec(n)
  else
    print *,"Enregistrement ", rang, " indéfini."
  end if
end do
close(1)
end program dir

Notes :

  • l'instruction inquire( iolength=size ) ... permet de récupérer dans l'entier size la taille de la liste de variables fournies qui servira à renseigner, par la suite, le paramètre RECL de l'instruction OPEN. Comme cette valeur est exprimée dans une unité dépendant du compilateur (pour les fichiers binaires en accès direct), cette nouvelle forme de l'instruction inquire(2), introduite par la norme Fortran 90, permet de la calculer en s'affranchissant de l'unité ;
  • l'instruction call random_number( matrice ) fait appel à la procédure intrinsèque Fortran 90 RANDOM_NUMBER qui valorise le tableau transmis à l'aide de nombres aléatoires générés dans l'intervalle [0., 1.].

7-4. Fichier temporaire

Si à l'ouverture d'un fichier on positionne le mot-clé STATUS à la valeur "scratch" alors celui-ci sera temporaire et détruit à sa fermeture. Un tel fichier est anonyme : le paramètre FILE de l'instruction OPEN ne doit donc pas être spécifié dans ce contexte.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
real, dimension(100) :: tab
integer ios

OPEN( UNIT=1, &
      FORM="formatted"  &
      ACCESS="direct",  &
      ACTION="write",   &
      STATUS="scratch", &
      RECL=1200,        &
      IOSTAT=ios )
if ( ios /= 0 ) then ! Problème à l'ouverture
  ...
end if
...
CLOSE( UNIT=1 )

7-5. Destruction d'un fichier

L'instruction CLOSE admet le paramètre à mot-clé STATUS qui par défaut (pour un fichier non temporaire) prend la valeur KEEP permettant ainsi de conserver le fichier après fermeture. Si on désire le supprimer, il suffira de préciser la valeur DELETE pour ce paramètre.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
real, dimension(100) :: tab
integer ios
OPEN( UNIT=1, &
      FILE="data_seq", &
      ACTION="read",   &
      STATUS="old",    &
      IOSTAT=ios )
if ( ios /= 0 ) then ! Problème à l'ouverture
  ...
end if
...
if ( condition ) then
  CLOSE( UNIT=1, STATUS="delete" )
else
  CLOSE( UNIT=1 )
end if

7-6. Fichier interne

On appelle fichier interne un fichier dont les enregistrements sont en mémoire. Ce type de fichier induit des échanges entre zones de la mémoire et non plus entre un support externe et la mémoire.

Ces fichiers sont préconnectés : il n'y a donc aucune ouverture ni fermeture à effectuer.

Dans les instructions READ/WRITE, à la place du numéro d'unité logique, on indique une variable de type chaîne de caractères. C'est celle-ci qui fait référence à l'enregistrement en mémoire.

Seul l'accès séquentiel formaté est permis dans ce cas. Les namelist sont interdites.

Lors d'une écriture, il faut s'assurer que la chaîne de caractères réceptrice est de taille suffisante.

Lors d'une lecture, la fin de fichier est atteinte lorsqu'on essaie d'accéder aux caractères situés au-delà de la chaîne qui fait référence à l'enregistrement.

Exemples
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
INTEGER, PARAMETER   :: n = 4, m = 6
REAL, DIMENSION(n,m) :: tab
CHARACTER(LEN=8)     :: fmt = "( F8.3)"
INTEGER              :: i, j, ios

WRITE( fmt(2:3), '(I2)' ) n ! fichier interne
OPEN( UNIT=1, &
      FILE="data_txt_seq", &
      POSITION="rewind",   &
      ACTION="write",      &
      STATUS="new",        &
      IOSTAT=ios )
if ( ios /= 0 ) then ! Problème à l'ouverture
  ...
else
  WRITE( UNIT=1, FMT=fmt ) &
          ((tab(i,j),i=1,n),j=1,m)
end if
CLOSE( UNIT=1 )

Dans un format le facteur de répétition doit obligatoirement être précisé à l'aide d'une constante littérale. Cet exemple montre comment le générer dynamiquement en utilisant un fichier interne.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
PROGRAM fichier_interne
  CHARACTER(len=80) enreg
  INTEGER ios
  REAL x, y, z
  NAMELIST/liste/x, y, z

  OPEN( UNIT=1, FILE="data_txt_seq",     &
        FORM="formatted", ACTION="read", &
        STATUS="old", POSITION="rewind", &
        IOSTAT=ios )
  IF ( ios /= 0 ) STOP 4
  READ( UNIT=1, FMT='(a)', IOSTAT=ios ) enreg
  DO WHILE( ios == 0 )
    IF ( VERIFY( enreg, &
                 " ,+-0123456789.eEdD" ) == 0 ) THEN
      READ( enreg, FMT=*, iostat=ios ) x, y, z
     !----------------------------------------
      WRITE( UNIT=*, NML=liste )
    END IF
    READ( UNIT=1, FMT='(a)', iostat=ios ) enreg
  END DO
  CLOSE( UNIT=1 )
END PROGRAM fichier_interne

Dans cet exemple, on lit un fichier en ne traitant que les enregistrements constitués de réels et en ignorant tous les autres.

7-7. Instructions de positionnement

Toute opération de lecture-écriture dans un fichier est effectuée par rapport à la position courante dans ce fichier, à l'ouverture celle-ci peut être précisée à l'aide du paramètre POSITION. Dans un fichier séquentiel, toute lecture-écriture d'un enregistrement de rang n implique le positionnement à l'enregistrement de rang n+1.

Trois instructions BACKSPACE, REWIND et ENDFILE permettent de modifier la position :

  • BACKSPACE force la position au début de l'enregistrement précédent ;
  • REWIND force la position au début du fichier ;
  • ENDFILE écrit un enregistrement de type fin de fichier. Il est alors nécessaire d'exécuter ensuite l'une des deux instructions précédentes.

Ces instructions admettent en paramètre le numéro de l'unité logique auquel le fichier est connecté.

Exemple : troncature contrôlée d'un fichier
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
program troncature
  REAL, dimension(100) :: tab
  INTEGER ios
  LOGICAL flag/.false./
    ...
  OPEN( UNIT=1,               &
        FILE="data_txt_seq",  &
        ACTION="readwrite",   &
        POSITION="append",    &
        STATUS="old",         &
        IOSTAT=ios )
  IF ( ios /= 0 ) then ! Problème à l'ouverture
    ...
  ELSE
    tab(:) = acos(-1.)
    WRITE( UNIT=1, FMT='(100F6.3)' ) tab
    REWIND( UNIT=1 )
  END IF

Le fichier dont le nom est data_txt_seq est ouvert avec un positionnement en fin de fichier (POSITION="append"). Après écriture d'un enregistrement, on se repositionne en tête (REWIND).

 
Sélectionnez
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
  READ( UNIT=1, FMT='(100F6.3)', IOSTAT=ios ) tab
  DO WHILE( ios == 0 )
    if ( flag ) then
      BACKSPACE( UNIT=1 )
      ENDFILE( UNIT=1 )
      BACKSPACE( UNIT=1 )
    END IF
    ...
    READ( UNIT=1, FMT='(100F6.3)',IOSTAT=ios ) tab
  END DO
  CLOSE( UNIT=1 )
end program troncature

Ensuite, on relit le fichier et si la variable flag contient la valeur .TRUE. on le tronque avant le dernier enregistrement lu. (Instructions BACKSPACE et ENDFILE).

7-8. Instruction INQUIRE

L'instruction d'interrogation INQUIRE permet de récupérer un certain nombre d'informations concernant un fichier ou un numéro d'unité logique.

Elle permet par exemple de tester si un fichier existe, s'il est connecté et dans ce cas de connaître les valeurs des paramètres positionnés lors de son ouverture via OPEN.

Cette interrogation peut être faite en indiquant soit le numéro d'unité logique soit le nom du fichier.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
program inquire
  LOGICAL existe
  INTEGER ios
  CHARACTER(len=3)  :: form
  CHARACTER(len=10) :: acces

  INQUIRE( FILE="data_txt_seq", EXIST=existe )
  if ( existe ) then
    OPEN( UNIT=1,              &
          FILE="data_txt_seq", &
          POSITION="rewind",   &
          ACTION="read",       &
          IOSTAT=ios )
    if ( ios /= 0 ) then ! erreur à l'ouverture
      ...
    else
      INQUIRE( UNIT=1, &
      FORMATTED=form, &
      ACCESS=acces )
    end if
    ...
    CLOSE( UNIT=1 )
  end if
end program inquire

Dans les variables caractères form et acces on récupère respectivement les valeurs YES et SEQUENTIAL (si le fichier data_txt_seq existe).

7-9. Remarques

Les spécificateurs de format Bw[.d], Ow[.d] et Zw[.d] permettent la conversion de données entières sous forme binaire, octale et hexadécimale respectivement.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
PROGRAM boz
  INTEGER I, J, K

  I = 1415; J = 1515; K = 1715
  WRITE( UNIT = 1, &
         FMT = "(B32.32,'|',O11.11,'|',Z8.8)" &
       ) I, J, K
  I = -1415; J = -1515; K = -1715
  WRITE( UNIT = 1, FMT='(B32.32)' ) I
  WRITE( UNIT = 1, FMT='(O11.11)' ) J
  WRITE( UNIT = 1, FMT='(Z8.8)' ) K
END PROGRAM boz

Sorties

00000000000000000000010110000111|00000002753|000006B3

11111111111111111111101001111001

37777775025

FFFFF94D

Les fichiers associés au clavier et à l'écran d'une session interactive sont préconnectés en général aux numéros d'unités logiques 5 et 6 respectivement : en lecture pour le premier, en écriture pour le second.

Dans un souci de portabilité, on préférera utiliser dans les instructions READ/WRITE le caractère * à la place du numéro de l'unité logique pour référencer l'entrée standard (READ) ou la sortie standard (WRITE). C'est la valeur par défaut du paramètre UNIT. L'instruction PRINT remplace l'instruction WRITE dans le cas où celui-ci n'est pas précisé.

Formes équivalentes

 
Sélectionnez
1.
2.
3.
4.
CHARACTER(LEN=8)      :: fmt = "(F8.3)"
READ( UNIT=5, FMT=fmt) ...
READ( UNIT=*, FMT=fmt) ...
READ fmt, ...
 
Sélectionnez
1.
2.
3.
WRITE( UNIT=6, FMT=fmt) ...
WRITE( UNIT=*, FMT=fmt) ...
PRINT fmt, ...

Le format d'édition peut être défini en dehors des instructions d'entrées-sorties READ/WRITE. Dans ce cas le paramètre FMT= est positionné à un numéro (étiquette) renvoyant à une instruction de définition de format (FORMAT).

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
    REAL, DIMENSION(5,6) :: tab
    INTEGER n, i
    CHARACTER(len=10) :: ch
    ...
    PRINT '( I4,A,(T20,F8.3) )', &
          n, ch, (tab(i,:),i=1,5)
    PRINT 100, n, ch, (tab(i,:),i=1,5)
100 FORMAT( I4,A,(T20,F8.3) )

En Fortran l'ouverture d'un fichier séquentiel est facultative. à défaut, l'ouverture du fichier est faite implicitement lors de l'exécution de la première instruction d'entrée-sortie. Le compilateur attribue au fichier un nom de la forme fort.i (i étant le numéro de l'unité logique indiqué dans l'instruction READ/WRITE). L'ouverture est faite en mode formatted ou unformatted suivant qu'un format a été ou non précisé.

Le paramètre END de l'instruction READ offre un autre moyen de tester une fin de fichier pour un accès séquentiel. On lui indique le numéro (étiquette) de l'instruction à laquelle on désire poursuivre le traitement. Ce paramètre n'est pas valide dans le cas d'un fichier à accès direct.

De même, le paramètre ERR permet de se débrancher à une instruction dans le cas d'une erreur de lecture (problème de format pour un fichier formaté, enregistrement inexistant pour un fichier à accès direct…).

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    INTEGER :: date

    do
      print *, "Saisie d'une date :"
      read( *, '(i4)', END=1, ERR=2 ) date
      print '(i4)', date
      cycle
2     print *, "Saisie invalide. Veuillez recommencer."
    end do
1   print *, "Arr^et de la saisie."
    ...

Remarque : au clavier, la saisie du caractère Ctrl-D après le caractère newline (touche Enter) indique une fin de fichier.


précédentsommairesuivant
formats B, O, Z : c.f. remarques en fin de chapitre.
cette instruction est détaillée plus loin.

Copyright © 2006 Patrick Corde et Anne Fouilloux. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.