Kurs FORTRANU | ||
---|---|---|
Předcházející | Další |
Zajímavá aplikace modulů a polí je při práci s tabulkami a obrázky. Problém je podobně řešitelný v různých jazicích. Zde si ukážeme čtení datového souboru (databáze) ve fortranu. Cvičně si zvolíme soubor s následující strukturou:
Tabulka 8. Struktura databazové tabulky
Část souboru | Údaj | délka |
---|---|---|
Hlavička | délka v x | 10 znaků |
Hlavička | délka v y | 10 znaků |
Hlavička | kometář | 40 znaků |
Data | záznamy | 10 čísel na radek |
každý záznam v tomhle souboru obsahuje 10 čísel na řádek. To znamená, že bez ohledu na délku v X nebo Y čteme pořád 10 číselné záznamy.
program pokus1 ! mozne naivni reseni integer :: nx,ny character(len=40) :: com real,allocatable :: data(:,:) read(*,"(3I10,I40)") nx,ny,com allocate(data(nx,ny)) do read(*,*,end=220) data(?????) enddo 220 continue end
Problem je s indexováním pole data. Jistě by šlo nejakým strašně složitým způsobem přetrasfomovávat indexy. Jiné řešení by bylo pomocí standardní funkce pack namapovat matici do vektoru a pak číst z něj. Ovšem existuje podstatně elegantnejší řešení.
Module databaze character(len=40), private :: com = ' ' integer, private :: nx=0,ny=0 real, private, allocatable :: data(:,:) logical :: databuf private :: readdata contains subroutine opendb(unit,name) integer :: unit character(len=*) :: name open(unit,file=name,status='old') read(*,"(3I10,I40)") nx,ny,com allocate(data(nx,ny)) databuf = .false. end subroutine subroutine getxy(nx1,nx2) integer :: nx1,ny1 nx1 = nx ny1 = ny end subroutine function readdb(unit,i,j) integer :: unit,i,j real :: readdb if( .not. databuf ) then call readdata(unit,i,j) databuf = .true. endif readdb = data(i,j) end function subroutine readdata(unit,x,y,data) integer :: unit, i, x, y real :: data(:) i = 1 do while ( i ≤ (nx*ny)/10 + 1) read(unit,*) data(i:i+80) i = i + 1 enddo end subroutine subroutine closedb(unit) integer ::: unit close(unit) nx = 0 ny = 0 com = ' ' deallocate(data) end subroutine end module Program pokus2 use database ! lepsi reseni nacitani integer nx,ny call opendb(1,"databaze.dat") call getxy(nx,ny) write(*,*) "posledni prvek =",readdb(1,nx,ny) if( status /= 0 ) stop 'Error while data read.' closedb(1) end program
Vypadá to uměle a složitě, ale v případě použití složitho souboru to velmi usnadní práci a čtení. Kromě toho je přesně s tímhle stylem definován astronomický FITS formát a programováno čtení a psaní do souboru v Unixu. Je totiž méně HW náročné načíst najednou 1kB z disku a pak z něj postupně číst, když je potřeba než provádět operace po bytech.
Předcházející | Domů | Další |
LU Rozklad | Datové typy |