2016-06-12 1 views
1

Ce programmePourquoi un accès direct I/O ne fonctionne pas correctement avec Intel de Visual Fortran

program test 

    real a(10) 

    open(1, file='f1',access='direct', recl=20) 
    do i=1, 10 
     a(i) = i-1 
    end do 
    write(1, rec=1)(a(i),i=1,5) 
    write(1, rec=2)(a(i),i=6,10) 
    close(1) 
    open(1, file='f1',access='direct',recl=8) 
    read(1, rec=4)(a(i),i =5,9,4) 
    print*,a 
    end 

œuvres incorrectes dans Visual Fortran (incorrect):

:

0.0000000E+00 1.000000  2.000000  3.000000  9.000000 
    5.000000  6.000000  7.000000  0.0000000E+00 9.000000 

Résultat dans WATCOM (correct)

0.0000000 1.0000000  2.0000000  3.0000000  6.0000000 
    5.0000000 6.0000000  7.0000000  7.0000000  9.0000000 

Pourquoi?

Répondre

1

La longueur d'unité par défaut de RECL dans Visual Fortran est un mot (4 octets). Si vous compilez avec l'option 'Utiliser les octets comme RECL = unité pour le fichier non formaté' (/ supposez: byterecl), vous obtiendrez ce que vous attendez.

2

Vous ne devriez pas avoir besoin de savoir lors de l'écriture du code quelle est exactement la longueur de l'enregistrement dans toutes les unités. Réglage recl=20 ou recl=5 et en fonction du comportement exact de votre compilateur et la taille exacte real est une recette pour les problèmes futurs.

Vous devriez demander au compilateur de la taille de l'enregistrement en unités selon qu'il utilise:

integer :: recl5, recl2 

inquire(iolength=recl5) (a(i),i=1,5) 

open(1, file='f1',access='direct', recl=recl5) 


... 


inquire(iolength=recl2) (a(i),i =5,9,4) 
open(1, file='f1',access='direct',recl=recl2) 

Note: Dans Fortran 90, il pourrait être beaucoup plus court en utilisant la notation sous-tableau.

Note2: Pour certains compilateurs votre programme ne fonctionnera jamais car le compilateur est autorisé à utiliser des marques de fin d'enregistrement dans le fichier et vous devez toujours l'ouvrir avec le même recl. Mais ce n'est pas commun.