14 データ入出力
ここまでのセクションではデータの入力には「read *, 変数並び」を用い、データの(画面への)出力には「print *, 出力項目並び」を用いてきました。 本セクションでは、Fortran の強力なデータ入出力機能をより詳しく説明します。14.1 書式指定付きのデータ出力
書式指定を行ってのデータ出力には、今まで見てきた print 文と、ここで説明する write 文が利用できます。 print 文は画面への出力のみが可能ですが、write 文は画面への出力の他、ファイルへの出力も可能です。 以下に例を示します。print 書式, i write (*,書式) i ! 上記 print 文と同じ事をします
書式部分にアスタリスク(*)を指定するとコンパイラのデフォルトの書式により出力することを表してます。 本テキストのこれまでのサンプルや記述はすべてこのデフォルトの書式指定で記述されていますが、ここでは書式の指定方法について説明を行います。
尚、上記の write 文のアスタリスクは出力先が画面である旨を指定しています。 ここに装置番号と呼ばれる番号を指定すると、その番号で指定された装置(画面、外部ファイル、内部ファイル)へ出力が行われるようになります。 print 文では出力先の指定が行えませんので常に画面への出力が行われます。 (画面以外への出力を行う方法についての詳細はファイル操作のセクションで説明します。)
14.2 書式指定
書式は文字定数表現として括弧で編集記述子(I5, F5.2 など)と文字定数表現("abcd", 'efg' など)の並びをくくって指定します。 例えば以下のように記述をします。print '(I5)', i write (*,'(I5)') i ! この上の print 文と全く同じ意味です print "(I5,I3)", i, j ! 複数の編集記述子はカンマで区切る write (*, "(I5, I3)") i, j ! この上の print 文と全く同じ意味です print "('value is ',i0)", i ! i0 は整数の左寄せを意味します
14.2.1 Format 文を用いた書式指定
書式指定の方法には Format 文を用いる方法もあります。 Format 文は以下の書式を持ちます。文番号 format(書式指定) 例えば print '(f10.4,I10)', r, i 上記と同じ書式を Format 文で指定する場合には以下のように指定します。 print 100, r, i ... ... 100 format(f10.4,I10) 以下のように同じ書式を再利用することもできます。 print 100, r, i print 100, q, j print 100, p, k ... ... 100 format(f10.4,I10)
FORMAT 文は同じプログラム単位内であればどこに記述することもできますが、多くの場合、対応する入出力文の直後、プログラムの終わり部分、プログラムの最初の部分のいずれかに記述されます。
書式指定は Format 文を用いる方法でも用いない方法でも、どちら利用してもかまいません。
14.2.2 編集記述子
編集記述子の主なものを以下に示します。
編集記述子 | 形式 | 意味 | 用例 |
I 形編集記述子 | Iw[.m] | 整数値の変換(幅=w, 最低要求桁数=m) | (I5, I5.4) |
F 形編集記述子 | Fw.d | 実数値の変換(幅=w, 小数点以下の桁数=d) | (f6.2, f15.0) |
E 形編集記述子 | Ew.d[ex] | 実数値の変換(幅=w, 小数点以下の桁数=d, 指数部桁数=x) | (E10.2, E15.2e1) |
A 形編集記述子 | A[w] | 文字の変換(幅=w) | (A, A10) |
X 形編集記述子 | nX | 進める文字数=n | (1X, 8X) |
改行する場合 | / | 改行する | ("abcd",/,"efgh") |
例)
以下に書式指定における注意点を述べます。
- A 形編集記述子において幅を指定しない場合には、該当する文字列の宣言時の幅が適用されます。
-
文字定数表現を書式指定の中に含めることができます。
この際に書式指定がアポストロフィ ' で括られている場合には引用符 " でくくり、逆に引用符で書式指定が括られている場合にはアポストロフィでくくると記述がよりシンプルになります。
【書式指定内の文字定数表現の例】 print '("x=", i0)', x print "('x=', i0)", x ! 上の行と同じ意味です
- 出力時の指定で、I および F 形編集記述子の幅をゼロとすると、特別に必要最小限の幅(実質左寄せ)が適用されます。 (入力時には指定できません。)
- 複素数は2つの実数値用編集記述子(それぞれ異なっていても良い)により指定します。
-
それぞれの編集記述子は、反復数を表す数値を直前に指定することが可能です。
【反復の指定例】 print '(2i5, 3f6.2)', i, j, a, b, c ! i5, i5, f6.2, f6.2, f6.2 と同じ意味 print '(2(i5,f8.2))', i, a, j, b ! かっこでくくられた部分を(この例では 2 回)反復できます
以下に様々な書式指定を利用する例を示します。
[
fmt-output.f90
] - 書式指定出力のサンプル
program fmt_output implicit none integer :: i = 1234 real :: a = 1.234 double precision :: d = 9.87654321d0 complex :: c = (1.5,2.345) character(len=4) :: s = "abcd" print '(i10)', i ! 幅 10、右寄せ print '(i0)', i ! 左寄せ print '(1x,i0)', i ! 1 文字空けて左寄せ print '(i1)', i ! 幅が足りない場合はアスタリスクが出力される print '("x = ", f5.2)', 99999.0 ! 幅が足りない場合のもう1つの例 write (*,'(i10.7)') i ! 幅 10、右寄せ、最低出力桁数 7 (満たない場合は 0 を出力) print '(f10.2)', a ! 幅 10、右寄せ、小数点以下 2 桁 print '(f0.2)', a ! 左寄せ、小数点以下 2 桁 write (*,'(e10.3, f15.5)') a, d ! 複数の書式指定をカンマで区切る例 write (*,'(e10.3e1)') a ! 指数部の桁数まで指定する例 write (*,'(e10.4, f10.4)') c ! 複素数は2つの実数の書式を指定する write (*,'(2f10.4)') c ! 複素数を反復数 2 で指定する print '("(real=",f0.2," imag=",f0.2,")")', c ! 文字定数表現を書式指定に含める例 print '(a)', s ! 幅を指定しないと、宣言時の長さ(ここでは 4)が使われる例 print '(a2)', s ! 幅が足りない場合は切り捨てられる end program fmt_output 出力例: 1234 1234 1234 * x = ***** 0001234 1.23 1.23 0.123E+01 9.87654 0.123E+1 0.1500E+01 2.3450 1.5000 2.3450 (real=1.50 imag=2.35) abcd ab
参考図
14.3 データ入力
データの入力には今まで下記のような指定を行ってきました。read 書式, 入力項目並び 例) read *, i
この例ではアスタリスクがデフォルトの書式を表しています。
これまでの記述方法ですと、入力は標準入力(キーボードなど)から行われますが、より汎用的に外部ファイルなどの入力元を明示的に指定したい場合は、同じ read 文でも下記のような書式で記述を行います。 (write 文の形式に似ています。)
read (*,書式) 入力項目並び
この書き方では最初のアスタリスクが標準入力から入力することを示します。 (入力を標準入力以外から行う方法についての詳細はファイル操作のセクションで説明します。)
デフォルトの書式で標準入力から入力する場合は下記のようにアスタリスクを2つ記述します。
read (*,*) 入力項目並び
上記は今まで使っていた以下と同等です。
read *, 入力項目並び
書式を指定する場合にはアスタリスクの代わりに明示的に書式の指定を行います。 書式の指定方法は出力時の指定に準じますが例えば以下のように行います。
read '(I5)', i read (*, '(I5)') i ! 上と同じ
以下に書式指定による入力を行うプログラム例とその出力例を示します。
[
fmt-input.f90
] - 書式指定入力のサンプル
program fmt_input implicit none integer i, j, k character(6) a print *, "Please enter 3 integers of width 2 (3i2):" read '(3i2)', i, j, k ! 幅 2 の整数を 3 つ読み込む指定 print *, i, j, k print *, "Please type a 6 letter string:" read '(a4)', a ! 6 文字のうち最初の 4 文字が読み込まれる print *, a print *, "Please type the same 6 letter string:" read '(a)', a ! 6 文字すべてが読み込まれる print *, a end program fmt_input 出力例: Please enter 3 integers of width 2 (3i2): 123456 12 34 56 Please type a 6 letter string: ABCDEF ABCD Please type the same 6 letter string: ABCDEF ABCDEF
14.4 ★ 練習課題:書式付き出力
整数を1つと実数を1つキーボードから入力し、以下に示す全ての出力を行うプログラムを作成して下さい。- 整数を幅 12、右寄せで出力
- 整数を左寄せで出力
- 左に 4 つの空白、それに引き続き左寄せで整数を出力
- 実数を小数点以下 4 桁、幅 16、右寄せで出力
- 実数を小数点以下 6 桁、左寄せで出力
- 実数を指数形式、小数点以下 6 桁、幅 16、指数部分 3 桁、右寄せで出力
- 左に 4 つの空白、それに引き続き 3 つの実数(入力された実数、その倍、その 3 倍)を幅 10、小数点以下 6 桁で出力
-
整数と実数(小数点以下 6 桁)を下記の例のように説明文に埋め込んで出力
例)
Integer is 1234 and real number is 1.234560
処理手順例
-
変数を宣言する
例)
integer i
real r -
整数をキーボードから入力する。
例)
read *, i -
実数をキーボードから入力する。
例)
read *, r - 指定された形式で出力する。
実行例: Please enter an integer 1234 Please enter a real number 9.87654 1234 1234 1234 9.8765 9.876540 0.987654E+001 9.876540 19.753080 29.629620 Integer is 1234 and real number is 9.876540
参考図
[ kadai-fmt.f90 ] - 書式付き出力のプログラム例
14.5 ★ 練習課題:英語の文(1 行)をすべて大文字に変換
キーボードより 1 行の英文を入力し、含まれる小文字のすべてを大文字に変換して出力するプログラムを作成して下さい。 この際の 1 行の最大文字数は 100 までとします。 また小文字から大文字への変換は以下の例を参考に行うものとします。※ スペースなども含んだ 1 行を読み込む際の書式は '(a)' を利用して下さい。
character oomoji, komoji oomoji = char(ichar(komoji)-32)
文字が小文字であるかどうかの判別は以下の例を参考に行って下さい。
if ( line(i:i) >= 'a' .and. line(i:i) <= 'z' ) then ...
処理手順例
-
変数を宣言する
例)
character(len=100) line ! 最大 100 文字まで -
文章をキーボードから入力する。(書式指定には '(a)' を利用)
例)
read '(a)', line -
line 内の文字を 1 文字ずつ調べて行くための反復を記述する(do 文)
例)
do i=1,len_trim(line) -
文字列内の各文字について小文字であれば大文字に変換する。
変換は例えば以下のように行う。
例)
if ( line(i:i) >= 'a' .and. line(i:i) <= 'z' ) then
line(i:i) = char( ichar(line(i:i))-32 )
end if - ループの終了する(end do)
- 変換後の line を出力する
実行例: I love fortran! I LOVE FORTRAN![ kadai-sentence-upper.f90 ] - 英語の文(1 行)をすべて大文字に変換するプログラム例
前へ 上へ 次へ