210 likes | 361 Views
Czytanie listy zmiennych według ich nazw: dyrektywa NAMELIST W części deklaracyjnej: NAMELIST / nazwa / zmienna _1, zmienna _2,…, zmienna _n Czytanie: READ( wejście , nazwa_listy ) Zmienne na liście mogą być zmiennymi prostymi lub tablicami. W pliku wejściowym piszemy:
E N D
Czytanie listy zmiennych według ich nazw: dyrektywa NAMELIST W części deklaracyjnej: NAMELIST /nazwa/ zmienna_1,zmienna_2,…,zmienna_n Czytanie: READ(wejście,nazwa_listy) Zmienne na liście mogą być zmiennymi prostymi lub tablicami. W pliku wejściowym piszemy: &nazwa_listyzmienna_1=wartość_1,…, zmienna_n=wartość_n &end Dla zmiennych tablicowych można podać albo leksykograficznie elementy tablicy albo wybrane elementy, np. A(1,1)=1.0,A(1,5)=4.0 Zmienna nie zaspecyfikowana na liście w pliku wejściowym przyjmuje wartość 0.
Obsługa wejścia/wyjścia (I/O) w FORTRANie • Rekord – elementarna porcja informacji jaka może być przesyłana pomiędzy pamięcią operacyjną a urządzeniem zewnętrznym (klawiaturą, ekranem, drukarką, dyskiem, taśmą magnetyczną). • Rekordy specjalne: EOF (End Of File; znacznik końca pliku). • Typy rekordów: • rekordy zredagowane; mogą być zapisane na każdym nośniku; ostatni znak jest znakiem końca linii (EOL; End Of Line); • rekordy niezredagowane; nie mogą być czytane z klawiatury ani zapisane na ekran i drukarkę. • Dostęp do rekordów: • sekwencyjny (pliki na wszystkich nośnikach); • bezpośredni (tylko pliki dyskowe).
Plik danych – uporządkowany zbiór rekordów danych jednakowego typu posiadający jednoznaczny identyfikator (np. nazwę w UNIXie). • Podział plików pod względem rodzaju komunikacji z pamięcią: • Pliki zewnętrzne (ogromna większość): pliki umieszczone na nośnikach zewnętrznych (dyskach, CD-ROMach, taśmach magnetycznych). W FORTRANie odwołujemy się do nich poprzez liczbę całkowitą lub *. • Pliki wewnętrzne: zmienne typu CHARACTER; w FORTRANie odwołujemy się do nich poprzez nazwę zmiennej. • W dawniejszych wersjach FORTRANu pliki wewnętrzne obsługiwały instrukcje ENCODE (pisanie) i DECODE (czytanie); począwszy od FORTRANu77 zwykłe instrukcje READ i WRITE.
Przykład użycia zmiennej jako pliku wewnętrznego w celu konwersji liczby na łancuch tekstowy. CHARACTER*4 LICZ ITER=111 WRITE(LICZ,’(I4.4)’) ITER Po wykonaniu tej operacji w zmiennej LICZ zostanie zapamiętany łańcuch 0111
Identyfikatory logiczne (uchwyty) plików: zmienna_tekstowa: tzw. plik wewnętrzny; *: klawiatura (czytanie) lub ekran (pisanie); 0: STDERR (ekran) standardowe urządzenie na które są wyprowadzane komunikaty o błędach; 5: STDIN (klawiatura) standardowe urządzenie wejścia; 6: STDOUT (ekran lub drukarka) standardowe urządzenie wyjścia; 1-4, 7 i wyżej: plik o danym numerze urządzenia; zwykle oznacza plik dyskowy. Pod numery 0, 5 i 6 można również podłączać pliki zewnętrzne; wtedy te urządzenia tracą swoje standardowe znaczenia.
Otwieranie plików Operacja otwierania przypisuje konkretny plik urządzeniu logicznemu. Standardowe urządzenia wejścia/wyjścia jest zawsze przypisywane identyfikatorowi *; tutaj nie wolno wykonywać instrukcji OPEN. Domyślnie numery (uchwyty) 0, 5 i 6 są przypisywane odpowiednim urządzeniom standardowym. Pozostałe numery (uchwyty) są domyślnie przypisywane plikom o nazwach o ogólnej postaci fort.n gdzie n jest numerem logicznym, a plikom jest przypisywany status ‘UNKNOWN’. Takie nazwy pojawią się po wykonaniu przez program pierwszej operacji na danym pliku różnej od instrukcji OPEN.
Przykład: wykonanie instrukcji: WRITE(1,*) “Ala ma kota” jako pierwszej operacji na pliku o numerze 1 spowoduje pojawienie się pliku o nazwie fort.1 z takim tekstem. Wykonanie instrukcji: WRITE(6,*) “Ala ma kota” Spowoduje wyprowadzenie tego tekstu na ekran.
Instrukcja OPEN otwierania pliku i przypisywania mu numeru logicznego (uchwytu) OPEN(nr_pliku[,FILE=nazwa_pliku][,FORM=forma][, ACCESS=acc][,ERR=etykieta]) Nazwy nie wolno nadawać plikom o statusie ‘SCRATCH’ Przykład: OPEN(1,FILE=“ala.txt”,form=“FORMATTED”) WRITE(1,*) “Ala ma kota” Zostanie utworzony plik ala.txt zawierający podany tekst.
Uwaga! Otwarcie pliku ze statusem ‘UNKNOWN’ powoduje, że pierwsza instrukcja WRITE niszczy poprzednią zawartość pliku. Jeżeli chcemy zachować poprzednią zawartość musimy zadeklarować ACCESS=‘APPEND’. Jest to rozszerzenie standardu FORTRANu 77 i dlatego przypisuje się ją różnym zmiennym I/O w zależności od implementacji; np. POSITION=‘APPEND’ na SGI. Przykład: Niech plik alaias zawiera linę Ala i As Wykonanie sekwencji: OPEN(1,FILE=‘alaias.txt’,status=‘UNKNOWN’,ACCESS=‘APPEND’) WRITE(1,*) “Ala ma kota” Spowoduje dodanie do pliku linii z podanym tekstem. W przeciwnym razie istniejąca zawartość zostałaby zastąpiona przez nową.
Przykład wykorzystania parametru ERR w instrukcji OPEN • CHARACTER*16 nazwa • PRINT ‘(A)’,”Podaj nazwe pliku z danymi” • READ(*,’(A)’) nazwa • OPEN(3,FILE=nazwa,STATUS=‘OLD’,ERR=10) • READ(3,*) X Ponieważ STATUS=‘OLD’, poprawne zakończenie instrukcji OPEN wymaga aby plik już istniał. Dlatego program będzie dotąd pytał o nazwę pliku aż podamy nazwę pliku istniejącego.
Zamykanie pliku CLOSE(nr_pliku [,STATUS=stat],[ERR=etykieta]) Przykład: CLOSE(1) Zamyka plik o numerze 1. CLOSE(1,STATUS=‘DELETE’) Zamyka i usuwa plik o numerze 1. Pliki są zawsze domyślnie zamykane po poprawnym zakończeniu programu nawet jak nie wykonamy instrukcji CLOSE.
Przykład programowej obsługi błędów mogących się pojawić przy czytaniu danych poprzez użycie zmiennych ERR i END: READ(1,*,END=10,ERR=20) X GOTO 30 10 PRINT *,"Koniec danych" STOP 20 PRINT *,"Blad w danych" STOP 30 CONTINUE W przypadku poprawnego przeczytania zmiennej X program przechodzi dalej; zatrzymuje się z odpowiednim komunikatem jeżeli wystąpił błąd przy czytaniu lub koniec danych.
Przykład czytania i pisania nieformatowanego. DOUBLE PRECISION A(100,100) …… C Zapisujemy zawartość macierzy A do pliku o przechowalnia.dat; macierz jest C zapisywana kolumnami i kazda kolumna stanowi 1 rekord. OPEN(1,FILE=“przechowalnia.dat”,STATUS=“NEW”, &FORM=“UNFORMATTED”,ACCESS=“SEQUENTIAL”) WRITE(1) (A(1,I),I=1,100) CLOSE(1) C Tablica A moze byc teraz wykorzystywana do innych celow a jej dotychczasowa C zawartosc jest przechowywana w pliku dyskowym. …… C Teraz chcemy zaladowac zapisana zawartosc macierzy A znowu na dysk. C Nalezy zwrocic uwage, ze dlugosc rekordow w instrukcji czytania musi byc taka C sama jak w instrukcji pisania, ktora zapisalismy tablice A do pliku, OPEN(1,FILE=“przechowalnia.dat”,STATUS=“OLD”, &FORM=“UNFORMATTED”,ACCESS=“SEQUENTIAL”) READ(1) (A(1,I),I=1,100) CLOSE(1,STATUS=“DELETE”) C Plik przechowalnia.dat zostal juz wykorzystany i wykasowany z dysku.
Przykład wykorzystania plików bezpośredniego dostępu. Przypuśćmy, że w pliku “katalog” znajdują się podstawowe dane o związkach chemicznych (nazwa, wzór sumaryczny) o kolejnych numerach katalogowych (numer katalogowy odpowiada numerowi linii) i plik jest na tyle duży, że nie można go wczytać do pamięci. Chcemy uzyskać informacje o związku o i-tym numerze katalogowym. Program Przykład pierwszych linii pliku
Instrukcja INQUIRE INQUIRE(ACCESS=acc,BLANK=blnk,DIRECT=dir, EXIST=ex,FORM=forma,IOSTAT=ios,FILE=nazwa, NAMED=nam,NEXTREC=numer,NUMBER=nr_pliku, OPENED=op, RECL=długość,SEQUENTIAL=seq, UNFORMATTED=unf, ERR=etykieta) dir, form, seq, unf: ‘YES’, ‘NO’ albo ‘UNKNOWN’ blnk: ‘NULL’ albo ‘ZERO’ ex, nam, op: .TRUE. albo .FALSE. ios, numer, nr_pliku, długość: INTEGER nazwa: CHARACTER
Przykład: Sprawdzanie istnienia pliku o danej nazwie. CHARACTER*16 nazwa LOGICAL EX READ(*,’(A)’) NAZWA INQUIRE(FILE=nazwa,EXIST=ex) IF (EX) THEN PRINT *,“Plik “,nazwa,” istnieje” ELSE PRINT *,”Plik “,nazwa,” nie istnieje” ENDIF