愛しの Fortran・3改

Fortran について気の向くままに綴ります

実数値を文字列に変換する関数 (その2)

さて、前回の関数 F_(A,N,FMT) は実数値 A と書式仕様 FMT の他に 関数結果の長さ N を引数としていました。 どうして書式仕様を与えているのに、さらに N が必要だったのか。 Fortran 95 までは関数結果の文字変数の長さは関数の開始時に確定していることが必要でした。 その当時の書き方だったからです。

ところで、結果変数に直接 WRITE せず、いったん別に用意した LINE に書いたのを コピーしてました。

      CHARACTER(MAX(L_,N)) :: LINE

      WRITE(LINE,FMT) A
      RESULT = LINE

これはユーザーが指定する結果変数が短かすぎることによるバッファオーバーフローを 避けるためです。 L_ は十分な長さと仮定しています。

なお、前回の出力結果はわざと末尾に空白が 1 つ付く 6 文字にしてありましたが、 ブログでは末尾の空白が消えて 5 文字になってしまいました。 markdownはてなブログmarkdown の仕様でしょうか。

さて、ここからが今日の本題。 Fortran 2003 以降は文字型の結果変数を ALLOCATABLE にできます。

      CHARACTER(:), ALLOCATABLE :: RESULT

結果変数の割り付けと代入は 1 文でできます。

      RESULT = TRIM(LINE)

代入時に RESULT が割り付けられていないか、TRIM(LINE) とは長さが違う場合、 右辺の長さに割り付けられて代入されます。 前回よりかは改善されたかと思います。 下に改訂版のプログラムを付けます。

ところで、実数の配列の値も出力したいですよね? これ意外に簡単じゃないです。

(つづく)

MODULE MODULE

      USE, INTRINSIC :: IEEE_ARITHMETIC

      INTEGER, PARAMETER :: &
       R_ = IEEE_SELECTED_REAL_KIND(13)

      INTEGER, PARAMETER :: L_ = 132

CONTAINS

!
      FUNCTION F_(A,FMT) RESULT(RESULT)
      REAL(R_), INTENT(IN) :: A
      CHARACTER(*), INTENT(IN) :: FMT
      CHARACTER(:), ALLOCATABLE :: RESULT

      CHARACTER(L_) :: LINE

      WRITE(LINE,FMT) A
      RESULT = TRIM(LINE)
      END FUNCTION F_

END MODULE MODULE

      PROGRAM PROGRAM
      USE :: MODULE

      WRITE(*,"(*(G0))") '"', F_(12.3_R_,"(F0.2)"), '"'
      END PROGRAM PROGRAM