Fortran入門: データ入出力
http://www.nag-j.co.jp/fortran/FI_14.html
format文 (Fortranプログラミング入門マニュアル | Fortran プログラミング 入門 講座)
http://harukin.la.coocan.jp/fortran/004/format.html
Fortranのファイル読み書き&フォーマット文に関しては上記を参照。
ただし、Fortran77 の時もそうだったのだが、Fortran で書き出して、Fortran で読み込む分にはさほど書式に気を遣わなくていい…というか、適当に write(*,*) で書き出して、read(*,*) で読み込めるってのが Fortran の便利なところ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | program Console1 implicit none integer count integer readdata character*80 fname ! ファイル出力 open(10,file= 'sample.txt',status='replace') write (10,*) 'Hello', x, y close(10) print *, 'write sample.txt' ! 一応初期化 x = 0 y = 0 ! ファイル入力 open(11,file= 'sample.txt',status='old') read(11,*), str, x, y close(11) print *, 'read sample.txt' print *, 'read:', str, x, y fname = 'sample2.txt' count = readdata(fname) print *, 'read count:', count end program Console1 |
フォーマットを決めずに write した後に read する例。単純に、変数を並べて write すれば良しなにしてくれるので非常に便利です。固定のデータ数や配列の場合には、ちまちま書くか、do ループを使って固定数分読み書きすればよい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ! データを終端 "END" まで読み込む integer function readdata(fname) implicit none ! character*80 :: fname character(*), intent( in ) :: fname integer :: count character*20 :: mark integer :: x, y count = 0 print *, 'fname:' , fname open(10,file=fname,status= 'old' ) do read(10,*,end=100), mark, x, y count = count + 1 if ( mark == 'end' ) then exit end if print *, 'read:' ,x,y end do 100 close(11) readdata = count end function readdata |
この do ループの部分は定番です。read の時に end=100 のように行番号で飛ばすのは、Fortran90 のスタイルではどうなのだろう?と思うのですが、ひとまずこれで。ファイル番号を付けるのは、VB6 と同じです。適当にダブらない番号を付ければ OK です。ただし、サブルーチンからサブルーチンを呼び出すときに、このファイル番号がダブった場合どうなるのかは不明。なので、open/close 自体はちょっと注意しないと。
このサンプルでは、文字列の先頭が「end」で終わったときに終端と判断していますが、数値が「-1」の時というのも定番な動作です。C++の場合は、1行読み込んだ後に、先頭が「end」なのか、有効な数字なのかという判断をしますが、Fortranの場合は、文字列を数値を混在させるのは面倒なので、最初のカラムが数値ならば「-1」で、文字列にするならば「end」でという使い分けをしたほうが良いでしょう…と fortran90 初心者は思う訳です(fortran77は昔やったことがあるけど)。「end」を終端にする場合は、先頭のカラムの文字列は捨てカラムにするのが良いですね。
1 2 3 4 5 | data 10 21 data 11 22 data 12 23 data 13 24 end |
のように、先頭のカラムを捨ててしまうわけです。実は、これが便利なのは先頭が「data」の時はデータ行をあらわして「end」の場合は終端、という形で1行を読み込んだときに判断が付くところです。perl で処理する時に楽だったりします。大学の頃は、フォーマットの前処理を perl でやって、最終的に fortran で読み込ませる方法を取っていました。