将数组数据读入不同大小的Fortran数组

时间:2014-09-25 19:13:31

标签: file-io fortran

假设我在文件array.txt中有一个5 x 5浮点数组:

1.0 1.1 0.0 0.0 0.0
1.2 1.3 1.4 0.0 0.0
0.0 1.5 1.6 1.7 0.0
0.0 0.0 1.8 1.9 1.0
0.0 0.0 0.0 1.1 1.2

我知道这可能是一件奇怪的事情,但我只是想更好地学习read语句:我想在Fortran中创建两个3x3数组,即real, dimension(3,3) :: array1, array2和尝试将前9个值按行读入array1,将以下9个值读入array2。也就是说,我希望数组具有

形式
array1 = 1.0 1.1 0.0
         0.0 0.0 1.2
         1.3 1.4 0.0

array2 = 0.0 0.0 1.5
         1.6 1.7 0.0
         0.0 0.0 1.8

接下来我想尝试按列进行相同操作:

array1 = 1.0 1.2 0.0
         0.0 0.0 1.1
         1.3 1.5 0.0

array2 = 0.0 0.0 1.4
         1.6 1.8 0.0
         0.0 0.0 1.7

我和#34;最近的"尝试逐行:

program scratch
  implicit none

  real, dimension(3,3) :: array1, array2
  integer :: i

  open(12, file="array.txt")

 !read in values                                                 
  do i = 1,3
        read(12,'(3F4.1)', advance="no") array1(i,:)
  end do

end program scratch

我的问题:

一个。如何在结束时前进到下一个记录?

B中。如何按列进行阅读?

℃。为什么需要'(3F4.1)',而不是'(3F3.1)'

2 个答案:

答案 0 :(得分:0)

因为要求"按列分配"我建议将整个作品读成5x5数组:

 real tmp(5,5)
 read(unit,*)tmp

(注意不需要格式规范)

然后使用数组操作完成所需的分配。

对于这个小数组,最简单的事情似乎是:

real tmp(5,5),flat(25),array1(3,3),array2(3,3)
read(unit,*)tmp
flat=reshape(tmp,shape(flat))
array1=reshape(flat(:9),shape(array1))
array2=reshape(flat(10:18),shape(array2))

然后换位版本就是:

flat=reshape(transpose(tmp),shape(flat))
array1=reshape(flat(:9),shape(array1))
array2=reshape(flat(10:18),shape(array2))

如果它是一个非常大的阵列,我会想到一种避免制作额外数据副本的方法。

请注意,如果需要,您可以在transpose中包装每个分配,具体取决于 你真正想要的数据,例如。

     array1=transpose(reshape(flat(:9),shape(array1)))

答案 1 :(得分:0)

逐行阅读很简单:

READ(12,*) ((array1(i,j),j=1,3),i=1,3),((array2(i,j),j=1,3),i=1,3)

"预先='无'"仅当您使用2个读取语句而不是1时(并且仅在第一次READ时)才需要。但这只适用于显式格式......

按列读取文件并不是那么明显,特别是因为读取文件通常是一项昂贵的任务。我建议您在较大的表中读取该文件,然后将值分配到您的两个数组中。例如:

real :: table(5,5)
integer :: i,j,ii,jj,k
..
read(12,*) ((table(i,j),j=1,5),i=1,5)
k=0
do j=1,3
   do i=1,3
      k=k+1
      jj=(k-1)/5+1
      ii=k-(jj-1)*5
      array1(i,j)=table(ii,jj)
   enddo
enddo
do j=1,3
   do i=1,3
      k=k+1
      jj=(k-1)/5+1
      ii=k-(jj-1)*5
      array2(i,j)=table(ii,jj)
   enddo
enddo

(3F4.1)优于(3F3.1),因为每个数字实际上占用4个字节(数字为3,数字之间为1)。但正如你所看到的,我已经使用了*,这避免了考虑这些细节。