2014-05-08 15 views
5

użyłem FORTRAN trochę, wiele lat temu, a niedawno za zadanie utrzymać starą FORTRAN programu (F77). Poniższy kod nie znał:objaśnienie Fortran domniemanej pętli

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

Przegląd niektóre on-line fora ujawniły, że część, która została mylące mnie, linia kontynuacji, jest implikowana pętla. Ponieważ mój program sprawia mi problemy tutaj, chcę przekonwertować to do konwencjonalnej pętli DO. Konwersja może również pomóc następnemu marnemu slobowi, który podnosi to zimno 5 lat od teraz! W każdym razie, mój najlepszy przypuszczenie na równowartość DO pętli jest

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

Ale kiedy zrobiłem tylko te zmiany, które zostały przypadki testowe pracujące przestał działać. Wciąż czuł, że to co się dzieje tutaj było dwa różne czyta (pierwszy dostać NUM_WORDS, a drugi do pętli danych), więc spróbował mniej drastyczne zmiany, przekształcając go do dwóch stwierdzeń, ale zachowując dorozumianej pętlę:

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

Ale ta zmiana powoduje również niepowodzenie dobrych przypadków testowych. W obu moich zmianach wartość NUM_WORDS nadchodziła zgodnie z oczekiwaniami, więc wydaje się, że pętla jest tam, gdzie się nie udaje.

Więc, co jest odpowiednikiem DO-pętla dla oryginalnego domniemanych pętli? Czy jestem na niewłaściwym torze?
Dzięki

+0

Dzięki za odpowiedź, janneb. Twoje założenie o otwartym pliku było poprawne; Używam niesformatowanej sekwencji. I z twojej odpowiedzi widzę, że ważniejszą kwestią jest READ i że straciłem kontrolę nad faktem, że czyta ona płytę. – user3617977

Odpowiedz

3

W jaki sposób otwierany jest plik? To znaczy. czy jest to ACCESS = 'sequential', access = 'direct', czy access = 'stream' (cóż, ostatni jest mało prawdopodobny, ponieważ jest dodatkiem F2003). Po drugie, czy jest sformatowany czy niesformatowany? Zakładam, że jest to niesformatowana sekwencja, ponieważ w instrukcjach odczytu nie ma specyfikatora REC = ani specyfikatora formatu.

Powodem, co starasz się nie jest to, że każdy przeczytać oświadczenie czyta oddzielny rekord. Przed wprowadzeniem access = 'stream' w F2003, Fortran I/O był całkowicie oparty na rejestrach, co jest nieco obce tym, których używaliśmy do streamowania plików typów, jak w większości innych języków.

Zapisy niesformatowany plików sekwencyjnych są zwykle oddzielone „markerów record” na koniec każdego rekordu, zwykle 4 bajty określające długość rekordu. Tak więc rekord (na dysku) może wyglądać tak

| długość (4 bajty) | num_words (4 bajty?) | bufor (1) | bufor (2) | ... | długość |

Teraz, jeśli spróbujesz odczytać, powiedzmy, num_words za pomocą jednej instrukcji READ, poprawnie odczyta ona num_words z pliku, THEN przejdzie do przodu, aż do rozpoczęcia następnego rekordu. A kiedy spróbujesz odczytać bufor za pomocą oddzielnej instrukcji READ, jesteś już zbyt daleko w pliku.

Jeśli oszukać trochę i używać F90 + składni tablicy, można uciec z

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

(choć nie jestem pewien, czy masz prawo odwołać NUM_WORDS w tym samym oświadczeniu, gdzie to jest napisane to)