Sun Studio 12: Fortran プログラミングガイド

2.1 Fortran プログラムからのファイルの探査

プログラムとデバイスまたはファイルとの間でデータの転送は、Fortran 論理ユニットを通じて行います。論理ユニットは、入出力文において、論理ユニット番号で識別されます。 論理ユニット番号は、0 から 4 バイト整数の最大値まで (2,147,483,647) です。

文字 * が論理ユニット識別子として現れることがあります。アスタリスクは、READ 文に現れたときは標準入力ファイル、 WRITE 文または PRINT 文に現れたときは標準出力ファイルを表します。

Fortran 論理ユニットは、OPEN 文を通じて、特定の名前付きファイルに関連付けることができます。また、割り当て済みユニットは、プログラムの実行開始時に自動的に特定のファイルに関連付けられます。

2.1.1 名前付きファイルに探査する

OPEN 文の FILE= 指定子は、実行時に、名前付き物理ファイルへの論理ユニットの関連付けを行います。ファイルはあらかじめ存在しているものでもかまいません。また、プログラムの実行時に作成することもできます。

OPEN 文の FILE= 指定子は、簡単なファイル名 (FILE='myfile.out') を指定することも、絶対ディレクトリパスか相対ディレクトリパスを前に付けたファイル名 (FILE='../Amber/Qproj/myfile.out') を指定することもできます。また、指定子は、文字定数、変数、文字式のどれでもかまいません。

ライブラリルーチンを使用して、コマンド行引数と環境変数を文字変数としてプログラムに渡し、OPEN 文でファイル名として使用できます。

次の例 (GetFilNam.f) は、入力された名前から絶対パスファイル名を作成する 1 つの方法を示しています。このプログラムは、ライブラリルーチンの GETENVLNBLNKGETCWD を使用して $HOME 環境変数の値を返し、文字列中の最後の空白以外の文字を見つけ、現在の作業用ディレクトリを決定します。


      CHARACTER F*128, FN*128, FULLNAME*128
      PRINT*, 'ENTER FILE NAME:'
      READ *, F
      FN = FULLNAME( F )
      PRINT *, 'PATH IS: ',FN
      END

      CHARACTER*128 FUNCTION FULLNAME( NAME )
      CHARACTER NAME*(*), PREFIX*128
C           これは、C シェルを仮定しています。
C           絶対パス名は変更しません。
C           '~/' で名前を始めると、チルド (~) はホームディレクトリに
C           置換されます。
C           それ以外の場合、現在のディレクトリのパスを
C           相対パス名の前に置きます。
      IF ( NAME(1:1) .EQ. '/' ) THEN
            FULLNAME = NAME
      ELSE IF ( NAME(1:2) .EQ. '~/' ) THEN
            CALL GETENV( 'HOME', PREFIX )
            FULLNAME = PREFIX(:LNBLNK(PREFIX)) //
     1                     NAME(2:LNBLNK(NAME))
      ELSE
            CALL GETCWD( PREFIX )
            FULLNAME = PREFIX(:LNBLNK(PREFIX)) //
     1                     '/' // NAME(:LNBLNK(NAME))
      ENDIF
      RETURN
      END

GetFilNam.f のコンパイルと実行の結果は、次のようになります。


demo% pwd
/home/users/auser/subdir
demo% f95 -o getfil GetFilNam.f
demo% getfil
 ENTER FILE NAME:
getfil
 PATH IS: /home/users/auser/subdir/atest.f

demo%

これらのルーチンについての詳細は、「2.1.4 ファイル名をプログラムに渡す」を参照してください。また、getarg(3F)、getcwd(3F)、および getenv(3F) のマニュアルページも併せて参照してください。『Fortran ライブラリ・リファレンス』には、そのほかの実用的なライブラリルーチンについても記述されています。

2.1.2 名前を指定しないでファイルを開く

OPEN 文には名前を指定する必要はありません。実行時システムがいくつかの規約に従い、ファイル名を補います。

2.1.2.1 一時ファイルとして開く場合

OPEN 文で STATUS='SCRATCH' を指定すると、システムは tmp.FAAAxnnnnn という形式の名前でファイルを開きます。nnnnn は現在のプロセス ID で置き換えられます。AAA は 3 文字の文字列を示し、x は英字を示します。AAAx によってファイル名が一意になります。プログラムを終了するか、CLOSE 文を実行すると、このファイルはただちに削除されます。FORTRAN 77 互換モード (-f77) でコンパイルするときに、この一時ファイルが削除されないようにするには、CLOSE 文に STATUS='KEEP' を指定します。これは規格外の拡張機能です。

2.1.2.2 すでに開いている場合

すでにプログラムによってファイルが開かれている場合は、そのあとの OPEN 文を使用して、BLANKFORM などのファイルの特性を変更できます。この場合は、変更するファイルの論理ユニット番号とパラメータだけを指定します。

2.1.2.3 あらかじめ接続されているか暗黙の名前付きユニット

プログラムの実行開始時、3 つのユニット番号が自動的に特定の標準入出力ファイルに関連付けられます。あらかじめ接続されるユニットは、標準入力、標準出力、標準エラーです。

通常、標準入力は、ワークステーションのキーボードから入力を受け取ります。標準出力と標準エラーは、ワークステーションの画面に出力を表示します。

そのほかの場合、つまり、OPEN 文に論理ユニット番号を指定し、「FILE= 名前」を指定しない場合、ファイルは fort.n という形式の名前で開かれます。n は論理ユニット番号です。

2.1.3 OPEN 文を使用せずにファイルを開く

デフォルトの規約が想定できる場合 OPEN 文は任意で、使用しなくてもかまいません。論理ユニットへの最初の操作が OPEN または INQUIRE 以外の入出力文である場合は、ファイル fort.n が参照されます。n は論理ユニット番号です。特別な意味を持つ、0、5、6 を除きます。

これらのファイルは、プログラムの実行の前に存在する必要はありません。ファイルへの最初の操作が OPEN 文または INQUIRE 文でない場合、ファイルは作成されます。

例: 次のコード中の WRITE 文がユニット 25 に発行される最初の入出力文である場合、ファイル fort.25 が作成されます。


demo% cat TestUnit.f
      IU=25
      WRITE( IU, '(I4)' ) IU
      END
demo%

このプログラムは、ファイル fort.25 を開いて、そのファイルに書式付きレコードを 1 つ書き込みます。


demo% f95 -o testunit TestUnit.f
demo% testunit
demo% cat fort.25
  25
demo%

2.1.4 ファイル名をプログラムに渡す

ファイルシステムは、Fortran プログラム中の論理ユニット番号を自動的に物理ファイルに関連付けるための機能を持っていません。

しかし、Fortran プログラムにファイル名を渡す方法はいくつかあります。

2.1.4.1 実行時引数と GETARG を経由する

ライブラリルーチン getarg(3F) を使用して、実行時にコマンド行引数を文字変数に読み込むことができます。引数はファイル名として解釈され、OPEN 文の FILE= 指定子で使用されます。


demo% cat testarg.f
         CHARACTER outfile*40
C  ユニット 51 の出力ファイル名として最初の引数を取得する
         CALL getarg(1,outfile)
         OPEN(51,FILE=outfile)
         WRITE(51,*)  'Writing to file: ', outfile
         END
demo% f95 -o tstarg testarg.f
demo% tstarg AnyFileName
demo% cat AnyFileName
 Writing to file: AnyFileName
demo%

2.1.4.2 環境変数と GETENV を経由する

同様に、ライブラリルーチン getenv(3F) を使用して、実行時に環境変数の値を文字変数に読み込むことができます。この値はファイル名として解釈されます。


demo% cat testenv.f
         CHARACTER outfile*40
C  ユニット 51 の出力ファイル名として $OUTFILE を取得する
         CALL getenv('OUTFILE',outfile)
         OPEN(51,FILE=outfile)
         WRITE(51,*) 'Writing to file: ', outfile
         END
demo% f95 -o tstenv testenv.f
demo% setenv OUTFILE EnvFileName
demo% tstenv
demo% cat EnvFileName
 Writing to file: EnvFileName
demo%

getarg または getenv を使用するときには、前後の空白に気をつけるようにしてください。Fortran 95 プログラムは組み込み関数 TRIM を使用でき、古い FORTRAN 77 はライブラリルーチン LNBLNK() を使用できます。この章のはじめにある例の FULLNAME 関数行を用いれば、相対パス名を利用できるようにもプログラムできます。

2.1.4.3 コマンド行における入出力のリダイレクトとパイプ

物理ファイルをプログラムの論理ユニット番号と関連付けるもう 1 つの方法は、あらかじめ接続された標準入出力ファイルをリダイレクトまたはパイプする方法です。リダイレクトやパイプは、実行時の実行コマンド上で行われます。

この方法において、標準入力 (ユニット 5) を読み取り、標準出力 (ユニット 6) か標準エラー (ユニット 0) に書き込むプログラムはリダイレクト、つまりコマンド行上で <, >, >>, >&, |, |&, 2>, 2>&1 を使用することによって、ほかの名前付きファイルを読み取ったり、書き込んだりできます。

これを次の表に示します。

表 2–1 csh/sh/ksh のコマンド行におけるリダイレクトとパイプ

処理 

C シェルを使用する場合 

Bourne または Korn シェルを使用する場合 

標準入力 — mydata から読み取る 

myprog < mydata

myprog < mydata

標準出力 — myoutput に書き込む(上書き) 

myprog > myoutput

myprog > myoutput

標準出力 — myoutput に書き込む(追加) 

myprog >> myoutput

myprog >> myoutput

標準エラーをファイルにリダイレクトする 

myprog >& errorfile

myprog 2> errorfile

標準出力をほかのプログラムの入力としてパイプする 

myprog1 | myprog2

myprog1 | myprog2

標準エラーと標準出力をほかのプログラムにパイプする 

myprog1 |& myprog2

myprog1 2>&1 | myprog2

コマンド行におけるリダイレクトとパイプについての詳細は、cshksh、および sh のマニュアルページを参照してください。