まず、重要な観察。サブルーチンへの引数として配列を渡すとき、下限が1でない限り、実際の引数の上限と下限は呼び出しで維持されません。しかし、ポインタを渡すときは、下限と上限が維持されます。 Fortran subroutine returning wrong values
第2に、Java、C/C++、Pythonなどとは異なり、FORTRAN/Fortranにファイルの概念はありません。参照:http://docs.cray.com/books/S-3695-35/html-S-3695-35/pdollsmg.html
さらに、ファイル識別ユニットをハードコーディングすると、エラーが発生しやすくなります。より大きな整数を使用する代わりに、それらを完全に避けることをお勧めします。以下のコードはnewunit
指定子を使用して、配列を読み込み、書式なしの*.dat
ファイルに書き込みます。
program main
use, intrinsic :: ISO_Fortran_env, only: &
stdout => OUTPUT_UNIT, &
compiler_version, &
compiler_options
! Explicit typing only
implicit none
! Variables
integer, parameter :: NX=2, NY=3
real, pointer :: write_ptr(:,:) => null()
real, allocatable :: read_alloc(:,:)
! Your original post did not have valid array extends
real, target, dimension(-NX:NX, -NY:NY) :: f, g
! Write data to binary files
write_ptr => f
call write_grid_to_file(write_ptr, './file1.dat')
nullify(write_ptr)
write_ptr => g
call write_grid_to_file(write_ptr, './file2.dat')
nullify(write_ptr)
! Allocate memory to read from files
allocate(read_alloc, mold=f)
call read_grid_from_file(read_alloc, './file1.dat')
print *, 'original f array'
print *, f
print *, 'read from *.dat file'
print *, read_alloc
write(stdout, '(/4a/)') &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
contains
subroutine write_grid_to_file(grid, file_name)
! Dummy arguments
real, pointer, intent (in) :: grid(:,:)
character(len=*), intent(in) :: file_name
! Local variable
integer :: file_id_unit
! Write grid to file
open(newunit=file_id_unit, file=file_name, &
status='replace', form='unformatted', &
action='write', access='stream')
write(file_id_unit) grid
close(file_id_unit)
end subroutine write_grid_to_file
subroutine read_grid_from_file(grid, file_name)
! Dummy arguments
real, intent (out) :: grid(:,:)
character(len=*), intent(in) :: file_name
! Local variable
integer :: file_id_unit
! Write grid to file
open(newunit=file_id_unit, file=file_name, &
status='old', form='unformatted', &
action='read', access='stream')
read(file_id_unit) grid
close(file_id_unit)
end subroutine read_grid_from_file
end program main
コマンドラインプロンプト:
gfortran -Wall -o main.exe main.f90; ./main.exe
利回り
original f array
0.00000000 0.00000000 0.00000000 0.00000000 -4.64743227E-27 4.59121429E-41 2.93318617E+14 4.56823299E-41 -4.64740762E-27 4.59121429E-41 1.02162904E+15 4.56823299E-41 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
read from *.dat file
0.00000000 0.00000000 0.00000000 0.00000000 -4.64743227E-27 4.59121429E-41 2.93318617E+14 4.56823299E-41 -4.64740762E-27 4.59121429E-41 1.02162904E+15 4.56823299E-41 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
This file was compiled using GCC version 6.2.0 20161010 using the options -mtune=generic -march=x86-64 -Wall
あなたは[FORTRANのファイルに大きな配列を作成するための最良の方法を見たことがありますか?テキスト対その他](http://stackoverflow.com/a/24395990/1115360) –
@AndrewMorton提案に感謝します。私は実際にその1日中、スタック交換で見つけたもう一つの役に立つリンクを読んでいました。しかし、私はまだ私の状況にそれを適用することはできません。 (私はそれが簡単だが、私のfortranの知識の欠如は本当に表示されていることを知っている)。 –
しかしそこには 'do i = 1、asize;という行があります。write(u、*)(array(i、j)、j = 1、asize); enddoは解決策です。 –