2016-10-25 22 views
1

こんにちは私は2次元配列を.datファイルに書き込もうとしています。サンプルコードは以下の通りです:2次元配列を.datファイルに書き込む

integer :: i,j 
integer, parameter :: nx=100, ny=100 
real,dimension(-nx:nx,-ny:ny) :: f,g 

open(unit=1,file='file1.dat') 
open(unit=2,file='file2.dat') 

したがって、各2次元配列は、これらが満たされていると仮定すると、

f(i,j) 
g(i,j) 

で与えられ、私は.datファイルに書き込むことができますか?私は暗黙DOを使用するだけで私が欲しいものではない1行として.datファイルに2次元配列を格納しかし

write(1,*) (f(i,j), i=-nx,nx), j=-ny,ny) 
write(2,*) (g(i,j), i=-nx,nx), j=-ny,ny) 

ループ試みました。私は店舗の2D配列を2D配列として(行列が格納されるように)したい。 nx = nyなので、2D配列は正方行列でなければなりません。

+0

あなたは[FORTRANのファイルに大きな配列を作成するための最良の方法を見たことがありますか?テキスト対その他](http://stackoverflow.com/a/24395990/1115360) –

+0

@AndrewMorton提案に感謝します。私は実際にその1日中、スタック交換で見つけたもう一つの役に立つリンクを読んでいました。しかし、私はまだ私の状況にそれを適用することはできません。 (私はそれが簡単だが、私のfortranの知識の欠如は本当に表示されていることを知っている)。 –

+2

しかしそこには 'do i = 1、asize;という行があります。write(u、*)(array(i、j)、j = 1、asize); enddoは解決策です。 –

答えて

1

まず、重要な観察。サブルーチンへの引数として配列を渡すとき、下限が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 
+0

アップス、私は実際にこの目的のためだけにポインタを使用しない、私はそれが将来の読者を混乱させる誤用だと思う。索引を直接操作しない場合でも、下限を保持する必要はありません。しばしば、1からsize(a)にループし、いくつかの異なるスコープでどのように宣言されているか気にしません。そして、あなたの配列が親スコープ内でターゲットになっていなければ、これを使うことはできません。それだけでなく、ターゲットの値を変更することが許可されているため、 'intent(in) 'の保護も使用できません。 –

+1

OPの質問の1つは、配列を行単位でテキストファイルに書き込む方法でした。この '解決策'は、テキストファイルに配列を1行で書き込む複雑な方法のようです。私はこの答えのポイントを見て苦労しています。 –

+0

私はこの答えを何でも理解していません。あなたのお手伝いをしてくれてありがとう。 –

関連する問題