[Fortranのはじめ方] Part18: フォーマット指定(FORMAT文)

Fortranで数値計算の結果やデータを思い通りに出力・入力したいとき、FORMAT文(または書式指定子)が非常に役立ちます✨。これを使うと、数値の桁数、小数点以下の表示、文字の配置などを細かく制御できます。


Warning: Undefined array key “is_admin” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 113

Warning: Undefined array key “is_category_top” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 118

Warning: Undefined array key “is_top” in /home/c2261046/public_html/omomuki-tech.com/wp-content/themes/sango-theme/library/gutenberg/dist/classes/Toc.php on line 124

FORMAT文とは?

READ文やWRITE文(PRINT文も含む)でデータの入出力を行う際、そのデータの「形」を指定するのがFORMAT文の役割です。例えば、「整数を5桁で表示したい」「実数を小数点以下3桁まで表示したい」といった要望に応えられます。

書式指定は、主に2つの方法で行います。

  1. WRITE文やREAD文の中に直接書式を書く方法:
    WRITE(*, '(書式指定子)') 変数リスト
    READ(*, '(書式指定子)') 変数リスト
    *は標準出力(通常は画面)や標準入力(通常はキーボード)を意味します。2番目の引数に書式指定子を文字列として記述します。
  2. 別行にFORMAT文を用意し、文番号で参照する方法:
    WRITE(*, 100) 変数リスト
    100 FORMAT(書式指定子)
    
    READ(*, 200) 変数リスト
    200 FORMAT(書式指定子)
    WRITE文やREAD文の2番目の引数に文番号(例: 100, 200)を指定し、対応するFORMAT文で書式を定義します。FORMAT文はプログラム内のどこに書いても良いですが、参照するWRITE/READ文の近くか、プログラムの最後にまとめて書くスタイルが一般的です。

どちらの方法でも同じことができますが、複雑な書式や同じ書式を何度も使う場合は、FORMAT文を使うとコードがすっきりすることがあります。

主要な書式記述子(エディットディスクリプタ) 📝

FORMAT文や書式指定文字列の中には、「書式記述子」と呼ばれるコードを記述します。よく使われるものをいくつか紹介します。

記述子 形式例 説明 例 (出力値)
I Iw, Iw.m 整数 (Integer)。wは全体の桁数(フィールド幅)。mは最小表示桁数(足りない場合は前に0が付く)。 WRITE(*,'(I5)') 123␣␣123
WRITE(*,'(I5.4)') 123␣0123
F Fw.d 実数(固定小数点形式, Fixed-point)。wは全体の桁数(符号、小数点を含む)、dは小数点以下の桁数。 WRITE(*,'(F7.3)') 12.34512.345
WRITE(*,'(F8.2)') -12.345␣-12.35 (四捨五入)
E Ew.d, Ew.dEe 実数(指数形式, Exponential)。wは全体の桁数、dは仮数部の小数点以下の桁数。eは指数部の桁数。科学技術計算で大きな値や小さな値を扱う際に便利です。 WRITE(*,'(E12.5)') 12345.6␣0.12346E+05
ES ESw.d, ESw.dEe 実数(科学形式, Scientific)。Eと似ていますが、仮数部が 1 ≤ |仮数| < 10 の形になるように調整されます。 WRITE(*,'(ES12.5)') 12345.6␣1.23456E+04
EN ENw.d, ENw.dEe 実数(工学形式, Engineering)。指数部が3の倍数になるように調整されます (例: E+03, E-06)。 WRITE(*,'(EN12.4)') 12345.612.3456E+03
G Gw.d, Gw.dEe 汎用 (General)。数値の大きさに応じてF形式かE(またはES)形式を自動で選択してくれます。便利ですが、出力形式が揃わない可能性もあります。 WRITE(*,'(G12.5)') 12.3456␣␣12.346␣␣
WRITE(*,'(G12.5)') 1234567.8␣0.12346E+07
A A, Aw 文字 (Character)。wを指定すると、その幅で出力します。指定しない場合、文字変数の長さで出力されます。wが文字長より短い場合は先頭からw文字、長い場合は右詰めで空白が追加されます。 CHARACTER(LEN=5) :: str = "Hello"
WRITE(*,'(A)') str
Hello
WRITE(*,'(A3)') strHel
WRITE(*,'(A7)') str␣␣Hello
L Lw 論理値 (Logical)。通常、T (真) または F (偽) として出力されます。wはフィールド幅。 LOGICAL :: flag = .TRUE.
WRITE(*,'(L2)') flag
␣T
X nX 空白 (Space)。n個の空白を挿入します。出力の位置調整に使います。 WRITE(*,'(I3, 3X, I3)') 10, 20␣10␣␣␣␣20
T Tn, TLn, TRn タブ (Tabulation)。Tnは絶対位置nへ移動。TLnは現在位置から左へn文字移動。TRnは現在位置から右へn文字移動。 WRITE(*,'(I5, T10, I5)') 1, 2␣␣␣␣1␣␣␣␣␣␣␣␣2 (10桁目から2番目の整数)
/ / 改行 (New Line)。出力時に新しい行を開始します。 WRITE(*,'(A, /, A)') "Line 1", "Line 2"Line 1
Line 2
' ', " " '文字列', "文字列" 文字定数。指定した文字列をそのまま出力します。 WRITE(*,'("Value = ", F5.2)') 1.23Value = ␣1.23
繰り返し r(記述子), r記述子 同じ書式記述子をr回繰り返します。 WRITE(*,'(3I5)') 1, 2, 3␣␣␣␣1␣␣␣␣2␣␣␣␣3 (I5, I5, I5と同じ)

Note: は空白文字を表します。

Note: w(フィールド幅)が指定された値を出力するのに足りない場合、多くの処理系ではフィールド全体がアスタリスク (*) で埋められます。⚠️

使用例 💡

いくつかのデータ型を組み合わせて出力してみましょう。

PROGRAM format_example
  IMPLICIT NONE
  INTEGER :: id = 101
  REAL :: temperature = 25.678
  CHARACTER(LEN=10) :: status = "OK"
  LOGICAL :: is_valid = .TRUE.

  ! WRITE文の中に直接書式を書く例
  WRITE(*, '("ID:", I4, 3X, "Temp:", F7.2, 3X, "Status:", A, 3X, "Valid:", L1)') &
       id, temperature, status, is_valid

  ! FORMAT文を使う例
  WRITE(*, 100) id, temperature, status, is_valid
100 FORMAT("ID:", I4, 3X, "Temp:", F7.2, 3X, "Status:", A, 3X, "Valid:", L1)

END PROGRAM format_example

このプログラムを実行すると、おそらく以下のような出力が得られます(空白の数に注意してください)。

ID: 101   Temp:  25.68   Status:OK         Valid:T
ID: 101   Temp:  25.68   Status:OK         Valid:T
  • I4: 整数idを4桁で出力 (␣101)。
  • 3X: 3つの空白を挿入。
  • F7.2: 実数temperatureを全体7桁、小数点以下2桁で出力 (␣␣25.68)。四捨五入されていますね。
  • 3X: 3つの空白を挿入。
  • A: 文字列statusをその長さ(10文字)で出力 (OK␣␣␣␣␣␣␣␣␣␣)。右側に空白が詰められています。もしA2ならOKだけが出力されます。
  • 3X: 3つの空白を挿入。
  • L1: 論理値is_validを1桁で出力 (T)。

注意点 ⚠️

  • フィールド幅 (w): 出力する値(符号、小数点、指数部などを含む)に対して十分な幅を指定しないと、アスタリスク(*****)で埋められてしまうことがあります。特に実数型では、符号や小数点も桁数に含まれる点に注意が必要です。
  • READ文での書式: READ文で書式を指定する場合、入力データの形式と書式指定が厳密に一致している必要があります。少しでもずれていると、予期せぬ値が読み込まれたり、エラーが発生したりします。自由形式の入力 (READ(*,*)) の方が扱いやすい場合も多いです。
  • 文字定数: 書式内で文字列を出力するには、シングルクォート'またはダブルクォート"で囲みます。
  • 繰り返しとグループ化: 括弧()を使って書式記述子をグループ化し、そのグループを繰り返すことも可能です。例: '(2(I5, 2X))''(I5, 2X, I5, 2X)' と同じ意味になります。

まとめ

FORMAT文(書式指定子)は、Fortranでの入出力をより柔軟かつ精密に制御するための強力な機能です。特に、整形されたレポートや、他のプログラムが読み込むための特定の形式でデータファイルを出力する場合に不可欠です。

最初は少し複雑に感じるかもしれませんが、基本的な書式記述子から試してみて、徐々に慣れていきましょう! 💪

参考情報

これらのリソースや、利用しているコンパイラのドキュメントも参照して、理解を深めてください。