2014-05-08 7 views
5

Ich habe FORTRAN vor ein paar, vielen Jahren, und vor kurzem beauftragt, ein altes FORTRAN-Programm (F77) zu erhalten. Der folgende Code war ungewohnt:Klärung eines Fortran implizierte Schleife

 READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS, 
    . (BUFFER(BIX), BIX=1, NUM_WORDS) 

Überprüfung einig Online-Foren aufgedeckt, dass der Teil, den ich verwirrt, die Fortsetzungszeile, eine implizite Schleife ist. Da mein Programm gerade hier Probleme macht, möchte ich dies in eine konventionelle DO-Schleife umwandeln. Die Umwandlung könnte auch dem nächsten armen Kerl helfen, der das Ding in 5 Jahren kalt macht! Wie auch immer, meine beste Vermutung an der DO-Schleife entspricht

READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS 
    DO BIX=1, NUM_WORDS 
    READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) BUFFER(BIX) 
    ENDDO 

Aber wenn ich nur diese Änderung vorgenommen, Testfälle, die Arbeiten wurden aufgehört zu arbeiten. Ich hatte immer noch das Gefühl, dass hier zwei verschiedene READs vorgingen (das erste, um NUM_WORDS zu erhalten, und das zweite, um die Daten zu durchlaufen), also versuchte ich eine weniger drastische Änderung, indem ich sie in zwei Anweisungen umwandelte, aber die implizierte Schleife behielt:

READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS 
    READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) (BUFFER(BIX), BIX=1, NUM_WORDS) 

Aber nur diese Änderung führt auch dazu, dass die guten Testfälle fehlschlagen. In beiden meiner Änderungen kam der Wert von NUM_WORDS wie erwartet durch, so scheint es, dass die Schleife dort ist, wo es fehlschlägt.

Also, was ist die äquivalente DO-Schleife für die ursprüngliche implizite Schleife? Oder bin ich überhaupt auf der falschen Spur?
Danke

+0

Danke für die Antwort, janneb. Ihre Annahme über die Dateiöffnung war richtig; Ich verwende unformatierte sequentielle. Und von Ihrer Antwort sehe ich, dass das wichtigere Problem das LESEN ist, und dass ich den Überblick über die Tatsache verlor, dass es eine Aufzeichnung liest. – user3617977

Antwort

3

Wie wird die Datei geöffnet? I.e. ist ACCESS = 'sequentiell', access = 'direct' oder access = 'stream' (nun, der letzte ist unwahrscheinlich, da es ein F2003-Zusatz ist). Zweitens, ist es formatiert oder unformatiert? Ich gehe davon aus, dass es sequenziell nicht formatiert ist, da es in Ihren Leseanweisungen weder einen REC = -Spezifikator noch einen Formatbezeichner gibt.

Der Grund, warum Sie versuchen, fehlschlägt, ist, dass jede gelesene Anweisung einen separaten Datensatz liest. Vor der Einführung von access = 'stream' in F2003 war Fortran I/O vollständig record-basiert, was ein wenig fremdartig zu denen von uns ist, die zum Streamen von Dateien verwendet wurden, wie in den meisten anderen Sprachen.

Datensätze für unformatierte sequentielle Dateien werden normalerweise durch "Datensatzmarkierungen" an jedem Ende des Datensatzes getrennt, typischerweise 4 Bytes, die die Länge des Datensatzes angeben. So sieht der Datensatz (auf Platte) wahrscheinlich so aus wie

| Länge (4 Byte) | num_words (4 Bytes?) | Puffer (1) | Puffer (2) | ... | Länge |

Jetzt, wenn Sie versuchen zu lesen, sagen, num_words mit einer READ-Anweisung, wird es korrekt num_words aus der Datei lesen, DANN wird bis zum Anfang des nächsten Datensatzes weiterspringen. Und wenn Sie dann versuchen, Puffer mit einer separaten READ-Anweisung zu lesen, sind Sie in der Datei bereits zu weit voraus.

Wenn Sie ein bisschen und Verwendung F90 + Array-Syntax betrügen, könnten Sie mit

READ(FILE_LOG_UNIT, IOSTAT=FILE_STATUS) NUM_WORDS, BUFFER(1:NUM_WORDS) 

weg (obwohl ich nicht sicher bin, wenn Sie erlaubt sind NUM_WORDS in derselben Anweisung zu verweisen, wo es geschrieben wird zu)