Fortran 2003 入門

ナビゲーション:前へ   上へ   次へ

7.17 ユーザ定義入出力

総称識別子READ(FORMATTED), READ(UNFORMATTED), WRITE(FORMATTED), WRITE(UNFORMATTED)は構造型項目に対する 通常の入出力処理を置き換える機能を提供します。 書式付き入出力の場合、この置換えは並び書式、名前並び書式、 及びDT編集記述子を持つ明示的書式に対して行われます。 それは明示的書式における他の編集記述子には影響を与えません。 ユーザ定義入出力を用いるとユーザ定義手続きが処理を行うため、 ポインタ成分や割付け成分を持つ構造型への入出力か可能となります。

ユーザ定義入出力手続きを持つ型定義の例を示します。

  TYPE tree
    TYPE(tree_node),POINTER :: first
  CONTAINS
    PROCEDURE :: fmtread=>tree_fmtread
    PROCEDURE :: fmtwrite=>tree_fmtwrite
    GENERIC,PUBLIC :: READ(formatted)=>fmtread, WRITE(formatted)=>fmtwrite
  END TYPE

上の型定義が与えられた場合、TYPE(tree)オブジェクトが書式付き入出力並びで有効な項目であるときは常に、 (READ文中で)モジュール手続きtree_fmtreadがコールされ、 もしくは(WRITE文中で)モジュール手続きtree_fmtwriteがコールされ、 該当オブジェクトに対する入出力が行われます。 総称引用仕様ブロックでもユーザ定義入出力の手続き宣言が行える点に注意してください。 連続型もしくはBIND(C)型においてはこの方法しかありませんが、拡張可能型に対しては推奨されません。

それぞれの入出力総称識別子と結合された手続きは、下記と同じ特性を持っていなくてはなりません。 ここにtype-declaration は拡張可能型の場合CLASS(derived-type-spec)であり、 連続型もしくはBIND(C)型の場合にはTYPE(derived-type-spec)です。 構造型が長さ型パラメタを持つ場合、 それらは(‘*’として指定される)“引継ぎ”でなければならない点に注意してください。

SUBROUTINE formatted_read(var,unit,iotype,vlist,iostat,iomsg)
type-declaration,INTENT(INOUT) :: var
INTEGER,INTENT(IN) :: unit
CHARACTER(*),INTENT(IN) :: iotype
INTEGER,INTENT(IN) :: vlist(:)
INTEGER,INTENT(OUT) :: iostat
CHARACTER(*),INTENT(INOUT) :: iomsg

SUBROUTINE unformatted_read(var,unit,iostat,iomsg)
type-declaration,INTENT(INOUT) :: var
INTEGER,INTENT(IN) :: unit
INTEGER,INTENT(OUT) :: iostat
CHARACTER(*),INTENT(INOUT) :: iomsg

SUBROUTINE formatted_write(var,unit,iotype,vlist,iostat,iomsg)
type-declaration,INTENT(IN) :: var
INTEGER,INTENT(IN) :: unit
CHARACTER(*),INTENT(IN) :: iotype
INTEGER,INTENT(IN) :: vlist(:)
INTEGER,INTENT(OUT) :: iostat
CHARACTER(*),INTENT(INOUT) :: iomsg

SUBROUTINE unformatted_write(var,unit,iostat,iomsg)
type-declaration,INTENT(IN) :: var
INTEGER,INTENT(IN) :: unit
INTEGER,INTENT(OUT) :: iostat
CHARACTER(*),INTENT(INOUT) :: iomsg

それぞれの手続き内で、unitは親入出力文が通常装置番号を使用しているときは通常装置番号を、 親入出力文が内部ファイルに対するものであるときは負の数を、 ‘*’装置のときはプロセッサ依存の番号(負の値もあり得ます)を意味します。 iostat引数にはユーザ定義入出力手続きからの復帰前に値が代入されていなくてはなりません。 その場合、ゼロは成功を、 負の値IOSTAT_EOR(組込みモジュールISO_FORTRAN_ENVで定義)はレコード終端条件を、 負の値IOSTAT_ENDはファイルの終端条件を、正の値はエラー条件をそれぞれ表します。 iomsg引数はエラーが発生していない時にはそのままにしておく必要があり、 iostatがゼロ以外の値を取るときには説明メッセージを代入する必要があります。

書式付き入出力手続きにおいてiotype引数は、 並び書式の場合に‘LISTDIRECTED’に、名前並び書式の場合に‘NAMELIST’に、 DT編集記述子が処理されている場合に‘DT’が文字表現(character-literal)と連結された値にセットされます。 vlist引数はDT編集記述子中の値の並びを持ち、 それが存在しない場合にはゼロサイズの配列となります。 DT編集記述子の構文は次の通りである点に注意してください:

DT [ character-literal ] [ ( value [ , value ]... ) ]

ここで空白は特に意味を持たず、character-literal は種別パラメタを持たないデフォルト文字定数表現で、 それぞれのvalue は種別パラメタを持たない省略可能で符号付きの整数定数表現です。 例えば‘DT’, ‘DT"z8,i4,e10.2"’, ‘DT(100,-3,+4,666)’, ‘DT"silly example"(0)’はすべて構文的に正しいDT編集記述子です。 それらが何を意味するかの解釈はユーザ定義手続き次第です。

ユーザ定義入出力手続きを実行している間、unit引数以外の外部装置への入出力は行えませんが、 内部ファイルへの入出力は許容されます。 ファイル位置付けコマンドは使用できません。 書式なし入出力の場合、手続き内で多数のデータ転送文が別個に実行されたとしても、 すべての入出力は現在のレコード内で行われます。すなわちネストされたデータ転送の前後でのファイル位置付けは抑止されます。 書式付き入出力の場合、その効果はネストされたデータ転送文が停留型とみなされるのとほぼ同等です。 (スラッシュ(/)編集記述子、 もしくはストリームファイルへの改行文字の送信を用いた)明示的なレコード終結は有効です。 またネストされた並びもしくは名前並び入出力文を用いてレコードを終わらせることも可能です。

unitが外部ファイルと結合されている場合(すなわち非負、 もしくは組込みモジュールISO_FORTRAN_ENVからの定数ERROR_UNIT, INPUT_UNIT, OUTPUT_UNITのいずれかに等しい場合)、PADモード、 符号モードなどの現在の設定をINQUIREunit引数にPAD=SIGN=等を指定して調べることができます。 なお、INQUIREunitが内部ファイルと結合している場合には使用できない点に注意して下さい。

最後に、ユーザ定義入出力は非同期入出力との互換性はありません。 ユーザ定義入出力に関連するすべての入出力文は同期型でなくてはなりません。


ナビゲーション:前へ   上へ   次へ

関連情報
ご案内
© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks