Write dynamical arrays in Fortran 90 [duplicate]

2019-06-27 12:55发布

This question already has an answer here:

I have arrays with dynamical dimension (dimx, dim) and I need a way to write such arrays in a file through the Write instruction, the problem is that until now I haven't been able to produce such files in a automatic way, I mean until now I have to change the dimension of the array in the Write instruction by hand and I need a way in which the dimension change depending of the dimension dimx and dim in the way:

integer :: dimx, dim 
complex, allocatable :: matA(:,:), vectB(:)

 allocate(matA(dimx,dimx), vectB(dim))  

write(1,'(**dimx** e16.6) matA
write(2,'(**dim** e16.6) vecB

Is there a way to do this?

2条回答
我想做一个坏孩纸
2楼-- · 2019-06-27 13:20

To supplement the other answer, and a matter not covered in the near-duplicate referred to in the comments ...

The 2008 language standard introduces the concept of the unlimited-format-item, that is a language-standard mechanism for repeating a format specification as many times as necessary. In the olden days one might precede a format specification with a very large number (as @dave_thompson_085 mentions), now one can use a * instead, for example

write(1,'(*(e16.6))') matA

rather than

write(1,'(999(e16.6))') matA

Many compilers in common use already implement this feature.

查看更多
虎瘦雄心在
3楼-- · 2019-06-27 13:37

The repeat-count on a format specifier in an I/O statement is not necessarily the dimension of an array in the data-list. It is entirely legal for several distinct data items to correspond to a single repeated format specifier like:

 write(unit,'(3f5.1)') x,y,z

or for an array to correspond to several different format specifiers:

 real::a(3)
 write(unit,'(f5.1,f10.2,f5.1)') a

And if there are more format specifiers than needed for the data-list (which can be variable using dynamic bounds and/or implied-do), including but not limited to repeated specifiers, the extra are ignored. Thus the traditional way (back to F66 at least) to handle a variable number of data items (in one dimension) is to use a 'huge' repeat count that is at least as large as the data ever is.

Your arrays are of complex elements, so each element is actually two values and the format repeat must be at least twice the number of elements.

Since F77 the format can be a character variable and you can set the value of that (or any other) character variable with an 'internal' WRITE, which allows constructing and using a data-dependent format. This method allows you to tailor the format for a 2-D array to one (exact) dimension.

An example showing both of these methods for your case:

program SO43482939
integer,parameter::dimx=2,dimy=3,dim=4
complex,allocatable::mata(:,:),vecb(:)
character(len=80)::fmt
integer i,j
allocate (mata(dimx,dimy),vecb(dim))
do i=1,dimx
  do j=1,dimy
    mata(i,j)=complex(i*10+j,i*10+j)
  end do
end do
do i=1,dim
  vecb(i)=complex(i*10+j,i*10+j)
end do
write(*,'(999f5.1)') vecb
write(fmt,'(a,i5,a)') '(',2*dimx,'f5.1)'
write(*,'(a)') fmt
write(*,fmt) mata
end program

OUTPUT

 14.0 14.0 24.0 24.0 34.0 34.0 44.0 44.0
(    4f5.1)
 11.0 11.0 21.0 21.0
 12.0 12.0 22.0 22.0
 13.0 13.0 23.0 23.0
查看更多
登录 后发表回答