情報処理概論
第８回

ファイル入出力

情報基盤研究開発センター

谷本 輝夫

1

今日の予習プログラム（1/2）
program msum
implicit none
integer :: i, j, m, nreal(8),dimension(:,:),allocatable :: a, b, c
open(10, file='a.dat')
open(11, file='b.dat')read(10, *) mread(11, *) n
if (m /= n) thenwrite(*, *) "Error: Sizes of matrices are different."stop
end ifallocate(a(n,n))
allocate(b(n,n))
allocate(c(n,n))2

今日の予習プログラム（2/2）
do i = 1, nread(10, *) a(i,1:n)read(11, *) b(i,1:n)
end doclose(10)close(11)c = a + bopen(12, file='c.out')
do i = 1, nwrite(12, *) c(i, 1:n)end doclose(12)stop
end program
3

さらに、次ページの二つのファイルも入力する今日の予習プログラム


データファイルを2個作成

ファイル名 b.dat

ファイル名 a.dat
3
1 2 3
4 5 6
7 8 9


ファイルの作り方：

3
1 1 1
2 2 2
3 3 3
プログラムの作成と同じ$ emacs ファイル名
プログラムを実行すると c.out というファイルが出来るので、内容を less か emacs で確認
4

今回の内容

ファイルからの read

ファイルへの write5キーボードからの入力の問題点


大量のデータを入力する場合に非効率

なぜ非効率か？

% ./msum
Enter n:2
A(1,1):1A(1,2):
2
A(2,1):
3
A(2,2):
4
B(1,1):
1
B(1,2):
1
B(2,1):
1
B(2,2):
61

データファイルの利用

データを別途ファイルとして入力し保存⇒ プログラムの入力データとして利用

プログラム% ./score4
Average = ...

データファイル
読み込み

1030
60
40
...
90
85
95

7

ファイルによる入力の利点

一度入力すれば何度でも利用可能

入力や修正が簡単

emacs など、使い慣れたエディタを利用

途中で間違っても修正が容易

様々なデータを利用可能

インターネットからダウンロードしたファイル



メールに添付されたファイル

スキャナや実験装置から得られたデータ

8

プログラム例１（1/2）
program score4
implicit none
integer, parameter :: kamoku = 3
integer :: i, j, total, number
integer, dimension(:,:), allocatable :: score
real(8) :: avescore.dat という名前のファイルをintrinsic dble

開いてファイル番号 10 を割り当てるopen(10, file="score.dat")! Read number from data fileread(10, *) number

ファイル番号 10 からデータ入力

allocate(score(number, kamoku) )このプログラムとは別に、score.dat という名前でデータファイルを（emacsで）作成する
9

プログラム例１（2/2）
do i = 1, number
read(10, *) score(i, 1:kamoku)
end doclose(10)ファイル番号 10 からデータ入力（一人分ずつ）

ファイル番号 10 を閉じる

total = 0
do i = 1, number
do j = 1, kamoku
total = total + score(i, j)
end doend doave = dble(total) / dble(number*kamoku)
write(*, *) 'Average = ', ave
stop
end program10ファイルからのデータ入力の手順


ファイルを開く (open)

データを読む (read)

ファイルに番号が付く

指定した番号のファイルからデータを読む

ファイルを閉じる(close)

番号とファイルの対応付けが無くなる＝ 同じ番号を別の openに利用できるようになる

11open ファイルを開くプログラムからファイルにアクセスするための番号を付ける



利用法

open(番号,file = "ファイル名")

番号：正の整数．


慣習的に10以上の番号を付けることが多い

番号のうち５と６は既に別の用途で使われているので避ける

ファイル名
と言うより、ファイルの場所



別のディレクトリにあるときはディレクトリ名を付けて書く

open(10, file="data/score.dat")12

read ファイルからデータを読む

利用法

read(番号，書式)


番号：open で指定したファイルの番号


データを格納する変数＊を指定すると, キーボードから入力

書式：通常は＊のままで良い＊を指定すると書式指定無し

Write と同様の書式を指定することもできるが、データもその書式の通りに並んでいなければならない

13

close ファイルを閉じる

ファイルへのアクセス終了

利用法

close(番号)

番号：

open で指定した番号14データを読み込む場合の注意

1 回の read で1行分のデータが全て読み込まれる


1 回の read で1行文のデータを全て格納しないと読み落としが発生

例）

以下のデータファイルを入力する場合



１回のread で１行分の全データが読み込まれるので10 20 30
40 50 60

10 20 30

1回あたり３個分の格納場所を指定する

do i = 1, 2read(10, *) a, b, cread(10, *) score(i, 1:3) またはread(10, *) d, e, f
end do15配列データの入力方法


方法A：

データファイル
102030405060

1要素ずつ入力

do i = 1, number
do j = 1, kamoku
read(10, *) score(i, j)
end doend do

方法B： 1行分まとめて入力

データファイル

do i = 1, number
read(10, *) score(i, 1:kamoku)
end do10 20 30
40 50 60
16

間違いの例


1行のデータ数と readに指定された格納場所の数が一致しない例）

do i = 1, number
do j = 1, kamoku
read(10, *) score(i, j)
end doend doデータファイル10 20 30
40 50 60

score(1,1)に1行目の最初の要素 10score(1,2)に2行目の最初の要素 40がそれぞれ格納され、20, 30, 50, 60はどこにも格納されない

しかも、score(1,3)のデータを読み込もうとしてデータが不足するのでエラーが発生
17

プログラム例１の場合
プログラム中の read とデータファイルの内容の対応関係

read(10, *) number

5
10 20 30
40 50 60
70 80 90
100 110 120
130 140 150

do i = 1, number
read(10, *) score(i, 1:kamoku)
end do18

今回の内容

ファイルからの read

ファイルへの write

19ファイルへの write

計算結果をデータとしてファイルに保存

画面に収まりきれない量のデータ

他のプログラムで利用したいデータ

成果として公表したいデータ
etc.

画面ではなくファイルに write

する

20

ファイルへのデータ出力


ファイルを開く (open)

データを書き出す (write)

ファイルに番号が付く

指定した番号のファイルにデータを書き出す

ファイルを閉じる (close)

番号とファイルの対応付けが無くなる

21

ファイルにデータを書き出す利用法

write(番号，書式) 出力データ


番号：ファイルの番号を指定する＊を指定すると画面に出力

22

プログラム例２（1/2）
program score5
implicit none
integer, parameter :: kamoku = 3
integer :: i, j, total, number
integer, dimension(:,:), allocatable :: score
real(8) :: ave
intrinsic dbleopen(10, file="score.dat")! Read number from data fileread(10, *) number
allocate(score(number, kamoku) )23

プログラム例２（2/2）
do j = 1, number
read(10, *) score(j, 1:kamoku)
end doclose(10)total = 0
do i = 1, kamoku
do j = 1, number
total = total + score(j, i)
end doend doave = dble(total) / dble(number*kamoku)
open(11, file = "score.out")
write(11, *) 'Average = ', aveclose(11)stop
end program24

今日の演習「ｎ人の身長と体重をファイルから読み込み、BMIを計算してファイルに書き出す」
人数ｎもファイルから読み込む



BMIの計算式は、𝐵𝐵𝐵𝐵𝐵𝐵 = 体重 kg ÷ (身長 𝑚𝑚 )2



時間に余裕がある人は、以下にも挑戦
「BMIが普通体重の範囲外であるものについては、マークを併せて表示する」

但し、日本人の適正範囲（普通体重）は、18.5以上、25未満25