可分配阵列'' at(1)必须具有延迟形状或假定等级,并且在(1)错误的READ语句中出现语法错误

时间:2017-08-01 01:24:17

标签: arrays fortran readfile gfortran allocatable-array

我正在尝试读取ASCII文件,并在编译时遇到错误:

Error: Syntax error in READ statement at (1)

Error: Allocatable array 'pos' at (1) must have a deferred shape or assumed rank

我的代码:

subroutine read_file(pos,mass,rho,vel,n)
integer :: i, n
real, allocatable, intent(out) :: pos(3,n), mass(n), rho(n), vel(3,n)

open(unit=11,file="star.ascii",status="old",action="read") 

n = 0

do
  read(unit=11,*)
  n = n+1
enddo

allocate(pos(3,n), mass(n), rho(n), vel(3,n))

do i = 1,n
  read(unit=11,*) pos(:,i), mass(i), rho(i), vel(:,i)
enddo
close(unit=11)

end subroutine read_file

我的ascii文件中的前8列是位置,质量,密度的x,y,z分量,以及我读入数组的速度的x,y,z分量,(1,n), (2,n),(3,n)相应地是x,y和z分量,n应该是粒子数。

我做错了什么以及如何编译此代码?

更新:第一个错误已解决,但仍然使用READ语句获得相同的语法错误。

subroutine read_file(pos,mass,rho,vel,n) 
integer :: i, n, ios
real, allocatable, intent(out) :: pos(:,:),mass(:),rho(:),vel(:,:)

open(unit=11,file="star.ascii",status="old",action="read")

n = 0
do
  read(unit=11,*,iostat=ios) pos,mass,rho,vel 
  if (ios /= 0) exit
  n = n+1
enddo

allocate(pos(3,n), mass(n), rho(n), vel(3,n))  
rewind(11)

do i = 1,n
  read(unit=11,*)pos(:,i),mass(i),rho(i),vel(:,i) 
enddo
close(unit=11)

end subroutine read_file

1 个答案:

答案 0 :(得分:0)

read语法错误来自于您使用命名的伪参数(unit=11),但您不会继续使用命名的伪参数。

假设你有一个带有这个界面的子程序:

subroutine mysub(a, b, c)
    implicit none
    integer, intent(in), optional :: a, b, c
end subroutine mysub

有两种方法可以调用这样的子程序:

  1. 没有命名的伪参数:

    call mysub(1, 2, 3)   ! a->1, b->2, c->3
    call mysub(4711, 2)   ! a->4711, b->2, c unset
    
  2. 使用所谓的关键字参数:

    call mysub(a=4, c=2)  ! b unset
    call mysub(b=14)      ! a and c unset
    
  3. 在案例1中,编译器根据接口中定义参数的顺序来解释输入。在第2种情况下,它通过关键字参数设置它们。在某种程度上,你可以混合一点:

    call mysub(1, c=5)   ! b unset
    

    但是,这很重要,在第一个关键字参数之后,您无法返回:

    call mysub(b=4, 2)   ! DOES NOT WORK
    

    在这种情况下,编译器不知道a或c是否应该是2。您可能会说,"如果我使用mysub(a=1, 2, 3)该怎么办,那该怎么说呢?&#34}?"它可能是,但为了避免陷阱,Fortran指南声明

      

    ...一旦关键字参数出现在列表中,所有剩余的参数也必须是关键字参数 1

    read的界面以unit为第一,fmt为第二参数。所以你可以选择其中一个:

    read(unit=11, fmt=*, iostat=ios) ...
    read(11, *, iostat=ios) ...
    

    但是,如果不宣布unit=

    ,您就无法使用fmt=

    如果声明可分配数组,则需要告诉它要为分配保留的维数。这不是使用n完成的,而是使用冒号:

    real, allocatable :: pos(:, :), mass(:), rho(:), vel(:, :)
    
    来自Chapman的

    1 :Fortran 95/2003科学家和工程师