Fortran Tip集

前へ   上へ   次へ

23 IS_IOSTAT_ENDとIS_IOSTAT_EORの使い方

Fortran 2008でI/O操作の管理をより簡単かつ効率的に行う事を可能とするIS_IOSTAT_ENDとIS_IOSTAT_EORが導入されました。

23.1 IS_IOSTAT_ENDの使い方

従来のFortranプログラムでは多くの場合、END=文番号と記述してファイルの終端を検出していました。 しかし、この方法では文番号にジャンプする事となり、プログラムフローをわかりにくくしていました。 以下に従来の方法を用いるプログラム例を示します。

[ read_file_traditional.f90 ] - END=を用いる従来の方法を示すサンプル

program read_file_traditional
  implicit none
  integer :: unit, iostat
  character(len=256) :: line

  open(newunit=unit, file='data.txt', status='old', action='read')
  do
    read(unit, '(A)', iostat=iostat, END=100) line
    print *, trim(line)
  end do
100 continue
  close(unit)
  print *, 'End of file reached.'
end program read_file_traditional

同じ処理内容をIS_IOSTAT_ENDを利用して記述すれば、より簡潔に、わかりやすく記述できるため、プログラムの保守性を向上させます。

[ read_file_traditional.f90 ] - IS_IOSTAT_ENDでファイル終端を検出する方法を示すサンプル

program read_file_modern
  implicit none
  integer :: unit, iostat
  character(len=256) :: line

  open(newunit=unit, file='data.txt', status='old', action='read')

  do
    read(unit, '(A)', iostat=iostat) line
    if (IS_IOSTAT_END(iostat)) then
      exit
    end if
    print *, trim(line)
  end do
  close(unit)
  print *, 'End of file reached.'
end program read_file_modern

[ data.txt ] - data.txtファイル

Hello, this is the first line.
The quick brown fox jumps over the lazy dog.
End of the example data file.
出力例)
 Hello, this is the first line.
 The quick brown fox jumps over the lazy dog.
 End of the example data file.
 End of file reached.

23.2 IS_IOSTAT_EORの使い方

Fortran 2008では、IS_IOSTAT_EORも導入され、これによりファイルからのデータ読み込み時にレコードの終わり(End Of Record)をポータブルな方法で検出することが可能になりました。 これは、特にデータの一部だけを読み込む必要がある場合に有用です。

以下のプログラムは入力ファイルから数値を読み込み、 各行の数値の合計を表示します。 IS_IOSTAT_EORを用いてレコード終端を検出し、 レコード終端に達した場合に合計値を計算するようになっています。

[ read_field.f90 ] - IS_IOSTAT_EORを利用するサンプル

program read_field
  implicit none
  integer, parameter :: nmax_fields = 10
  integer :: unit, iostat, val(nmax_fields), i

  i = 1
  open(newunit=unit, file='data_for_eor.txt', status='old', action='read')

  do
    read(unit, '(I2,1X)', iostat=iostat, advance='no') val(i)
    if (IS_IOSTAT_END(iostat)) then
      exit
    elseif (IS_IOSTAT_EOR(iostat)) then
      print *, "Sum of record:", sum(val(1:i))
      i = 1
      cycle
    elseif ( iostat /= 0 ) then
       print *, "読み込みエラー:", iostat
       exit
    else
      print *, val(i)
      i = i + 1
    end if
  end do

  close(unit)
end program read_field

[ data_for_eor.txt ] - data_for_eor.txtファイルの内容

12 34 56
78
91 23 45 67
89
出力例)
 12
 34
 56
 Sum of record: 102
 78
 Sum of record: 78
 91
 23
 45
 67
 Sum of record: 226
 89
 Sum of record: 89



前へ   上へ   次へ
関連情報
ご案内
© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks