愛しの Fortran・3改

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

書式付き流れ探査入出力 (その6)

停留入出力

書式付き流れ探査入出力は、従来の(書式付き)順番探査入出力とほぼ上位互換で、 機能が拡張されているということを見てきました。

元々、流れ探査は C のストリーム入出力との互換性を意識した機能です。 ぱっと見て C と Fortran のテキスト入出力の大きな違いは、 C が文字単位のアクセスと、Fortran が行単位のアクセスを主に意図しているところです。 従来との上位互換のため、書式付き流れ探査入出力も、既定では行単位の入出力になっています。

一方で、C により似せるための方策として、停留入出力というのがあります。

      WRITE(UNIT,"(G0)",ADVANCE="NO") "a"
      WRITE(UNIT,"(G0)",ADVANCE="NO") "b"
      WRITE(UNIT,"(G0)",ADVANCE="NO") NEW_LINE("")
      WRITE(UNIT,"(G0)",ADVANCE="NO") "c"
      WRITE(UNIT,"(G0)",ADVANCE="NO") NEW_LINE("")

WRITE 文に「ADVANCE="NO"」指定子を付けます。 こうすると、WRITE 文が既定では暗黙的に行う末尾の改行が省かれます。 これを Fortran 用語では「停留入出力」(nonadvancing input/output) と呼びます。 逆に通常の、文の実行ごとに改行される入出力は「前進入出力」(advancing ー) です。

上のコード片の出力は

ab
c

になります。 上の例では 1 文字ずつ出力しているので、C で言う fputc() の代わりになって、 C 言語用のアルゴリズムを「直訳」して実装することにも便利です。

ただし、入力については C との違いがもう少し大きくなります。 下は「入力のそのまま出力」を C 流に実装するプログラム片です。

      CHARACTER :: CH

      DO
        READ(UNIT,"(A)",ADVANCE="NO",IOSTAT=IOSTAT) CH
        IF (IOSTAT > 0) THEN
          ERROR STOP 74  ! エラー
        ELSE IF (IS_IOSTAT_END(IOSTAT)) THEN
          EXIT  ! EOF
        END IF

        IF (IS_IOSTAT_EOR(IOSTAT)) THEN
          WRITE(*,"()")  ! '\n'
        ELSE
          WRITE(*,"(G0)",ADVANCE="NO") CH
        END IF
      END DO

C だと fgetc() の戻り値が直接 '\n'EOF だったりしますが、 Fortran では行末とファイル末(それにエラー)は IOSTAT 指定子の値に返されます。

(つづく、次回最終回)