web-dev-qa-db-ja.com

fortranのtxtファイルからデータを読み取る

テキストファイルからデータを読み取り、コンソールに書き込むFORTRANプログラムを作成しています。データファイルは次のようになります

1234567890123456 123456.789 987654.321 673647.890 654356.890
6172876534567890 768909.098 234543.890 654321.908 987890.090

データを読み取り、コンソールに書き込むFORTRANコードの次の行があります

 OPEN(1,FILE='data.txt')
    READ(1,'(I16,3F9.3)') A ,B, C, D
    WRITE (*, '(I16,3F9.3)') A,B,C,D
   CLOSE(1)

テキストファイルに同じ値として表示される代わりに、以下は出力です

1234567890123456*********89987.656    0.322
6172876534567890*********98234.547    0.891

これを手伝ってくれませんか。

どうもありがとう

6
Shenoy Tinny

リスト指向のIO(つまり、*)は、特に入力の場合に簡単です。それでも、完全なIOコントロールを使用する場合があるため、理解する価値があります。入力では、データ項目と記述子を列ごとに並べる必要があります。入力の場合、Fw.dでは、データ項目に小数点があるかどうかは関係ありません。フィールドは、入力と出力の両方で十分な幅が必要です。 。変数とデータ項目に一致するタイプの十分な記述子が必要です。このサンプルプログラムと比較してください。

program test_read

   implicit none
   integer, parameter :: VLI_K = selected_int_kind (18)
   integer, parameter :: DR_K = selected_real_kind (14)

   integer (VLI_K) :: i
   real (DR_K) :: a, b, c, d

   open (unit=15, file="data.txt", status='old',    &
             access='sequential', form='formatted', action='read' )

   read (15, 110)  i, a, b, c, d
   110 format (I16, 4(1X, F10.0) )
   write (*, 120) i, a, b, c, d
   120 format ( I18, 4 (2X, F12.3) )

   read (15, *) i, a, b, c, d
   write (*, 120) i, a, b, c, d

end program test_read
9
M. S. B.

読み取りを使用するのにこれまでで最も苦労しましたが、最後に... .txtファイルに保存されているマトリックスを読み取りたい場合は、次を使用してください。

program FILEREADER

   real, dimension(:,:), allocatable :: x
   integer :: n,m

   open (unit=99, file='array.txt', status='old', action='read')
   read(99, *), n
   read(99, *), m
   allocate(x(n,m))

   do I=1,n,1
      read(99,*) x(I,:)
      write(*,*) x(I,:)
   enddo

end

また、「array.txt」ファイルは、たとえば次のようにする必要があります(メインの同じフォルダーに配置します)。

4
3
0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
9.0 10.0 11.0

それがそこにいるすべての人のために働くことを願っています

列構造が固定されている入力ファイルの編集と検査は、ジグザグデータよりも簡単であるため、固定形式を使用しました。私の問題は、Fortranランタイムリーダープロシージャが小数点ドットの有無をどのように解釈するかでした。自分のソリューションが最適かどうかはわかりませんが、データ行を文字配列として読み取り、長さが12文字のフィールドに分割してから、read(*)ステートメントでフィールドを読み取ります。

2
Ferenc Nagy

@ AndrésArgüElloGuillén回答にわずかな変更。

他のほとんどのソリューションとは異なり、私のコードでは、行と列の数を事前に指定する必要はありません。

CHARACTER(128) :: buffer

integer strlen, rows, cols
real, dimension(:,:), allocatable :: x

OPEN (1, file = 'matrix.txt', status='old', action='read')

!Count the number of columns

read(1,'(a)') buffer !read first line WITH SPACES INCLUDED
REWIND(1) !Get back to the file beginning

strlen = len(buffer) !Find the REAL length of a string read
do while (buffer(strlen:strlen) == ' ') 
  strlen = strlen - 1 
enddo

cols=0 !Count the number of spaces in the first line
do i=0,strlen
  if (buffer(i:i) == ' ') then
    cols=cols+1
  endif
enddo

cols = cols+1

!Count the number of rows

rows = 0 !Count the number of lines in a file
DO
  READ(1,*,iostat=io)
  IF (io/=0) EXIT
  rows = rows + 1
END DO

REWIND(1)

print*, 'Number of rows:', rows
print*, 'Number of columns:', cols

allocate(x(rows,cols))

do I=1,rows,1
  read(1,*) x(I,:)
  write(*,*) x(I,:)
enddo

CLOSE (1)

matrix.txt

0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
1
prograils

その理由は、実数に対して小さすぎる幅を指定しているためです。通常、幅が収まらない場合、Fortranはアスタリスクを表示します。これはあなたの場合に発生します。

9桁ですが、コンマも1列を占めるため、少なくとも10桁必要です。したがって、3F9.3を3F10.3に置き換えるとうまくいくはずです。

1
lemdan

通常、固定されていない形式でデータを読み取ることをお勧めします。そして、それらを書き出すときに数字が収まるように、いくつかの先頭のスペースを残すこと。

integer(8) :: i
real(4) :: x, y, z
open(unit=1, file='data.txt')
read(1,*)i, x, y, z
write(*,'(i16, 3f11.3)')i, x, y, z
end
0
Rook